Compare commits
1 Commits
v.0.0.0.23
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a675da959 |
7
hooks/hook-pygount.py
Normal file
7
hooks/hook-pygount.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from PyInstaller.utils.hooks import collect_all
|
||||||
|
|
||||||
|
# Collect all package data, binaries and hidden imports from pygount
|
||||||
|
datas, binaries, hiddenimports = collect_all('pygount')
|
||||||
|
|
||||||
|
# Export to PyInstaller
|
||||||
|
__all__ = ['datas', 'binaries', 'hiddenimports']
|
||||||
23
pyucc.spec.bak
Normal file
23
pyucc.spec.bak
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
from PyInstaller.utils.hooks import collect_all
|
||||||
|
|
||||||
|
# Ensure pygount package contents are explicitly collected (datas, binaries, hiddenimports)
|
||||||
|
_pygount_datas, _pygount_binaries, _pygount_hiddenimports = collect_all('pygount')
|
||||||
|
|
||||||
|
block_cipher = None
|
||||||
|
a = Analysis(pathex=['pyucc', '.'], binaries=[], datas=[('PyUcc.ico', '.'), ('external\\python-tkinter-logger\\tkinter_logger.py', '.'), ('external\\python-resource-monitor\\resource_monitor.py', '.'), ('external\\python-resource-monitor', 'python-resource-monitor'), ('external\\python-tkinter-logger', 'python-tkinter-logger'), ('external\\_setup_paths.py', '.'), ('external\\python-resource-monitor', 'python-resource-monitor'), ('external\\python-tkinter-logger', 'python-tkinter-logger'), ('external\\_setup_paths.py', '.'), ('external\\python-resource-monitor', 'python-resource-monitor'), ('external\\python-tkinter-logger', 'python-tkinter-logger'), ('external\\_setup_paths.py', '.'), ('external\\python-resource-monitor', 'python-resource-monitor'), ('external\\python-tkinter-logger', 'python-tkinter-logger')], hiddenimports=['tkinter_logger', 'resource_monitor', 'pyucc.core.differ', 'pyucc.gui.gui', 'pyucc.config.settings', 'logging', 'logging.handlers', 'logging.config', 'ConfigParser', 'Cython', 'HTMLParser', 'IPython', 'OpenSSL', 'PIL', 'Queue', 'StringIO', 'android', 'annotationlib', 'argcomplete', 'attr', 'autocommand', 'backports', 'cgi', 'chardet', 'colorama', 'contextlib2', 'cryptography', 'ctags', 'distutils', 'dl', 'docutils', 'dummy_thread', 'dummy_threading', 'exceptiongroup', 'fcntl', 'filelock', 'future_builtins', 'git', 'gitdb', 'gitdb_speedups', 'google', 'grp', 'htmlentitydefs', 'httplib', 'importlib_metadata', 'importlib_resources', 'inflect', 'ini2toml', 'iniconfig', 'ipywidgets', 'jaraco', 'java', 'jinja2', 'jnius', 'keyring', 'linkify_it', 'lizard', 'lizard_ext', 'lizard_languages', 'markdown_it', 'mdurl', 'mock', 'mod', 'mod2', 'more_itertools', 'nspkg', 'ntlm', 'numpy', 'packaging', 'path', 'pathspec', 'pexpect', 'pip', 'pkg1', 'pkg_resources', 'platformdirs', 'pluggy', 'psutil', 'pwd', 'py', 'pygments', 'pygount', 'pytest', 'pyucc', 'pywintypes', 'readline', 'redis', 'resource', 'rich', 'setuptools', 'sha', 'smmap', 'socks', 'sphinx', 'target_simulator', 'thread', 'tomli', 'tomli_w', 'trove_classifiers', 'twisted', 'typeguard', 'typeshed', 'typing_extensions', 'urllib2', 'urllib3_secure_extra', 'urlparse', 'wheel', 'win32api', 'win32con', 'win32process', 'wmi', 'xmlrpclib', 'xx', 'zipp', 'zope', 'traitlets', 'gdb', 'matplotlib', 'PyInstaller'], hookspath=['hooks'], runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher, noarchive=False, scripts=['pyucc\\__main__.py'])
|
||||||
|
try:
|
||||||
|
a.hiddenimports += _pygount_hiddenimports
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
||||||
|
exe = EXE(pyz, a.scripts, a.binaries, a.zipfiles, a.datas, [], name='PyUcc', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, upx_exclude=[], runtime_tmpdir=None, console=False, icon='PyUcc.ico', exclude_binaries=True)
|
||||||
|
coll = COLLECT(exe, a.binaries, a.zipfiles, a.datas, strip=False, upx=True, upx_exclude=[], name='PyUcc')
|
||||||
|
block_cipher = None
|
||||||
|
a = Analysis(pathex=['pyucc', '.'], binaries=[], datas=[('PyUcc.ico', '.'), ('external\\python-tkinter-logger\\tkinter_logger.py', '.'), ('external\\python-resource-monitor\\resource_monitor.py', '.'), ('external\\python-resource-monitor', 'python-resource-monitor'), ('external\\python-tkinter-logger', 'python-tkinter-logger'), ('external\\_setup_paths.py', '.'), ('external\\python-resource-monitor', 'python-resource-monitor'), ('external\\python-tkinter-logger', 'python-tkinter-logger'), ('external\\_setup_paths.py', '.'), ('external\\python-resource-monitor', 'python-resource-monitor'), ('external\\python-tkinter-logger', 'python-tkinter-logger'), ('external\\_setup_paths.py', '.'), ('external\\python-resource-monitor', 'python-resource-monitor'), ('external\\python-tkinter-logger', 'python-tkinter-logger')], hiddenimports=['tkinter_logger', 'resource_monitor', 'pyucc.core.differ', 'pyucc.gui.gui', 'pyucc.config.settings', 'logging', 'logging.handlers', 'logging.config', 'ConfigParser', 'Cython', 'HTMLParser', 'IPython', 'OpenSSL', 'PIL', 'Queue', 'StringIO', 'android', 'annotationlib', 'argcomplete', 'attr', 'autocommand', 'backports', 'cgi', 'chardet', 'colorama', 'contextlib2', 'cryptography', 'ctags', 'distutils', 'dl', 'docutils', 'dummy_thread', 'dummy_threading', 'exceptiongroup', 'fcntl', 'filelock', 'future_builtins', 'git', 'gitdb', 'gitdb_speedups', 'google', 'grp', 'htmlentitydefs', 'httplib', 'importlib_metadata', 'importlib_resources', 'inflect', 'ini2toml', 'iniconfig', 'ipywidgets', 'jaraco', 'java', 'jinja2', 'jnius', 'keyring', 'linkify_it', 'lizard', 'lizard_ext', 'lizard_languages', 'markdown_it', 'mdurl', 'mock', 'mod', 'mod2', 'more_itertools', 'nspkg', 'ntlm', 'numpy', 'packaging', 'path', 'pathspec', 'pexpect', 'pip', 'pkg1', 'pkg_resources', 'platformdirs', 'pluggy', 'psutil', 'pwd', 'py', 'pygments', 'pygount', 'pytest', 'pyucc', 'pywintypes', 'readline', 'redis', 'resource', 'rich', 'setuptools', 'sha', 'smmap', 'socks', 'sphinx', 'target_simulator', 'thread', 'tomli', 'tomli_w', 'trove_classifiers', 'twisted', 'typeguard', 'typeshed', 'typing_extensions', 'urllib2', 'urllib3_secure_extra', 'urlparse', 'wheel', 'win32api', 'win32con', 'win32process', 'wmi', 'xmlrpclib', 'xx', 'zipp', 'zope', 'traitlets', 'gdb', 'matplotlib', 'PyInstaller'], hookspath=[], runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher, noarchive=False, scripts=['pyucc\\__main__.py'])
|
||||||
|
try:
|
||||||
|
a.hiddenimports += _pygount_hiddenimports
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
||||||
|
exe = EXE(pyz, a.scripts, a.binaries, a.zipfiles, a.datas, [], name='PyUcc', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, upx_exclude=[], runtime_tmpdir=None, console=False, icon='PyUcc.ico', exclude_binaries=True)
|
||||||
|
coll = COLLECT(exe, a.binaries, a.zipfiles, a.datas, strip=False, upx=True, upx_exclude=[], name='PyUcc')
|
||||||
@ -151,19 +151,19 @@ def main():
|
|||||||
|
|
||||||
if not getattr(countings_impl, "_HAS_PYGOUNT", False):
|
if not getattr(countings_impl, "_HAS_PYGOUNT", False):
|
||||||
print(
|
print(
|
||||||
"ATTENZIONE: il pacchetto 'pygount' non è disponibile. I conteggi dei commenti e le metriche estese potrebbero non essere disponibili.",
|
"WARNING: the 'pygount' package is not available. Comment counts and some extended metrics may not be available.",
|
||||||
file=sys.stderr,
|
file=sys.stderr,
|
||||||
)
|
)
|
||||||
print(
|
print(
|
||||||
"Per risolvere: attiva la virtualenv usata per eseguire l'app e esegui 'pip install pygount'",
|
"To fix: activate the virtualenv used to run the app and run 'pip install pygount'",
|
||||||
file=sys.stderr,
|
file=sys.stderr,
|
||||||
)
|
)
|
||||||
print(
|
print(
|
||||||
"Se distribuisci con PyInstaller, ricostruisci l'eseguibile includendo 'pygount' (aggiungi un hook o hiddenimports).",
|
"If you ship a PyInstaller executable, rebuild it including 'pygount' (add a hook or hiddenimports).",
|
||||||
file=sys.stderr,
|
file=sys.stderr,
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
# Non critico: continuiamo senza interrompere l'esecuzione
|
# Non-critical: continue execution
|
||||||
pass
|
pass
|
||||||
# If user asked for GUI, or no positional directories were provided, launch GUI and exit
|
# If user asked for GUI, or no positional directories were provided, launch GUI and exit
|
||||||
if args.gui or len(args.baseline_dirs or []) == 0:
|
if args.gui or len(args.baseline_dirs or []) == 0:
|
||||||
|
|||||||
BIN
pyucc/_internal/pygount-3.0.0-py3-none-any.whl
Normal file
BIN
pyucc/_internal/pygount-3.0.0-py3-none-any.whl
Normal file
Binary file not shown.
@ -6,10 +6,10 @@
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
# --- Version Data (Generated) ---
|
# --- Version Data (Generated) ---
|
||||||
__version__ = "v.0.0.0.22-0-gea1d31b-dirty"
|
__version__ = "v.0.0.0.23-0-gc67280d-dirty"
|
||||||
GIT_COMMIT_HASH = "ea1d31b82e9fa64a3bb809c001f8c465fbcb0294"
|
GIT_COMMIT_HASH = "c67280df44cb0db1bad3815a2938adc0904a10de"
|
||||||
GIT_BRANCH = "master"
|
GIT_BRANCH = "master"
|
||||||
BUILD_TIMESTAMP = "2025-12-15T07:30:39.921932+00:00"
|
BUILD_TIMESTAMP = "2025-12-15T09:32:07.391542+00:00"
|
||||||
IS_GIT_REPO = True
|
IS_GIT_REPO = True
|
||||||
|
|
||||||
# --- Default Values (for comparison or fallback) ---
|
# --- Default Values (for comparison or fallback) ---
|
||||||
|
|||||||
@ -10,14 +10,90 @@ import subprocess
|
|||||||
import logging
|
import logging
|
||||||
import threading
|
import threading
|
||||||
import hashlib
|
import hashlib
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import glob
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import pygount # type: ignore
|
import pygount # type: ignore
|
||||||
|
|
||||||
_HAS_PYGOUNT = True
|
_HAS_PYGOUNT = True
|
||||||
except Exception:
|
except Exception:
|
||||||
|
# Try to load a bundled pygount wheel (offline install) — useful for PyInstaller one-folder
|
||||||
_HAS_PYGOUNT = False
|
_HAS_PYGOUNT = False
|
||||||
|
|
||||||
|
def _attempt_load_bundled_pygount() -> bool:
|
||||||
|
"""If a pygount wheel is bundled with the app (e.g. in _internal), add it to sys.path and try import.
|
||||||
|
|
||||||
|
Returns True if import succeeded.
|
||||||
|
"""
|
||||||
|
|
||||||
|
candidates = []
|
||||||
|
# If running frozen (PyInstaller), packaged data are extracted to sys._MEIPASS
|
||||||
|
base = getattr(sys, "_MEIPASS", None)
|
||||||
|
if base:
|
||||||
|
# search both at root of MEIPASS and recursively (some datas end up nested)
|
||||||
|
candidates.append(os.path.join(base, "pygount*.whl"))
|
||||||
|
candidates.append(os.path.join(base, "**", "pygount*.whl"))
|
||||||
|
candidates.append(os.path.join(base, "pygount", "**", "*.py"))
|
||||||
|
candidates.append(os.path.join(base, "**", "pygount", "**", "*.py"))
|
||||||
|
# Also look into a relative _internal folder in source tree
|
||||||
|
repo_internal = os.path.normpath(os.path.join(os.path.dirname(__file__), "..", "_internal"))
|
||||||
|
candidates.append(os.path.join(repo_internal, "pygount*.whl"))
|
||||||
|
candidates.append(os.path.join(repo_internal, "pygount", "**", "*.py"))
|
||||||
|
|
||||||
|
found_paths = []
|
||||||
|
for pattern in candidates:
|
||||||
|
try:
|
||||||
|
for p in glob.glob(pattern, recursive=True):
|
||||||
|
if p and p not in found_paths:
|
||||||
|
found_paths.append(p)
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Prefer a wheel file if present (zipimport works for wheels)
|
||||||
|
wheel_paths = [p for p in found_paths if p.lower().endswith('.whl')]
|
||||||
|
if wheel_paths:
|
||||||
|
wheel = wheel_paths[0]
|
||||||
|
try:
|
||||||
|
if wheel not in sys.path:
|
||||||
|
sys.path.insert(0, wheel)
|
||||||
|
import pygount # type: ignore
|
||||||
|
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
# remove added path if import failed
|
||||||
|
try:
|
||||||
|
if wheel in sys.path:
|
||||||
|
sys.path.remove(wheel)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# If no wheel, try adding a plain package folder
|
||||||
|
pkg_dirs = [os.path.dirname(p) for p in found_paths if p.lower().endswith('.py')]
|
||||||
|
# remove duplicates
|
||||||
|
pkg_dirs = list(dict.fromkeys(pkg_dirs))
|
||||||
|
for d in pkg_dirs:
|
||||||
|
try:
|
||||||
|
if d not in sys.path:
|
||||||
|
sys.path.insert(0, d)
|
||||||
|
import pygount # type: ignore
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
try:
|
||||||
|
if d in sys.path:
|
||||||
|
sys.path.remove(d)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
if _attempt_load_bundled_pygount():
|
||||||
|
_HAS_PYGOUNT = True
|
||||||
|
except Exception:
|
||||||
|
_HAS_PYGOUNT = False
|
||||||
|
|
||||||
_LOG = logging.getLogger(__name__)
|
_LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
# Cache to store counting results by file content hash ONLY
|
# Cache to store counting results by file content hash ONLY
|
||||||
|
|||||||
@ -238,25 +238,25 @@ class App(tk.Tk):
|
|||||||
if not getattr(countings_impl, "_HAS_PYGOUNT", False):
|
if not getattr(countings_impl, "_HAS_PYGOUNT", False):
|
||||||
msg = (
|
msg = (
|
||||||
"""
|
"""
|
||||||
Il pacchetto 'pygount' non è disponibile.
|
The 'pygount' package is not available.
|
||||||
|
|
||||||
I conteggi dei commenti e alcune metriche estese potrebbero non funzionare correttamente.
|
Comment counting and some extended metrics may not work correctly.
|
||||||
|
|
||||||
Soluzioni possibili:
|
Possible fixes:
|
||||||
1) Se usi l'ambiente di sviluppo: attiva la virtualenv e esegui 'pip install pygount'.
|
1) If you are using a development environment: activate the virtualenv and run 'pip install pygount'.
|
||||||
2) Se usi l'eseguibile PyInstaller: ricostruiscilo includendo 'pygount' (hook o hiddenimports).
|
2) If you are using a PyInstaller-built executable: rebuild it including 'pygount' (hook or hiddenimports).
|
||||||
3) Per controllare rapidamente: esegui
|
3) Quick check: run
|
||||||
python -c 'from pyucc.core import countings_impl; print(countings_impl._HAS_PYGOUNT)'
|
python -c "from pyucc.core import countings_impl; print(countings_impl._HAS_PYGOUNT)"
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
messagebox.showwarning("Dipendenza mancante: pygount", msg)
|
messagebox.showwarning("Missing dependency: pygount", msg)
|
||||||
except Exception:
|
except Exception:
|
||||||
# If messagebox fails (headless), fallback to logging
|
# If messagebox fails (headless), fallback to logging
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
self.log(
|
self.log(
|
||||||
"pygount non disponibile: conteggio commenti e metriche estese disabilitate",
|
"pygount not available: comment counting and extended metrics disabled",
|
||||||
level="WARNING",
|
level="WARNING",
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|||||||
@ -5,8 +5,14 @@
|
|||||||
"duplicates": {
|
"duplicates": {
|
||||||
"threshold": 5.0,
|
"threshold": 5.0,
|
||||||
"extensions": [
|
"extensions": [
|
||||||
".py",
|
".inl",
|
||||||
".pyw"
|
".h",
|
||||||
|
".hh",
|
||||||
|
".c",
|
||||||
|
".cxx",
|
||||||
|
".hpp",
|
||||||
|
".cpp",
|
||||||
|
".cc"
|
||||||
],
|
],
|
||||||
"k": 25,
|
"k": 25,
|
||||||
"window": 4
|
"window": 4
|
||||||
|
|||||||
162
tools/bundle_pygount.py
Normal file
162
tools/bundle_pygount.py
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Bundle pygount wheel into the project and update pyucc.spec.
|
||||||
|
|
||||||
|
Usage: run inside your project's virtualenv/checkout root:
|
||||||
|
python tools/bundle_pygount.py
|
||||||
|
|
||||||
|
What it does:
|
||||||
|
- Locates a local `pygount-*.whl` in the current Python environment (site-packages)
|
||||||
|
- Copies it to `pyucc/_internal/`
|
||||||
|
- Updates `pyucc.spec`, adding the wheel as a `datas` entry so PyInstaller bundles it
|
||||||
|
|
||||||
|
This enables the runtime fallback added in `pyucc.core.countings_impl` to import pygount
|
||||||
|
from a bundled wheel when running on an offline target.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import shutil
|
||||||
|
import glob
|
||||||
|
from pathlib import Path
|
||||||
|
import sysconfig
|
||||||
|
import site
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
SPEC_PATH = REPO_ROOT / "pyucc.spec"
|
||||||
|
DEST_DIR = REPO_ROOT / "pyucc" / "_internal"
|
||||||
|
|
||||||
|
|
||||||
|
def find_local_pygount_wheel() -> Path | None:
|
||||||
|
"""Search common site-packages locations for pygount-*.whl and return first match."""
|
||||||
|
candidates = []
|
||||||
|
|
||||||
|
# Preferred: current environment's site-packages (sysconfig)
|
||||||
|
try:
|
||||||
|
purelib = sysconfig.get_paths().get("purelib")
|
||||||
|
if purelib:
|
||||||
|
candidates.append(Path(purelib))
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# site.getsitepackages() may return multiple dirs
|
||||||
|
try:
|
||||||
|
for p in site.getsitepackages():
|
||||||
|
candidates.append(Path(p))
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Fallback: sys.path entries
|
||||||
|
for p in sys.path:
|
||||||
|
try:
|
||||||
|
candidates.append(Path(p))
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Also check repository-local wheel folder and current working dir
|
||||||
|
try:
|
||||||
|
candidates.append(REPO_ROOT / "wheels")
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
candidates.append(Path.cwd())
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
candidates.append(DEST_DIR)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
seen = set()
|
||||||
|
for base in candidates:
|
||||||
|
if not base:
|
||||||
|
continue
|
||||||
|
base = base.resolve()
|
||||||
|
if str(base) in seen:
|
||||||
|
continue
|
||||||
|
seen.add(str(base))
|
||||||
|
pattern = str(base / "pygount-*.whl")
|
||||||
|
for f in glob.glob(pattern):
|
||||||
|
if f:
|
||||||
|
return Path(f).resolve()
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def copy_wheel_to_internal(wheel_path: Path) -> Path:
|
||||||
|
DEST_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
|
dest = DEST_DIR / wheel_path.name
|
||||||
|
shutil.copy2(wheel_path, dest)
|
||||||
|
return dest
|
||||||
|
|
||||||
|
|
||||||
|
def patch_spec_add_datas(spec_path: Path, wheel_rel_path: str) -> bool:
|
||||||
|
"""Insert a datas tuple ('<wheel_rel_path>', '_internal') into all datas=[...] lists in the spec.
|
||||||
|
|
||||||
|
Returns True if file modified.
|
||||||
|
"""
|
||||||
|
text = spec_path.read_text(encoding="utf-8")
|
||||||
|
tuple_entry = f"('{wheel_rel_path}', '_internal'),"
|
||||||
|
|
||||||
|
if tuple_entry in text:
|
||||||
|
print("Spec already contains wheel datas entry; nothing to do.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Find all occurrences of 'datas=[' and insert the tuple after the opening bracket
|
||||||
|
new_text = text
|
||||||
|
inserts = 0
|
||||||
|
idx = 0
|
||||||
|
while True:
|
||||||
|
m = re.search(r"\bdatas\s*=\s*\[", new_text[idx:])
|
||||||
|
if not m:
|
||||||
|
break
|
||||||
|
# m.start() relative to new_text[idx:]
|
||||||
|
start = idx + m.end()
|
||||||
|
# Insert after start
|
||||||
|
new_text = new_text[:start] + tuple_entry + new_text[start:]
|
||||||
|
inserts += 1
|
||||||
|
idx = start + len(tuple_entry)
|
||||||
|
|
||||||
|
if inserts:
|
||||||
|
backup = spec_path.with_suffix(spec_path.suffix + ".bak")
|
||||||
|
spec_path.replace(backup)
|
||||||
|
spec_path.write_text(new_text, encoding="utf-8")
|
||||||
|
print(f"Patched {spec_path} - inserted datas entry in {inserts} places (backup saved to {backup}).")
|
||||||
|
return True
|
||||||
|
|
||||||
|
print(r"No datas=\[...] occurrences found in spec; no changes made.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print(f"Repo root: {REPO_ROOT}")
|
||||||
|
|
||||||
|
wheel = find_local_pygount_wheel()
|
||||||
|
if not wheel:
|
||||||
|
print("Could not locate a local pygount wheel in this environment.")
|
||||||
|
print("Please download a pygount wheel (pygount-<ver>-py3-none-any.whl) into your environment or site-packages.")
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
print(f"Found pygount wheel: {wheel}")
|
||||||
|
|
||||||
|
dest = copy_wheel_to_internal(wheel)
|
||||||
|
print(f"Copied wheel to: {dest}")
|
||||||
|
|
||||||
|
# wheel_rel_path relative to project root (use forward slashes)
|
||||||
|
wheel_rel = f"pyucc/_internal/{dest.name}"
|
||||||
|
|
||||||
|
if not SPEC_PATH.exists():
|
||||||
|
print(f"Spec file not found at {SPEC_PATH}; please run this script from project root.")
|
||||||
|
sys.exit(3)
|
||||||
|
|
||||||
|
changed = patch_spec_add_datas(SPEC_PATH, wheel_rel)
|
||||||
|
if changed:
|
||||||
|
print("Specification updated. Rebuild using: pyinstaller pyucc.spec")
|
||||||
|
else:
|
||||||
|
print("Specification unchanged.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
9
tools/check_pygount_build.py
Normal file
9
tools/check_pygount_build.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import sys, importlib
|
||||||
|
sys.path.insert(0, r'dist\\PyUcc')
|
||||||
|
from pyucc.core import countings_impl as c
|
||||||
|
print('HAS_PYGOUNT=', getattr(c, '_HAS_PYGOUNT', 'UNKNOWN'))
|
||||||
|
try:
|
||||||
|
m = importlib.import_module('pygount')
|
||||||
|
print('pygount import ok, version=', getattr(m, '__version__', '?'))
|
||||||
|
except Exception as e:
|
||||||
|
print('pygount import failed:', repr(e))
|
||||||
Loading…
Reference in New Issue
Block a user