crosssubtitle-ai/scripts/prepare-bundled-licenses.py
2026-03-19 14:50:22 +08:00

120 lines
3.9 KiB
Python

#!/usr/bin/env python3
from __future__ import annotations
import json
import shutil
from pathlib import Path
ROOT_DIR = Path(__file__).resolve().parent.parent
CELLAR_DIR = Path("/opt/homebrew/Cellar")
LICENSE_ROOT = ROOT_DIR / "src-tauri" / "vendor" / "licenses" / "homebrew"
LICENSE_BUNDLE_ROOT = ROOT_DIR / "src-tauri" / "vendor" / "licenses_bundle"
FFMPEG_RECEIPT = sorted(CELLAR_DIR.glob("ffmpeg/*/INSTALL_RECEIPT.json"))[-1]
LICENSE_PATTERNS = [
"LICENSE*",
"LICENCE*",
"COPYING*",
"COPYRIGHT*",
"NOTICE*",
]
def load_runtime_formulas() -> list[tuple[str, str | None]]:
data = json.loads(FFMPEG_RECEIPT.read_text())
formulas: list[tuple[str, str | None]] = [("ffmpeg", None)]
for item in data.get("runtime_dependencies", []):
full_name = item.get("full_name")
version = item.get("version")
if full_name:
formulas.append((full_name, version))
return formulas
def resolve_formula_dir(name: str, version: str | None) -> Path | None:
if version:
exact = CELLAR_DIR / name / version
if exact.exists():
return exact
matches = sorted((CELLAR_DIR / name).glob("*"))
return matches[-1] if matches else None
def collect_license_files(formula_dir: Path) -> list[Path]:
found: list[Path] = []
seen: set[Path] = set()
for pattern in LICENSE_PATTERNS:
for path in sorted(formula_dir.rglob(pattern)):
if path.is_file() and path not in seen:
seen.add(path)
found.append(path)
return found
def main() -> None:
if LICENSE_ROOT.exists():
shutil.rmtree(LICENSE_ROOT)
LICENSE_ROOT.mkdir(parents=True, exist_ok=True)
LICENSE_BUNDLE_ROOT.mkdir(parents=True, exist_ok=True)
manifest_lines = [
"CrossSubtitle-AI Third-Party Notices",
"",
"This directory contains license files collected from Homebrew formulas",
"used by the bundled ffmpeg binary and its runtime dependencies.",
"",
]
for formula_name, version in load_runtime_formulas():
formula_dir = resolve_formula_dir(formula_name, version)
target_dir = LICENSE_ROOT / formula_name.replace("@", "_at_")
target_dir.mkdir(parents=True, exist_ok=True)
target_dir.chmod(0o755)
if formula_dir is None:
manifest_lines.append(f"- {formula_name}: formula directory not found")
continue
copied: list[str] = []
for license_file in collect_license_files(formula_dir):
destination = target_dir / license_file.name
if destination.exists():
destination.chmod(0o644)
shutil.copy2(license_file, destination)
destination.chmod(0o644)
copied.append(license_file.name)
actual_version = formula_dir.name
if copied:
manifest_lines.append(
f"- {formula_name} ({actual_version}): {', '.join(sorted(copied))}"
)
else:
note = target_dir / "MISSING_LICENSE.txt"
note.write_text(
f"No license file matching common patterns was found in {formula_dir}\n"
)
manifest_lines.append(
f"- {formula_name} ({actual_version}): no matching license file found"
)
manifest_path = LICENSE_ROOT / "THIRD_PARTY_NOTICES.txt"
manifest_path.write_text("\n".join(manifest_lines) + "\n")
manifest_path.chmod(0o644)
bundle_manifest = LICENSE_BUNDLE_ROOT / "THIRD_PARTY_NOTICES.txt"
shutil.copy2(manifest_path, bundle_manifest)
bundle_manifest.chmod(0o644)
archive_base = LICENSE_BUNDLE_ROOT / "homebrew-licenses"
archive_path = shutil.make_archive(str(archive_base), "zip", LICENSE_ROOT)
Path(archive_path).chmod(0o644)
print(f"Prepared bundled licenses at: {LICENSE_ROOT}")
print(f"Prepared bundled license archive at: {archive_path}")
if __name__ == "__main__":
main()