Skip to content

Commit

Permalink
Merge pull request #255 from hakonhagland/fix_run_docker
Browse files Browse the repository at this point in the history
Fixed bug in the run docker container script
  • Loading branch information
lisajulia authored Nov 13, 2024
2 parents 94d9fb6 + b32abf4 commit 46e6363
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 7 deletions.
5 changes: 2 additions & 3 deletions docker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,8 @@ NOTE: The actual tag name of the Docker image is not necessarily the same as the
### `lodocker-run-container`

This script runs LibreOffice from a Docker container. You should supply the file name you
want to open in LibreOffice as the first argument to the script. The file names are
relative to directory `../parts` (as seen from this directory, i.e. the directory containing
this `README.md` file). You can also supply the
want to open in LibreOffice as the first argument to the script. The file name is
relative to directory `parts` directory in the Git root directory of the `opm-reference-manual` repository, see example below. You can also supply the
directory of the Dockerfile you used to build the image (see `lodocker-build-image`) as an
optional argument to the script. So

Expand Down
8 changes: 8 additions & 0 deletions docker/src/lodocker/constants.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
from pathlib import Path

class Directories():
parts = "parts"
docker_files = "docker_files"

class FileNames():
main_document = "main.fodt"

class Paths:
container_home = Path("/home/docker-user")
docker_files = Path("docker_files")

57 changes: 54 additions & 3 deletions docker/src/lodocker/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import click

from lodocker.constants import Directories, FileNames
from lodocker.constants import Paths

class ClickHelpers:
Expand All @@ -17,11 +18,13 @@ def get_directories(path: str) -> list[str]:

@staticmethod
def directory_callback(ctx: click.Context, param: click.Parameter, value: Optional[str]) -> Any:
project_dir = Helpers.get_python_project_dir()
if value is None:
# Dynamically read the directories and prompt the user to choose
choices = ClickHelpers.get_directories('docker_files')
dir_ = project_dir / Directories.docker_files
choices = ClickHelpers.get_directories(dir_)
if not choices:
raise click.UsageError('No directories found in docker_files.')
raise click.UsageError(f'No directories found in {dir_}.')

choice_dict = dict(enumerate(choices, start=1))
click.echo("Select a Dockerfile:")
Expand Down Expand Up @@ -77,6 +80,11 @@ def get_libreoffice_userdir(dockerfile_dirname: str) -> str:
else:
return str(Path(".config") / "libreoffice" / "4")

@staticmethod
def get_python_project_dir() -> Path:
"""Get the root directory of the Python project."""
return Helpers.locate_git_root() / "docker"

@staticmethod
def get_tag_name_from_docker_dirname(dockerfile_dirname: str) -> str | None:
"""Get the tag name for a docker image from the directory name of the Dockerfile.
Expand All @@ -85,7 +93,8 @@ def get_tag_name_from_docker_dirname(dockerfile_dirname: str) -> str | None:
If there exists a file named "tag_name.txt" in the directory, use the contents of
that file as the tag name. Otherwise, display an error message and return.
"""
dockerfile_dirname = Path("docker_files") / dockerfile_dirname
project_dir = Helpers.get_python_project_dir()
dockerfile_dirname = project_dir / Directories.docker_files / dockerfile_dirname
# Check that the Dockerfile exists
if not dockerfile_dirname.exists():
logging.error(f"Dockerfile directory {dockerfile_dirname} does not exist.")
Expand All @@ -102,6 +111,48 @@ def is_dev_container(dockerfile_dirname: str) -> bool:
"""Check if the Dockerfile is for a development container."""
return dockerfile_dirname == "ubuntu2310-dev"

@staticmethod
def locate_git_root() -> Path:
"""Locate the root directory of a git repository. Note that this may fail in the
unlikely case that the user has installed the project globally outside the git
repository and the current working directory is not within the repository.
"""
root = None
try:
root = Helpers.locate_git_root_from_path(Path(__file__))
except FileNotFoundError:
pass
if root is None:
root = Helpers.locate_git_root_from_path(Path.cwd())
return root

@staticmethod
def locate_git_root_from_path(path: Path) -> Path:
"""Locate the root directory of a git repository from a file within the repository.
:param file: A file within the git repository.
:return: The root directory of the git repository.
"""
path = path.resolve()
if path.is_file():
path = path.parent
assert path.is_absolute(), "File path must be absolute."
assert path.is_dir(), "File path must be a file."
cwd = path
while True:
# Check if we have reached the root directory
# filename.parent == filename is True if filename is the root directory
if cwd.parent == cwd:
raise FileNotFoundError(f"Could not derive git root from '{file}'.")
# Check if the current directory is a git repository and that there is a
# directory named "parts" with a main document file therein
if (cwd / ".git").exists() and (cwd / ".git").is_dir():
if (cwd / Directories.parts).exists():
if (cwd / Directories.parts / FileNames.main_document).exists():
return cwd
cwd = cwd.parent
# This should never be reached
return Path("")

@staticmethod
def run_command(command: str | list) -> int:
# Determine if command should be executed within a shell
Expand Down
4 changes: 3 additions & 1 deletion docker/src/lodocker/run_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
class RunContainer:
def __init__(self):
self.shared_doc_dir = "parts"
self.git_root = Path(__file__).resolve().parents[3]
#self.git_root = Path(__file__).resolve().parents[3]
# Use cwd instead of __file__ to locate the git root directory
self.git_root = Helpers.locate_git_root()
logging.info(f"git_root: {self.git_root}")
self.document_dir = self.git_root / self.shared_doc_dir
# The home directory of the user in the Docker container
Expand Down
20 changes: 20 additions & 0 deletions docker/tests/test_find_git_root.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from pathlib import Path
from lodocker.helpers import Helpers

def test_git_root_exists(tmp_path: Path):
# Create a dummy git repository in the tmp_path directory
git_dir = tmp_path / ".git"
git_dir.mkdir()
# Create a folders and a file: "docker/.venv/lib/python3.12/site-packages/lodocker/run_container.py"
docker_dir = tmp_path / "docker/.venv/lib/python3.12/site-packages/lodocker"
docker_dir.mkdir(parents=True)
run_container = docker_dir / "run_container.py"
run_container.touch()
# Create a parts directory
parts_dir = tmp_path / "parts"
parts_dir.mkdir()
# Create a main.fodt file
main_fodt = parts_dir / "main.fodt"
main_fodt.touch()
found_root = Helpers.locate_git_root_from_file(str(run_container))
assert found_root == tmp_path

0 comments on commit 46e6363

Please sign in to comment.