diff --git a/project_manager/common/template.py b/project_manager/common/template.py index e440ab4..d77f6a7 100644 --- a/project_manager/common/template.py +++ b/project_manager/common/template.py @@ -9,6 +9,10 @@ from jinja2 import Environment from ..preset.model import Variables +def do_bool(data: str | None) -> bool: + return not (data is None or data.lower() in ["false", "null", "none", "0", ""]) + + def _build_env(basepath: Path) -> Environment: env = Environment() @@ -60,6 +64,7 @@ def _build_env(basepath: Path) -> Environment: env.filters["get"] = do_get env.filters["search"] = do_search env.filters["key"] = do_key + env.filters["bool"] = do_bool return env @@ -78,6 +83,6 @@ class PathTemplate: def check_conditions(self, templates: list[str], variables: Variables) -> bool: for template in templates: value = self.fill_template(template, variables) - if value.lower() in ["false", "null", "none", "0", ""]: + if not do_bool(value): return False return True diff --git a/project_manager/entry/detector.py b/project_manager/entry/detector.py index c76c034..234e1f3 100644 --- a/project_manager/entry/detector.py +++ b/project_manager/entry/detector.py @@ -3,6 +3,18 @@ from pathlib import Path from .entry import Entry +class EmptyEntry(Entry): + def __init__(self): + super().__init__({}, Path()) + + def __bool__(self): + return False + + +ENTRY_NONE = EmptyEntry() +ENTRY_SKIP = EmptyEntry() + + class EntryDetector: - def detect_entry(self, basepath: Path) -> Entry | None: + def detect_entry(self, basepath: Path) -> Entry: raise NotImplementedError diff --git a/project_manager/entry/resolver.py b/project_manager/entry/resolver.py index a49ce48..55b0f6a 100644 --- a/project_manager/entry/resolver.py +++ b/project_manager/entry/resolver.py @@ -3,6 +3,7 @@ from typing import Iterable from pathspec import PathSpec +from ..preset.detector import ENTRY_SKIP from .detector import EntryDetector from .entry import Entry @@ -15,12 +16,16 @@ class EntryResolver: def _resolve(self, basepath: Path, depth: int = 0) -> Iterable[Entry]: if basepath.is_dir(): - if self._ignore.match_file(basepath): + if basepath.name.startswith(".") or self._ignore.match_file(basepath): return entry = self._detector.detect_entry(basepath) if entry: yield entry - if depth < self._max_depth and basepath.is_dir(): + if ( + not entry == ENTRY_SKIP + and depth < self._max_depth + and basepath.is_dir() + ): for path in basepath.iterdir(): yield from self._resolve(path, depth + 1) diff --git a/project_manager/preset/default/docker.toml b/project_manager/preset/default/docker.toml index 3b7cb4e..b134a26 100644 --- a/project_manager/preset/default/docker.toml +++ b/project_manager/preset/default/docker.toml @@ -4,7 +4,7 @@ variables.docker_name = "{{ 'pyproject.toml' | read | get('project.name') or 'pa variables.docker_version = "{{ 'pyproject.toml' | read | get('project.version') or 'package.json' | read | get('version') }}" variables.docker_repo = "{{ '.env' | read | get('DOCKER_REPO') }}" variables.docker_group = "{{ '.env' | read | get('DOCKER_GROUP') }}" -variables.docker_image = "{{ docker_group }}/{{ docker_name }}" +variables.docker_image = "{% if docker_group | bool %}{{ docker_group }}/{% endif %}{{ docker_name }}" variables.docker_tag = "{{ '.env' | read | get('DOCKER_TAG') or 'latest' }}" # build @@ -13,7 +13,7 @@ commands = ["docker build -t {{ docker_image }} . -f Dockerfile"] # publish version [presets.docker.tasks.publish.version] -conditions = ["{{ docker_version }}"] +conditions = ["{{ docker_version and docker_repo }}"] commands = [ "docker tag {{ docker_image }} {{ docker_repo }}/{{ docker_image }}:{{ docker_version }}", "docker push {{ docker_repo }}/{{ docker_image }}:{{ docker_version }}", @@ -21,7 +21,7 @@ commands = [ # publish tag [presets.docker.tasks.publish.tag] -conditions = ["{{ docker_tag }}"] +conditions = ["{{ docker_tag and docker_repo }}"] commands = [ "docker tag {{ docker_image }} {{ docker_repo }}/{{ docker_image }}:{{ docker_tag }}", "docker push {{ docker_repo }}/{{ docker_image }}:{{ docker_tag }}", diff --git a/project_manager/preset/detector.py b/project_manager/preset/detector.py index 5d77e64..78cb9b0 100644 --- a/project_manager/preset/detector.py +++ b/project_manager/preset/detector.py @@ -2,7 +2,7 @@ from collections import defaultdict from pathlib import Path from ..common.template import PathTemplate -from ..entry.detector import EntryDetector +from ..entry.detector import ENTRY_NONE, ENTRY_SKIP, EntryDetector from ..entry.entry import Entry, TaskKey from .loader import PresetLoader, PresetLoaderConfig from .model import Variables @@ -13,11 +13,11 @@ class PresetEntryDetector(EntryDetector): def __init__(self, preset_loader_config: PresetLoaderConfig | None = None): self._preset_loader_config = preset_loader_config - def detect_entry(self, basepath: Path) -> Entry | None: + def detect_entry(self, basepath: Path) -> Entry: template = PathTemplate(basepath) preset = PresetLoader(basepath, self._preset_loader_config).load() if preset.skip: - return None + return ENTRY_SKIP tasks = defaultdict(list) for tag, preset in preset.presets.items(): preset_variables: Variables = {"entry_path": basepath} @@ -41,4 +41,4 @@ class PresetEntryDetector(EntryDetector): ] if tasks: return Entry(tasks, basepath) - return None + return ENTRY_NONE diff --git a/tests/.pm.toml b/tests/.pm.toml new file mode 100644 index 0000000..7ff2a63 --- /dev/null +++ b/tests/.pm.toml @@ -0,0 +1 @@ +skip = true