Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions src/deploy_tools/apptainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@

def __init__(self, templater: Templater, layout: Layout) -> None:
self._templater = templater
self._entrypoints_root = layout.entrypoints_root
self._sif_root = layout.sif_files_root
self._layout = layout

Check warning on line 21 in src/deploy_tools/apptainer.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/apptainer.py#L21

Added line #L21 was not covered by tests

def create_entrypoint_files(self, config: Apptainer, module: Module) -> None:
self._generate_sif_file(config, module)
metadata = module.metadata

Check warning on line 25 in src/deploy_tools/apptainer.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/apptainer.py#L25

Added line #L25 was not covered by tests

entrypoints_folder = (
self._entrypoints_root / module.metadata.name / module.metadata.version
entrypoints_folder = self._layout.get_entrypoints_folder(

Check warning on line 27 in src/deploy_tools/apptainer.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/apptainer.py#L27

Added line #L27 was not covered by tests
metadata.name, metadata.version
)
entrypoints_folder.mkdir(parents=True, exist_ok=True)
sif_file = self._get_sif_file_path(config, module.metadata)
Expand Down Expand Up @@ -72,6 +72,6 @@
subprocess.run(commands, check=True)

def _get_sif_file_path(self, config: Apptainer, metadata: ModuleMetadata) -> Path:
sif_parent = self._sif_root / metadata.name / metadata.version
sif_folder = self._layout.get_sif_files_folder(metadata.name, metadata.version)

Check warning on line 75 in src/deploy_tools/apptainer.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/apptainer.py#L75

Added line #L75 was not covered by tests
file_name = uuid.uuid3(uuid.NAMESPACE_URL, config.container.url).hex
return sif_parent / f"{file_name}.sif"
return sif_folder / f"{file_name}.sif"

Check warning on line 77 in src/deploy_tools/apptainer.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/apptainer.py#L77

Added line #L77 was not covered by tests
6 changes: 3 additions & 3 deletions src/deploy_tools/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@

def __init__(self, templater: Templater, layout: Layout) -> None:
self._templater = templater
self._entrypoints_root = layout.entrypoints_root
self._layout = layout

Check warning on line 12 in src/deploy_tools/command.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/command.py#L12

Added line #L12 was not covered by tests

def create_entrypoint_file(
self,
config: Command,
module: Module,
) -> None:
entrypoints_folder = (
self._entrypoints_root / module.metadata.name / module.metadata.version
entrypoints_folder = self._layout.get_entrypoints_folder(

Check warning on line 19 in src/deploy_tools/command.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/command.py#L19

Added line #L19 was not covered by tests
module.metadata.name, module.metadata.version
)
entrypoints_folder.mkdir(parents=True, exist_ok=True)
entrypoint_file = entrypoints_folder / config.name
Expand Down
25 changes: 14 additions & 11 deletions src/deploy_tools/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,26 @@
class Layout:
"""Represents the layout of the deployment area."""

ENTRYPOINTS_ROOT_NAME = "entrypoints"
MODULES_ROOT_NAME = "modules"
MODULEFILES_ROOT_NAME = "modulefiles"
SIF_FILES_ROOT_NAME = "sif_files"
DEPRECATED_ROOT_NAME = "deprecated"
ENTRYPOINTS_FOLDER = "entrypoints"
SIF_FILES_FOLDER = "sif_files"

DEPLOYMENT_SNAPSHOT_FILENAME = "deployment.yaml"

def __init__(self, deployment_root: Path) -> None:
self._root = deployment_root

def get_module_folder(self, name: str, version: str) -> Path:
return self.modules_root / name / version

Check warning on line 19 in src/deploy_tools/layout.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/layout.py#L19

Added line #L19 was not covered by tests

def get_entrypoints_folder(self, name: str, version: str):
return self.get_module_folder(name, version) / self.ENTRYPOINTS_FOLDER

Check warning on line 22 in src/deploy_tools/layout.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/layout.py#L22

Added line #L22 was not covered by tests

def get_sif_files_folder(self, name: str, version: str):
return self.get_module_folder(name, version) / self.SIF_FILES_FOLDER

Check warning on line 25 in src/deploy_tools/layout.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/layout.py#L25

Added line #L25 was not covered by tests

@property
def deployment_root(self) -> Path:
return self._root
Expand All @@ -23,12 +33,8 @@
return self._root / self.DEPRECATED_ROOT_NAME

@property
def entrypoints_root(self) -> Path:
return self._root / self.ENTRYPOINTS_ROOT_NAME

@property
def sif_files_root(self) -> Path:
return self._root / self.SIF_FILES_ROOT_NAME
def modules_root(self) -> Path:
return self._root / self.MODULES_ROOT_NAME

Check warning on line 37 in src/deploy_tools/layout.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/layout.py#L37

Added line #L37 was not covered by tests

@property
def modulefiles_root(self) -> Path:
Expand All @@ -41,6 +47,3 @@
@property
def snapshot_file(self) -> Path:
return self._root / self.DEPLOYMENT_SNAPSHOT_FILENAME

def get_application_paths(self) -> list[Path]:
return [self.entrypoints_root, self.sif_files_root]
22 changes: 12 additions & 10 deletions src/deploy_tools/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
ModuleVersionsByName: TypeAlias = dict[str, list[str]]

VERSION_FILENAME = ".version"
VERSION_GLOB = "*/[!.version]*"
DEVELOPMENT_VERSION = "dev"


Expand All @@ -21,25 +22,26 @@
self._templater = templater
self._layout = layout
self._modulefiles_root = layout.modulefiles_root
self._entrypoints_root = layout.entrypoints_root

def create_module_file(self, module: Module) -> None:
config = module.metadata
entrypoints_folder = self._entrypoints_root / config.name / config.version
metadata = module.metadata
entrypoints_folder = self._layout.get_entrypoints_folder(

Check warning on line 28 in src/deploy_tools/module.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/module.py#L27-L28

Added lines #L27 - L28 were not covered by tests
metadata.name, metadata.version
)

description = config.description
description = metadata.description

Check warning on line 32 in src/deploy_tools/module.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/module.py#L32

Added line #L32 was not covered by tests
if description is None:
description = f"Scripts for {config.name}"
description = f"Scripts for {metadata.name}"

Check warning on line 34 in src/deploy_tools/module.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/module.py#L34

Added line #L34 was not covered by tests

params = {
"module_name": config.name,
"module_name": metadata.name,
"module_description": description,
"env_vars": config.env_vars,
"dependencies": config.dependencies,
"env_vars": metadata.env_vars,
"dependencies": metadata.dependencies,
"entrypoint_folder": entrypoints_folder,
}

module_file = self._modulefiles_root / config.name / config.version
module_file = self._modulefiles_root / metadata.name / metadata.version

Check warning on line 44 in src/deploy_tools/module.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/module.py#L44

Added line #L44 was not covered by tests
module_file.parent.mkdir(exist_ok=True, parents=True)

self._templater.create(module_file, TemplateType.MODULEFILE, params)
Expand Down Expand Up @@ -84,7 +86,7 @@
)
found_modules: ModuleVersionsByName = defaultdict(list)

for version_path in modulefiles_root.glob("*/[!.version]*"):
for version_path in modulefiles_root.glob(VERSION_GLOB):

Check warning on line 89 in src/deploy_tools/module.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/module.py#L89

Added line #L89 was not covered by tests
found_modules[version_path.parent.name].append(version_path.name)

return found_modules
Expand Down
14 changes: 6 additions & 8 deletions src/deploy_tools/remove.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,17 @@
module_file = layout.modulefiles_root / name / version
module_file.unlink()

remove_application_paths(name, version, layout)
remove_module(name, version, layout)

Check warning on line 46 in src/deploy_tools/remove.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/remove.py#L46

Added line #L46 was not covered by tests


def remove_deprecated_module(name: str, version: str, layout: Layout) -> None:
module_file = layout.deprecated_modulefiles_root / name / version
module_file.unlink()

remove_application_paths(name, version, layout)
remove_module(name, version, layout)

Check warning on line 53 in src/deploy_tools/remove.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/remove.py#L53

Added line #L53 was not covered by tests


def remove_application_paths(name: str, version: str, layout: Layout) -> None:
to_remove = layout.get_application_paths()
for path in to_remove:
version_path = path / name / version
if version_path.exists():
shutil.rmtree(version_path)
def remove_module(name: str, version: str, layout: Layout) -> None:
module_folder = layout.get_module_folder(name, version)
if module_folder.exists():
shutil.rmtree(module_folder)

Check warning on line 59 in src/deploy_tools/remove.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/remove.py#L57-L59

Added lines #L57 - L59 were not covered by tests
21 changes: 15 additions & 6 deletions src/deploy_tools/remove_name_folders.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import shutil
from pathlib import Path

from .layout import Layout
from .models.module import Module
from .module import VERSION_GLOB


class RemoveNameFoldersError(Exception):
Expand All @@ -16,17 +18,24 @@
) -> None:
"""Remove module name folders where all versions have been removed."""
for module in deprecated:
delete_name_folder(module.metadata.name, layout.modulefiles_root)
delete_modulefile_name_folder(module.metadata.name, layout.modulefiles_root)

Check warning on line 21 in src/deploy_tools/remove_name_folders.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/remove_name_folders.py#L21

Added line #L21 was not covered by tests

for module in restored:
delete_name_folder(module.metadata.name, layout.deprecated_modulefiles_root)
delete_modulefile_name_folder(

Check warning on line 24 in src/deploy_tools/remove_name_folders.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/remove_name_folders.py#L24

Added line #L24 was not covered by tests
module.metadata.name, layout.deprecated_modulefiles_root
)

app_roots = layout.get_application_paths()
for module in removed:
delete_name_folder(module.metadata.name, layout.deprecated_modulefiles_root)
delete_modulefile_name_folder(

Check warning on line 29 in src/deploy_tools/remove_name_folders.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/remove_name_folders.py#L29

Added line #L29 was not covered by tests
module.metadata.name, layout.deprecated_modulefiles_root
)
delete_name_folder(module.metadata.name, layout.modules_root)

Check warning on line 32 in src/deploy_tools/remove_name_folders.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/remove_name_folders.py#L32

Added line #L32 was not covered by tests

for root in app_roots:
delete_name_folder(module.metadata.name, root)

def delete_modulefile_name_folder(name: str, modulefiles_root: Path) -> None:
modulefiles_name_path = modulefiles_root / name
if modulefiles_name_path.glob(VERSION_GLOB):
shutil.rmtree(modulefiles_name_path)

Check warning on line 38 in src/deploy_tools/remove_name_folders.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/remove_name_folders.py#L36-L38

Added lines #L36 - L38 were not covered by tests


def delete_name_folder(name: str, area_root: Path) -> None:
Expand Down
6 changes: 3 additions & 3 deletions src/deploy_tools/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@

def __init__(self, templater: Templater, layout: Layout) -> None:
self._templater = templater
self._entrypoints_root = layout.entrypoints_root
self._layout = layout

Check warning on line 15 in src/deploy_tools/shell.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/shell.py#L15

Added line #L15 was not covered by tests

def create_entrypoint_file(
self,
config: Shell,
module: Module,
) -> None:
entrypoints_folder = (
self._entrypoints_root / module.metadata.name / module.metadata.version
entrypoints_folder = self._layout.get_entrypoints_folder(

Check warning on line 22 in src/deploy_tools/shell.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/shell.py#L22

Added line #L22 was not covered by tests
module.metadata.name, module.metadata.version
)
entrypoints_folder.mkdir(parents=True, exist_ok=True)
entrypoint_file = entrypoints_folder / config.name
Expand Down
4 changes: 2 additions & 2 deletions src/deploy_tools/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
UpdateGroup,
check_actions,
validate_default_versions,
validate_deployment,
validate_update_group,
)


Expand All @@ -25,7 +25,7 @@
layout = Layout(deployment_root)
snapshot = load_snapshot(layout)

update_group = validate_deployment(deployment, snapshot)
update_group = validate_update_group(deployment, snapshot)

Check warning on line 28 in src/deploy_tools/sync.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/sync.py#L28

Added line #L28 was not covered by tests
default_versions = validate_default_versions(deployment)

check_actions(update_group, default_versions, layout)
Expand Down
9 changes: 6 additions & 3 deletions src/deploy_tools/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
layout = Layout(deployment_root)
snapshot = load_snapshot(layout)

update_group = validate_deployment(deployment, snapshot)
update_group = validate_update_group(deployment, snapshot)

Check warning on line 52 in src/deploy_tools/validate.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/validate.py#L52

Added line #L52 was not covered by tests
default_versions = validate_default_versions(deployment)

check_actions(update_group, default_versions, layout)
Expand Down Expand Up @@ -106,7 +106,7 @@
print()


def validate_deployment(deployment: Deployment, snapshot: Deployment) -> UpdateGroup:
def validate_update_group(deployment: Deployment, snapshot: Deployment) -> UpdateGroup:
"""Validate configuration to get set of actions that need to be carried out."""
old_modules = snapshot.modules
new_modules = deployment.modules
Expand Down Expand Up @@ -230,12 +230,15 @@
"""Return module versions that will exist after sync action has been carried out."""
final_versions: ModuleVersionsByName = defaultdict(list)
for name, module_versions in deployment.modules.items():
final_versions[name] = [
versions = [

Check warning on line 233 in src/deploy_tools/validate.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/validate.py#L233

Added line #L233 was not covered by tests
version
for version, module in module_versions.items()
if not module.metadata.deprecated
]

if versions:
final_versions[name] = versions

Check warning on line 240 in src/deploy_tools/validate.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/validate.py#L239-L240

Added lines #L239 - L240 were not covered by tests

return final_versions


Expand Down
Loading