haraka 0.2.31__py3-none-any.whl → 0.2.33__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.
@@ -23,6 +23,7 @@ from __future__ import annotations
23
23
  from pathlib import Path
24
24
 
25
25
  from pathspec import PathSpec
26
+ from typing import Tuple, List
26
27
 
27
28
  from haraka.post_gen.service.fileOps.files import FileOps
28
29
  from haraka.utils import Logger, divider
@@ -34,6 +35,12 @@ _MANIFEST_DIR = Path(__file__).resolve().parent.parent.parent / "manifests"
34
35
  # --------------------------------------------------------------------------- #
35
36
  # main purger #
36
37
  # --------------------------------------------------------------------------- #
38
+ def is_dir_protected(rel: str, spec: PathSpec) -> bool:
39
+ """True if *rel* (or an ancestor) is matched by keep spec."""
40
+ # `spec.match_file` already walks ancestors for dirs
41
+ return spec.match_file(rel)
42
+
43
+
37
44
  class ResourcePurger:
38
45
  """Filesystem cleaner driven by variant manifest files."""
39
46
 
@@ -70,61 +77,94 @@ class ResourcePurger:
70
77
  for pattern in keep_patterns:
71
78
  self._log.debug(f"Keep pattern: {pattern}")
72
79
 
73
- self._purge_unrelated(project_dir, spec)
80
+ all_paths = self._walk_tree(project_dir)
81
+
82
+ matched, non_dirs, non_files, _ = self.classify_paths(all_paths, project_dir, spec)
83
+
84
+ self.print_summary(matched, non_dirs, non_files)
85
+
74
86
  self._log.debug(f"Finished purging unrelated paths in project directory: {project_dir}")
75
87
 
76
88
  divider("Project tree after purge…")
77
89
  self._f.print_tree(project_dir)
78
90
 
91
+
92
+ # ----------------------------- internals ------------------------------ #
93
+
94
+ def _walk_tree(self, root: Path) -> List[Path]:
95
+ """Return every file/dir under *root*, logging the walk."""
96
+ paths = list(root.rglob("*"))
97
+ self._log.debug(f"📋 All paths under {root} (total {len(paths)}:")
98
+ for p in paths:
99
+ self._log.debug(f" {p.relative_to(root)}")
100
+ return paths
101
+
102
+
79
103
  # --------------------------------------------------------------------------- #
80
- # internals #
104
+ # Classification helpers #
81
105
  # --------------------------------------------------------------------------- #
82
- def _purge_unrelated(self, root: Path, spec: PathSpec) -> None:
83
- """
84
- Walk *root* recursively and delete every path **not** matched by *spec*.
85
- A directory is preserved if **it or any ancestor** is matched.
86
- """
87
- all_paths = list(root.rglob("*"))
88
- self._log.debug("📋 Scanning %d paths under %s", len(all_paths), root)
89
-
90
- keep: list[str] = []
91
- delete_files: list[str] = []
92
- delete_dirs: list[str] = []
93
106
 
94
- for path in all_paths:
107
+ def classify_paths(
108
+ self,
109
+ paths: List[Path], root: Path, spec: PathSpec
110
+ ) -> Tuple[List[str], List[str], List[str], List[str]]:
111
+ """Split paths into keep/delete buckets."""
112
+ matched: List[str] = []
113
+ non_matched_files: List[str] = []
114
+ non_matched_dirs: List[str] = []
115
+ directories_skipped: List[str] = []
116
+
117
+ for path in paths:
95
118
  rel = path.relative_to(root).as_posix()
96
119
 
97
120
  if spec.match_file(rel):
98
- keep.append(rel)
121
+ self._log.debug(f"✅ KEEP {rel}")
122
+ matched.append(rel)
99
123
  continue
100
124
 
101
125
  if path.is_dir():
102
- if self._dir_has_kept_ancestor(rel, spec):
103
- self._log.debug("⏭️ SKIP DIR (kept ancestor): %s", rel)
126
+ if is_dir_protected(rel, spec):
127
+ self._log.debug(f"⏭️ SKIPPING DELETE: Protected ancestor found: {path}")
128
+ directories_skipped.append(rel)
104
129
  else:
105
- self._log.debug("❌ DELETE DIR: %s", rel)
106
- delete_dirs.append(rel)
130
+ self._log.debug(f"❌ DELETE DIR: {rel}")
131
+ non_matched_dirs.append(rel)
107
132
  else:
108
- self._log.debug("❌ DELETE FILE: %s", rel)
109
- delete_files.append(rel)
133
+ non_matched_files.append(rel)
110
134
 
111
- # -- perform deletions -------------------------------------------------- #
112
- for f in delete_files:
113
- self._f.remove_file(root / f)
135
+ return matched, non_matched_dirs, non_matched_files, directories_skipped
114
136
 
115
- # delete directories bottom-up to avoid “directory not empty” errors
116
- for d in sorted(delete_dirs, key=lambda p: p.count("/"), reverse=True):
117
- (root / d).rmdir()
118
-
119
- # -- summary ------------------------------------------------------------ #
120
- self._log.info("✅ kept : %d", len(keep))
121
- self._log.info("🗂️ dirs : %d deleted", len(delete_dirs))
122
- self._log.info("📄 files : %d deleted", len(delete_files))
137
+ # --------------------------------------------------------------------------- #
138
+ # Summary printing helpers #
139
+ # --------------------------------------------------------------------------- #
140
+ def _print_section(self, title: str, items: List[str]) -> None:
141
+ self._log.info(f"{title} {len(items)}")
142
+ if items:
143
+ for p in sorted(items):
144
+ self._log.info(" %s", p)
145
+ else:
146
+ self._log.info(" (none)")
147
+ self._log.info("-" * 70)
148
+
149
+ def print_summary(
150
+ self,
151
+ matched: List[str],
152
+ non_matched_dirs: List[str],
153
+ non_matched_files: List[str],
154
+ ) -> None:
155
+ """Human-friendly digest of keep/delete results."""
156
+ self._log.info("\n" + "=" * 70)
157
+ self._print_section("✅ MATCHED (keep)", matched)
158
+ self._print_section("🗂️ NON-MATCHED DIRECTORIES (delete)", non_matched_dirs)
159
+ self._print_section("📄 NON-MATCHED FILES (delete)", non_matched_files)
160
+ self._log.info("=" * 70)
123
161
 
124
162
  @staticmethod
125
- def _dir_has_kept_ancestor(rel: str, spec: PathSpec) -> bool:
163
+ def _is_dir_protected(relative_path: str, spec: PathSpec) -> bool:
126
164
  """
127
- Return True if *rel* **or any of its ancestors** is matched by *spec*.
165
+ Walks from `path` up to `root`, and returns True if any ancestor
166
+ is matched by the spec.
128
167
  """
129
- parts = rel.split("/")
130
- return any(spec.match_file("/".join(parts[: i + 1])) for i in range(len(parts)))
168
+ if spec.match_file(relative_path):
169
+ return True
170
+ return False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: haraka
3
- Version: 0.2.31
3
+ Version: 0.2.33
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
@@ -17,7 +17,7 @@ haraka/post_gen/service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
17
17
  haraka/post_gen/service/command.py,sha256=yvEzW9rMSXWeQ_2DXuQNtGH6sRuZnK6viMud-amFQXw,2348
18
18
  haraka/post_gen/service/fileOps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  haraka/post_gen/service/fileOps/files.py,sha256=Jm_0bhvVnNqSPGKQ2RnMpx8JLV74M-IXMmwly9fpmVw,3020
20
- haraka/post_gen/service/fileOps/purge.py,sha256=fU-sQ0ThjW9op0e0gfEgmrqodyt50aSw_Xy-qJP1Kjs,4970
20
+ haraka/post_gen/service/fileOps/purge.py,sha256=DA0BRmn01jBMv4DScjRk95KMCE1n_DbeD468YqgVFB0,6298
21
21
  haraka/post_gen/service/gitOps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
22
  haraka/post_gen/service/gitOps/gitops.py,sha256=clWny1m9qB4yr8asba8JwqBjewlMVsJUmIOCLtAL8RI,4052
23
23
  haraka/utils/__init__.py,sha256=3Cp4u0dyAGcmqes-tIr95KFsNsJx5Ji5Yzkto9546Hs,168
@@ -29,7 +29,7 @@ haraka/utils/manifests/go-grpc-gateway-buf.yml,sha256=47DEQpj8HBSa-_TImW-5JCeuQe
29
29
  haraka/utils/manifests/go-grpc-protoc.yml,sha256=OaQlfW_S_OguhW_UcpBVdqdEtUMlg-SrT4bqLhQrY7Y,936
30
30
  haraka/utils/manifests/java-springboot.yml,sha256=DTZoVrIDNVpq2AuuXjL2jAvPggeKWVuKJEKwFb90cz4,989
31
31
  haraka/utils/manifests/python-fastapi.yml,sha256=nhO6S9j_r-S10nM8nuw7PtR247-ePhBXHvaXg74CjWw,922
32
- haraka-0.2.31.dist-info/METADATA,sha256=zqfs-3D99QSYiPBh9Qea6NkfMxf8VNPSB_o9UJDAB3Q,579
33
- haraka-0.2.31.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
34
- haraka-0.2.31.dist-info/top_level.txt,sha256=1khpwypLKWoklVd_CgFiwAfcctVSXRoRPc3BI9lyIXo,7
35
- haraka-0.2.31.dist-info/RECORD,,
32
+ haraka-0.2.33.dist-info/METADATA,sha256=i4dTqI3SMwj6Gn_4_YHtutOGW_o_aga1VXNyS_4knOU,579
33
+ haraka-0.2.33.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
34
+ haraka-0.2.33.dist-info/top_level.txt,sha256=1khpwypLKWoklVd_CgFiwAfcctVSXRoRPc3BI9lyIXo,7
35
+ haraka-0.2.33.dist-info/RECORD,,