maketool 0.7.6__tar.gz → 0.7.8__tar.gz

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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maketool
3
- Version: 0.7.6
3
+ Version: 0.7.8
4
4
  Summary: Python Automation tool for building PySide6 UI and PyInstaller EXE.
5
5
  Author-email: Alan Lilly <panofish@gmail.com>
6
6
  Requires-Python: >=3.7
@@ -316,7 +316,10 @@ def compute_missing_used_imports(
316
316
 
317
317
 
318
318
  def print_missing_imports(entry: Path) -> None:
319
- print("MISSING (used but not installed):")
319
+
320
+ title = "MISSING (used but not installed):"
321
+ print(title)
322
+ print("-" * len(title))
320
323
 
321
324
  if packages_distributions is None:
322
325
  print(" (skipped: Python 3.8+ required for packages_distributions())")
@@ -356,13 +359,9 @@ def print_missing_imports(entry: Path) -> None:
356
359
 
357
360
  def main() -> int:
358
361
 
359
- print("ARGV:", sys.argv)
360
-
361
362
  # refscan input: optional positional path (Sublime {file}); otherwise CWD
362
363
  entry: Optional[Path] = None
363
- print(f"entry = {entry}")
364
364
  root = Path.cwd().resolve()
365
- print(f"root = {root}")
366
365
 
367
366
  if len(sys.argv) >= 2:
368
367
  p = Path(sys.argv[1]).expanduser()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maketool
3
- Version: 0.7.6
3
+ Version: 0.7.8
4
4
  Summary: Python Automation tool for building PySide6 UI and PyInstaller EXE.
5
5
  Author-email: Alan Lilly <panofish@gmail.com>
6
6
  Requires-Python: >=3.7
@@ -4,7 +4,6 @@ maketool/__init__.py
4
4
  maketool/build.py
5
5
  maketool/clean.py
6
6
  maketool/compile.py
7
- maketool/refscan - Copy.py
8
7
  maketool/refscan.py
9
8
  maketool/run.py
10
9
  maketool/sublime.py
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "maketool"
3
- version = "0.7.6"
3
+ version = "0.7.8"
4
4
  description = "Python Automation tool for building PySide6 UI and PyInstaller EXE."
5
5
  authors = [{ name = "Alan Lilly", email = "panofish@gmail.com" }]
6
6
  readme = "README.md"
@@ -1,186 +0,0 @@
1
- #!/usr/bin/env python3
2
- """maketool-refscan
3
-
4
- Option B: String reference scan
5
-
6
- - Scans a project directory (derived from Sublime's {file} or current directory)
7
- - Shows ONLY unused candidates
8
- - Groups UNUSED files by extension, separated by a blank line
9
- - No group headers
10
-
11
- Expected input:
12
- refscan.py "C:\\full\\path\\to\\current_file.py"
13
- (Sublime typically passes {file})
14
-
15
- If no argument is provided, scans the current working directory.
16
-
17
- This is intentionally heuristic: it searches for filename/path *tokens* inside
18
- project text sources. It's best for catching unused assets (.ui/.ico/.png/.qss/etc.)
19
- and "orphan" files. For definitive Python reachability, use an import/AST walk.
20
- """
21
-
22
- from __future__ import annotations
23
-
24
- import sys
25
- from collections import defaultdict
26
- from dataclasses import dataclass
27
- from pathlib import Path
28
- from typing import Dict, Iterable, List, Optional, Set, Tuple
29
-
30
-
31
- DEFAULT_IGNORE_DIRS = {
32
- ".git", ".hg", ".svn",
33
- "__pycache__", ".mypy_cache", ".pytest_cache",
34
- ".venv", "venv", "env",
35
- "build", "dist", ".tox",
36
- }
37
-
38
- DEFAULT_SCAN_EXTS = {
39
- ".py", ".ui", ".qrc", ".qss",
40
- ".bat", ".cmd", ".ps1",
41
- ".txt", ".md", ".rst",
42
- ".ini", ".cfg", ".toml",
43
- ".json", ".yaml", ".yml",
44
- ".xml", ".html", ".htm", ".css",
45
- }
46
-
47
- DEFAULT_SKIP_CONTENT_EXTS = {
48
- ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".webp", ".svg",
49
- ".ico", ".icns",
50
- ".pdf", ".zip", ".7z", ".rar",
51
- ".db", ".sqlite", ".dll", ".exe", ".pyd",
52
- }
53
-
54
-
55
- @dataclass(frozen=True)
56
- class Candidate:
57
- path: Path
58
- rel: str
59
- tokens: Tuple[str, ...]
60
-
61
-
62
- def iter_files(root: Path, ignore_dirs: Set[str]) -> Iterable[Path]:
63
- for p in root.rglob("*"):
64
- if p.is_dir():
65
- continue
66
- if any(part in ignore_dirs for part in p.parts):
67
- continue
68
- yield p
69
-
70
-
71
- def safe_read_text(p: Path) -> Optional[str]:
72
- try:
73
- return p.read_text(encoding="utf-8", errors="ignore")
74
- except Exception:
75
- return None
76
-
77
-
78
- def norm(s: str) -> str:
79
- return s.replace("\\", "/").lower()
80
-
81
-
82
- def build_candidates(root: Path, files: List[Path]) -> List[Candidate]:
83
- out: List[Candidate] = []
84
- for p in files:
85
- rel = str(p.relative_to(root))
86
- rel_norm = norm(rel)
87
- base = p.name.lower()
88
- stem = p.stem.lower()
89
-
90
- tokens = {
91
- base,
92
- stem,
93
- rel_norm,
94
- rel_norm.replace("/", "\\"),
95
- }
96
-
97
- out.append(Candidate(p, rel, tuple(t for t in tokens if t)))
98
- return out
99
-
100
-
101
- def is_text_source(p: Path) -> bool:
102
- ext = p.suffix.lower()
103
- if ext in DEFAULT_SKIP_CONTENT_EXTS:
104
- return False
105
- return ext in DEFAULT_SCAN_EXTS
106
-
107
-
108
- def choose_root_from_argv(argv: List[str]) -> Path:
109
- """
110
- If Sublime passes {file}, argv[1] is the absolute file path.
111
- Scan that file's parent directory.
112
- """
113
- if len(argv) >= 2:
114
- p = Path(argv[1]).expanduser()
115
- try:
116
- p = p.resolve()
117
- except Exception:
118
- pass
119
-
120
- if p.suffix:
121
- return p.parent
122
- return p
123
-
124
- return Path.cwd().resolve()
125
-
126
-
127
- def print_unused_grouped(unused: List[Candidate]) -> None:
128
- groups: Dict[str, List[str]] = defaultdict(list)
129
-
130
- for c in unused:
131
- ext = c.path.suffix.lower() or ""
132
- groups[ext].append(c.rel)
133
-
134
- title = "UNUSED files (no filename/path tokens found)"
135
- print(title)
136
- print("-" * len(title))
137
-
138
- first = True
139
- for ext in sorted(groups):
140
- if not first:
141
- print()
142
- first = False
143
-
144
- for rel in sorted(groups[ext]):
145
- print(rel)
146
- print()
147
-
148
-
149
- def main() -> int:
150
- root = choose_root_from_argv(sys.argv)
151
-
152
- if not root.exists() or not root.is_dir():
153
- title = "UNUSED files (no filename/path tokens found)"
154
- print(title)
155
- print("-" * len(title))
156
- print(f"(skipped: root is not a directory: {root})")
157
- print()
158
- return 2
159
-
160
- files = sorted(iter_files(root, DEFAULT_IGNORE_DIRS))
161
- candidates = build_candidates(root, files)
162
- text_sources = [p for p in files if is_text_source(p)]
163
-
164
- references: Dict[str, List[str]] = {c.rel: [] for c in candidates}
165
-
166
- for src in text_sources:
167
- text = safe_read_text(src)
168
- if not text:
169
- continue
170
- hay = text.lower()
171
- src_rel = str(src.relative_to(root))
172
-
173
- for c in candidates:
174
- if src == c.path:
175
- continue
176
- if any(tok in hay for tok in c.tokens):
177
- references[c.rel].append(src_rel)
178
-
179
- unused = [c for c in candidates if not references[c.rel]]
180
- print_unused_grouped(unused)
181
-
182
- return 0
183
-
184
-
185
- if __name__ == "__main__":
186
- raise SystemExit(main())
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes