haraka 0.2.6__py3-none-any.whl → 0.2.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,10 @@
1
1
  from dataclasses import dataclass
2
2
  from pathlib import Path
3
+ from typing import Iterable
4
+ import yaml
5
+ from pathspec import PathSpec
6
+
7
+ _MANIFEST_DIR = Path(__file__).resolve().parent.parent.parent / "manifests"
3
8
 
4
9
  @dataclass(frozen=True, slots=True)
5
10
  class PostGenConfig:
@@ -8,4 +13,25 @@ class PostGenConfig:
8
13
  author: str
9
14
  description: str
10
15
  project_dir: Path
11
- swagger: bool
16
+
17
+
18
+ def load_manifest(variant: str) -> list[str]:
19
+ """Return the `keep:` pattern list from `<variant>.yml`."""
20
+ manifest_path = _MANIFEST_DIR / f"{variant}.yml"
21
+ if not manifest_path.exists():
22
+ raise FileNotFoundError(
23
+ f"No manifest found for variant '{variant}' "
24
+ f"(expected {manifest_path})"
25
+ )
26
+ doc = yaml.safe_load(manifest_path.read_text())
27
+ if not isinstance(doc, dict) or "keep" not in doc:
28
+ raise ValueError(f"Manifest {manifest_path} missing a `keep:` section")
29
+ keep_patterns = doc["keep"]
30
+ if not isinstance(keep_patterns, Iterable):
31
+ raise TypeError(f"`keep` section in {manifest_path} must be a list")
32
+ return list(keep_patterns)
33
+
34
+
35
+ def build_spec(patterns: Iterable[str]) -> PathSpec:
36
+ """Compile patterns using git-style wildmatch syntax."""
37
+ return PathSpec.from_lines("gitwildmatch", patterns)
haraka/post_gen/runner.py CHANGED
@@ -4,10 +4,10 @@ from haraka.art.create import Create
4
4
  from haraka.art.ascii.assets import *
5
5
  from .config import PostGenConfig
6
6
  from haraka.utils import divider, Logger
7
- from haraka.post_gen.utils.command import CommandRunner
8
- from haraka.post_gen.utils.files import FileOps
9
- from haraka.post_gen.utils.purge import ResourcePurger
10
- from haraka.post_gen.utils.gitops import GitOps
7
+ from haraka.post_gen.service.command import CommandRunner
8
+ from haraka.post_gen.service.files import FileOps
9
+ from haraka.post_gen.service.purge import ResourcePurger
10
+ from haraka.post_gen.service.gitops import GitOps
11
11
 
12
12
 
13
13
  def main(cfg: PostGenConfig) -> None:
@@ -38,7 +38,7 @@ def main(cfg: PostGenConfig) -> None:
38
38
 
39
39
  divider("🎉 Project generation complete 🎉")
40
40
 
41
- if cfg.language == "go" and not cfg.swagger:
41
+ if cfg.language == "go-grpc-protoc":
42
42
  go_emoji_logo = [emoji["go"]]
43
43
  go_performance_mode = [
44
44
  goLang, divider_xl, performance_mode, divider_l, tools, divider_s,
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ haraka.post_gen.utils.purge
4
+
5
+ Delete all template artefacts that are **not** required for the chosen
6
+ variant, as defined by a YAML manifest in `haraka/manifests/<variant>.yml`.
7
+
8
+ Manifest format (git-wildmatch globs):
9
+
10
+ variant: python-fastapi
11
+ keep:
12
+ - src/app/**
13
+ - tests/**
14
+ - Dockerfile
15
+ - chart/**
16
+
17
+ Anything matching a `keep:` pattern survives. Everything else is removed.
18
+
19
+ Requires: pip install pathspec PyYAML
20
+ """
21
+ from __future__ import annotations
22
+
23
+ from pathlib import Path
24
+ from typing import Iterable
25
+
26
+ import yaml
27
+ from pathspec import PathSpec
28
+
29
+ from .files import FileOps
30
+ from haraka.utils import Logger, divider
31
+ from ..config import config
32
+
33
+ _MANIFEST_DIR = Path(__file__).resolve().parent.parent.parent / "manifests"
34
+
35
+
36
+ # --------------------------------------------------------------------------- #
37
+ # main purger #
38
+ # --------------------------------------------------------------------------- #
39
+ class ResourcePurger:
40
+ """Filesystem cleaner driven by variant manifest files."""
41
+
42
+ def __init__(self, fops: FileOps, logger: Logger | None = None) -> None:
43
+ self._f = fops
44
+ self._log = logger or Logger("ResourcePurger")
45
+
46
+ # ------------------------------ public API ----------------------------- #
47
+ def purge(self, variant: str, project_dir: Path) -> None:
48
+ """
49
+ Remove everything outside the manifest’s `keep:` patterns.
50
+
51
+ Parameters
52
+ ----------
53
+ variant
54
+ Variant key, e.g. ``python-fastapi`` or ``go-grpc-protoc``.
55
+ project_dir
56
+ Root of the freshly generated Cookiecutter project.
57
+ """
58
+ variant = variant.lower()
59
+ self._log.info(f"Starting purge for variant: {variant}")
60
+
61
+ keep_patterns = config.load_manifest(variant)
62
+ spec = config.build_spec(keep_patterns)
63
+
64
+ self._log.info(f"Keeping {len(keep_patterns)} pattern(s)")
65
+
66
+ self._purge_unrelated(project_dir, spec)
67
+
68
+ divider("Project tree after purge…")
69
+ self._f.print_tree(project_dir)
70
+
71
+ # ----------------------------- internals ------------------------------ #
72
+ def _purge_unrelated(self, root: Path, spec: PathSpec) -> None:
73
+ """
74
+ Walk the project tree; delete every path NOT matched by *spec*.
75
+ """
76
+ for path in root.rglob("*"):
77
+ rel = path.relative_to(root).as_posix()
78
+
79
+ if spec.match_file(rel):
80
+ continue # keep it
81
+
82
+ if path.is_dir():
83
+ self._f.remove_dir(path)
84
+ else:
85
+ self._f.remove_file(path)
haraka/utils/__init__.py CHANGED
@@ -1,5 +1,5 @@
1
1
  from haraka.post_gen.config import PostGenConfig
2
2
  from .logging.log_util import Logger
3
3
  from .common.utils import *
4
- from haraka.post_gen.utils.assets import *
4
+ from haraka.post_gen.service.assets import *
5
5
  __all__ = ["PostGenConfig", "", "divider", "Logger", "LANGUAGE_ASSETS", "GLOBAL_ASSETS"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: haraka
3
- Version: 0.2.6
3
+ Version: 0.2.7
4
4
  Summary: Reusable post-generation helper for Cookiecutter micro-service templates
5
5
  Author-email: Will Burks <will@example.com>
6
6
  License: MIT
@@ -8,21 +8,21 @@ haraka/art/ascii/frame/border.py,sha256=n7qaLxzzBmf8ewatbe5gN97DO4afZM67bBjpU1Oq
8
8
  haraka/art/ascii/frame/framer.py,sha256=s_-lsb-hGhlH_73q5iTtk8KHW0MSeSHSAvNFVmL1c9A,3951
9
9
  haraka/art/ascii/frame/width_utils.py,sha256=in4AV3gTBBXUX6N01j67Icu9vsHFomybBN8rpL3sQ5s,810
10
10
  haraka/post_gen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
- haraka/post_gen/runner.py,sha256=HuWKMoHVcF-SLZK9HYLb1NLO1sqnl9Sr92xmFqWbOR4,1816
11
+ haraka/post_gen/runner.py,sha256=a5S3OfOcjv1p5NX5y_XHWRWDENBilsjvbSFayOILj9s,1816
12
12
  haraka/post_gen/config/__init__.py,sha256=-_XkJ_Dni28yJCMfIceQSiH1wa_hHsZMoBTyvR9Ikbc,62
13
- haraka/post_gen/config/config.py,sha256=VpRgp_-dU1sJd3Jow3MAOeerqElzBcHdkSqvgd1bkwk,234
14
- haraka/post_gen/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- haraka/post_gen/utils/assets.py,sha256=UARi1iDczVHoNGm5FpKkSXCk-yvnzyMMtSJM1SxMRSA,6157
16
- haraka/post_gen/utils/command.py,sha256=5yxPSQmQpzAyPNoLtzxaUz1VWgPnTfD7XlkBUu5rIeI,1672
17
- haraka/post_gen/utils/files.py,sha256=1hPHn_nYI5A2JKJqxmNFK5fpo9DNPcGR4K7qCPOO5GE,1993
18
- haraka/post_gen/utils/gitops.py,sha256=hRnztg_5yW3L_bdh05gcgGQ25wwjSTn8pX1sja-m91s,2434
19
- haraka/post_gen/utils/purge.py,sha256=9EQg-CdFVnjEo-KY9_Au_emicpZId7z2-QyWFPLty-M,2633
20
- haraka/utils/__init__.py,sha256=dqjKz10MTfH6fFl68cu_giWYYZ41HAUDg_0-OwC1qjE,246
13
+ haraka/post_gen/config/config.py,sha256=-2L_VXRHCioT6nNrCMGYzfJIGrYCjpf33aRhCukJEaM,1253
14
+ haraka/post_gen/service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ haraka/post_gen/service/assets.py,sha256=UARi1iDczVHoNGm5FpKkSXCk-yvnzyMMtSJM1SxMRSA,6157
16
+ haraka/post_gen/service/command.py,sha256=5yxPSQmQpzAyPNoLtzxaUz1VWgPnTfD7XlkBUu5rIeI,1672
17
+ haraka/post_gen/service/files.py,sha256=1hPHn_nYI5A2JKJqxmNFK5fpo9DNPcGR4K7qCPOO5GE,1993
18
+ haraka/post_gen/service/gitops.py,sha256=hRnztg_5yW3L_bdh05gcgGQ25wwjSTn8pX1sja-m91s,2434
19
+ haraka/post_gen/service/purge.py,sha256=cNs2pHkXN1EJS7RIGR7pAmqJcyQ4eUbhkGpPqrq0Zv4,2656
20
+ haraka/utils/__init__.py,sha256=3WDKxExMNfIrsYqnO0somSJavCJc5_s56S7ffbnXmzc,248
21
21
  haraka/utils/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
22
  haraka/utils/common/utils.py,sha256=kMnMXe_hcxGkD0MKGmR1lIwsRND7BaFPRbGN4PwonfM,360
23
23
  haraka/utils/logging/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
24
  haraka/utils/logging/log_util.py,sha256=rl-VnSPns84MPDp7SwArtrO4oPHUPUiRNdkp0NBvxsY,778
25
- haraka-0.2.6.dist-info/METADATA,sha256=eas99sXOXhJe9zPkVz3XI_qo3e-RyifQBmeLp6vvYmg,578
26
- haraka-0.2.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
- haraka-0.2.6.dist-info/top_level.txt,sha256=1khpwypLKWoklVd_CgFiwAfcctVSXRoRPc3BI9lyIXo,7
28
- haraka-0.2.6.dist-info/RECORD,,
25
+ haraka-0.2.7.dist-info/METADATA,sha256=3jnqlwSLI-7_43h7Mal44W977NZZWqACzx8EXbx7QV4,578
26
+ haraka-0.2.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
+ haraka-0.2.7.dist-info/top_level.txt,sha256=1khpwypLKWoklVd_CgFiwAfcctVSXRoRPc3BI9lyIXo,7
28
+ haraka-0.2.7.dist-info/RECORD,,
@@ -1,70 +0,0 @@
1
- # haraka/post_gen/utils/purge.py
2
- from pathlib import Path
3
- from typing import Dict, Set
4
-
5
- from .files import FileOps
6
- from haraka.utils import Logger, divider
7
- from haraka.post_gen.utils.assets import LANGUAGE_ASSETS, GLOBAL_ASSETS
8
-
9
-
10
- class ResourcePurger:
11
- """Delete template artefacts not relevant to the selected language."""
12
-
13
- def __init__(self, fops: FileOps, logger: Logger | None = None) -> None:
14
- self._f = fops
15
- self._log = logger or Logger("ResourcePurger")
16
-
17
- # Build a quick lookup: language → {"files": set, "dirs": set}
18
- self._index: Dict[str, Dict[str, Set[str]]] = {
19
- spec["language"]: {
20
- "files": set(spec["files"]),
21
- # store directory names *without* trailing “/”
22
- "dirs": {d.rstrip("/") for d in spec["dirs"]},
23
- }
24
- for spec in LANGUAGE_ASSETS
25
- }
26
-
27
- # ------------------------------------------------------------------ #
28
- # public API #
29
- # ------------------------------------------------------------------ #
30
- def purge(self, language: str, project_dir: Path) -> None:
31
- language = language.lower()
32
- if language not in self._index:
33
- self._log.warn(f"Unrecognised language '{language}'; skipping purge.")
34
- return
35
-
36
- self._log.info(f"Starting purge for language: {language}")
37
-
38
- keep_files = self._index[language]["files"] | set(GLOBAL_ASSETS["files"])
39
- keep_dirs = self._index[language]["dirs"] | {
40
- d.rstrip("/") for d in GLOBAL_ASSETS["dirs"]
41
- }
42
-
43
- self._log.info(f"Keeping {len(keep_files)} files & {len(keep_dirs)} dirs")
44
-
45
- self._purge_unrelated(project_dir, keep_files, keep_dirs)
46
-
47
- divider("Project tree after purge…")
48
- self._f.print_tree(project_dir)
49
-
50
- # ------------------------------------------------------------------ #
51
- # internals #
52
- # ------------------------------------------------------------------ #
53
- def _purge_unrelated(
54
- self,
55
- root: Path,
56
- keep_files: Set[str],
57
- keep_dirs: Set[str],
58
- ) -> None:
59
- for path in root.rglob("*"):
60
- rel = path.relative_to(root).as_posix()
61
-
62
- inside_kept_dir = any(rel.startswith(d + "/") for d in keep_dirs)
63
-
64
- if rel in keep_files or rel in keep_dirs or inside_kept_dir:
65
- continue # safe
66
-
67
- if path.is_dir():
68
- self._f.remove_dir(path)
69
- else:
70
- self._f.remove_file(path)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes