115 lines
3.9 KiB
Python
115 lines
3.9 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
embed_for_dist.py
|
||
─────────────────
|
||
Re-embeds edited source files back into Avaya_5952_setup.py
|
||
for single-file distribution to end users.
|
||
|
||
Run after editing source files:
|
||
python embed_for_dist.py
|
||
|
||
This is the reverse of extract_for_dev.py.
|
||
"""
|
||
|
||
import re, sys, ast
|
||
from pathlib import Path
|
||
|
||
HERE = Path(__file__).parent
|
||
SETUP = HERE / "Avaya_5952_setup.py"
|
||
|
||
if not SETUP.exists():
|
||
print(f"Error: {SETUP} not found")
|
||
sys.exit(1)
|
||
|
||
src = SETUP.read_text()
|
||
|
||
# ── Helper: replace a repr()-encoded constant ───────────────────────────────
|
||
|
||
def replace_repr(src, name, new_value):
|
||
idx = src.find(f'\n{name} = ')
|
||
if idx == -1:
|
||
print(f" Warning: {name} not found in setup script")
|
||
return src
|
||
start = idx + len(f'\n{name} = ')
|
||
qc = src[start]
|
||
end = start + 1
|
||
while end < len(src):
|
||
if src[end] == qc and src[end-1] != '\\':
|
||
end += 1; break
|
||
end += 1
|
||
new_repr = repr(new_value)
|
||
return src[:start] + new_repr + src[end:]
|
||
|
||
# ── Helper: replace a triple-quoted constant ────────────────────────────────
|
||
|
||
def replace_triple(src, name, new_value):
|
||
pattern = rf'({name}\s*=\s*""").*?(""")'
|
||
replacement = r'\g<1>' + new_value.replace('\\', '\\\\') + r'\g<2>'
|
||
new_src = re.sub(pattern, replacement, src, flags=re.DOTALL)
|
||
if new_src == src:
|
||
print(f" Warning: {name} not found or unchanged")
|
||
return new_src
|
||
|
||
# ── Files to embed ───────────────────────────────────────────────────────────
|
||
|
||
embeddings = [
|
||
# (embed_fn, source_filename, constant_name, note)
|
||
(replace_repr, 'switch_backend.py', 'BACKEND_SRC', "FastAPI backend"),
|
||
(replace_repr, 'ers5952-manager.jsx', 'JSX_SRC', "React frontend"),
|
||
(replace_repr, 'README.md', 'README_SRC', "Documentation"),
|
||
(replace_triple, 'Dockerfile', 'DOCKERFILE', "Docker image"),
|
||
(replace_triple, 'docker-compose.yml', 'COMPOSE_YML', "Docker Compose"),
|
||
]
|
||
|
||
print("Embedding source files into Avaya_5952_setup.py...\n")
|
||
|
||
updated = src
|
||
changed = []
|
||
|
||
for fn, fname, const, note in embeddings:
|
||
fpath = HERE / fname
|
||
if not fpath.exists():
|
||
print(f" ✗ {fname:<35} not found — skipping")
|
||
continue
|
||
content = fpath.read_text()
|
||
new_src = fn(updated, const, content)
|
||
if new_src != updated:
|
||
updated = new_src
|
||
changed.append(fname)
|
||
print(f" ✓ {fname:<35} {note} ({len(content):,} chars)")
|
||
else:
|
||
print(f" – {fname:<35} unchanged")
|
||
|
||
if not changed:
|
||
print("\nNo changes — Avaya_5952_setup.py not modified")
|
||
sys.exit(0)
|
||
|
||
# ── Validate syntax before writing ──────────────────────────────────────────
|
||
|
||
print("\nValidating Python syntax...")
|
||
try:
|
||
ast.parse(updated)
|
||
print(" ✓ Syntax OK")
|
||
except SyntaxError as e:
|
||
print(f" ✗ Syntax error at line {e.lineno}: {e.msg}")
|
||
print(" Avaya_5952_setup.py NOT modified — fix the error first")
|
||
sys.exit(1)
|
||
|
||
# ── Write ────────────────────────────────────────────────────────────────────
|
||
|
||
# Backup first
|
||
backup = SETUP.with_suffix('.py.bak')
|
||
backup.write_text(src)
|
||
print(f" Backup saved to {backup.name}")
|
||
|
||
SETUP.write_text(updated)
|
||
|
||
import os
|
||
size = os.path.getsize(SETUP)
|
||
print(f"\n✓ Avaya_5952_setup.py updated ({size:,} bytes, {size//1024} KB)")
|
||
print(f" {len(changed)} file(s) embedded: {', '.join(changed)}")
|
||
print("""
|
||
The updated Avaya_5952_setup.py is ready for distribution.
|
||
Test it: python Avaya_5952_setup.py
|
||
""")
|