refactor(obfuscate_release): improve source file selection and cleanup logic, enhancing error handling for asset processing

This commit is contained in:
smueller
2026-05-28 17:24:05 +02:00
parent 1c0a3ff468
commit d7851763f7
2 changed files with 48 additions and 6 deletions

View File

@@ -210,11 +210,39 @@ def collect_asset_groups(asset_root: Path) -> dict[tuple[Path, str, str], list[P
return groups return groups
def pick_source_file(paths: list[Path], base: str, ext: str) -> Path: def pick_source_file(paths: list[Path], base: str, ext: str) -> Path | None:
plain = paths[0].parent / f"{base}{ext}" if not paths:
return None
parent = paths[0].parent
plain = parent / f"{base}{ext}"
ordered: list[Path] = []
if plain in paths: if plain in paths:
return plain ordered.append(plain)
return min(paths, key=lambda p: len(p.name)) for candidate in sorted(paths, key=lambda p: len(p.name)):
if candidate not in ordered:
ordered.append(candidate)
for candidate in ordered:
try:
content = candidate.read_text(encoding="utf-8")
except (OSError, UnicodeDecodeError):
continue
if is_valid_source_content(content):
return candidate
return None
def cleanup_invalid_siblings(paths: list[Path], source: Path) -> None:
for path in paths:
if path == source or not path.exists():
continue
try:
content = path.read_text(encoding="utf-8")
except (OSError, UnicodeDecodeError):
content = ""
if not is_valid_source_content(content):
path.unlink()
def run_cmd(command: list[str], cwd: Path) -> None: def run_cmd(command: list[str], cwd: Path) -> None:
@@ -232,7 +260,10 @@ def run_cmd(command: list[str], cwd: Path) -> None:
def process_js(path: Path, cwd: Path) -> None: def process_js(path: Path, cwd: Path) -> None:
original = path.read_text(encoding="utf-8") original = path.read_text(encoding="utf-8")
if not is_valid_source_content(original): if not is_valid_source_content(original):
raise ValueError(f"invalid or corrupted JS source: {path}") raise ValueError(
f"invalid or corrupted JS source: {path} "
f"(restore e.g. 'git checkout dev -- {path.as_posix()}')"
)
if shutil.which("npx"): if shutil.which("npx"):
tmpdir = Path(tempfile.mkdtemp()) tmpdir = Path(tempfile.mkdtemp())
@@ -360,6 +391,8 @@ def build_hash_mapping(public_root: Path) -> dict[str, str]:
groups = collect_asset_groups(asset_root) groups = collect_asset_groups(asset_root)
for (parent, base, ext), paths in groups.items(): for (parent, base, ext), paths in groups.items():
source = pick_source_file(paths, base, ext) source = pick_source_file(paths, base, ext)
if source is None:
continue
digest = hash_file(source) digest = hash_file(source)
target = parent / f"{base}.{digest}{ext}" target = parent / f"{base}.{digest}{ext}"
rel_new = target.relative_to(public_root).as_posix() rel_new = target.relative_to(public_root).as_posix()
@@ -397,8 +430,17 @@ def main() -> int:
asset_root = public_root / "assets" asset_root = public_root / "assets"
if asset_root.exists(): if asset_root.exists():
groups = collect_asset_groups(asset_root) groups = collect_asset_groups(asset_root)
for (_parent, base, ext), paths in sorted(groups.items()): for (parent, base, ext), paths in sorted(groups.items()):
source = pick_source_file(paths, base, ext) source = pick_source_file(paths, base, ext)
if source is None:
rel = (parent / f"{base}{ext}").relative_to(public_root)
print(
f"ERROR: No valid source for {rel}. "
f"Restore from dev, e.g.: git checkout dev -- {rel}",
file=sys.stderr,
)
return 1
cleanup_invalid_siblings(paths, source)
if ext == ".js": if ext == ".js":
process_js(source, repo_root) process_js(source, repo_root)
else: else: