#!/usr/bin/env python3 """Compile Pop media-pull related classes and jar-uf into a deployable fat jar.""" from __future__ import annotations import shutil import subprocess import tempfile import zipfile from pathlib import Path ROOT = Path(r"F:\0000wyrs\Aliyun") JAR = ROOT / "target" / "remote-control-1.0.0.jar" OUT_JAR = ROOT / "target" / "remote-control-1.0.0.media-pull.jar" JAVA_HOME = Path(r"C:\Program Files\Eclipse Adoptium\jdk-17.0.20.8-hotspot") JAVAC = JAVA_HOME / "bin" / "javac.exe" JAR_BIN = JAVA_HOME / "bin" / "jar.exe" LOMBOK = ROOT / "scripts" / "lib" / "lombok-1.18.34.jar" SRC_FILES = [ "com/wyrs/pop/config/PopProperties.java", "com/wyrs/pop/entity/PopUserMedia.java", "com/wyrs/pop/repository/PopUserMediaRepository.java", "com/wyrs/pop/dto/PopMediaPullDtos.java", "com/wyrs/pop/dto/PopSyncDtos.java", "com/wyrs/pop/store/PopMediaPullFileStore.java", "com/wyrs/pop/service/PopMediaPullService.java", "com/wyrs/pop/service/PopSyncService.java", "com/wyrs/pop/controller/PopAdminMediaPullController.java", "com/wyrs/pop/controller/PopClientMediaPullController.java", "com/wyrs/pop/controller/PopClientOpsController.java", "com/wyrs/pop/controller/PopClientSyncController.java", "com/wyrs/pop/controller/PopAdminController.java", ] def main() -> None: if not JAR.is_file(): raise SystemExit(f"missing base jar {JAR}") if not JAVAC.is_file(): raise SystemExit(f"missing javac {JAVAC}") if not LOMBOK.is_file(): raise SystemExit(f"missing lombok {LOMBOK}") work = Path(tempfile.mkdtemp(prefix="wyrs-media-pull-")) try: extract = work / "extract" classes_out = work / "classes" extract.mkdir() classes_out.mkdir() print("extracting classpath from fat jar...") with zipfile.ZipFile(JAR, "r") as z: for name in z.namelist(): if name.startswith("BOOT-INF/lib/") or name.startswith("BOOT-INF/classes/"): z.extract(name, extract) cp_parts = [str(extract / "BOOT-INF" / "classes"), str(LOMBOK)] lib = extract / "BOOT-INF" / "lib" for j in sorted(lib.glob("*.jar")): cp_parts.append(str(j)) cp = ";".join(cp_parts) src_root = ROOT / "src" / "main" / "java" src_args = [] for rel in SRC_FILES: p = src_root / rel if not p.is_file(): raise SystemExit(f"missing source {p}") src_args.append(str(p)) cmd = [ str(JAVAC), "-encoding", "UTF-8", "-parameters", "-cp", cp, f"-processorpath", str(LOMBOK), "-d", str(classes_out), *src_args, ] print("javac", len(src_args), "files ...") p = subprocess.run(cmd, capture_output=True) log = ROOT / "logs" log.mkdir(parents=True, exist_ok=True) (log / "javac_media_pull_err.txt").write_bytes(p.stderr or b"") (log / "javac_media_pull_out.txt").write_bytes(p.stdout or b"") if p.returncode != 0: print((p.stderr or b"").decode("utf-8", "replace")[:4000]) raise SystemExit(f"javac failed code={p.returncode}") # Collect produced class files under packages we care about produced = list(classes_out.rglob("*.class")) if not produced: raise SystemExit("no class files produced") print(f"produced {len(produced)} class files") # markers markers = [b"contactsConsented", b"pullContacts", b"pullDocuments", b"hasContactsConsent"] blob = b"".join(f.read_bytes() for f in produced) for m in markers: print(f"marker {m!r}:", m in blob) shutil.copy2(JAR, OUT_JAR) update_root = work / "update" for f in produced: rel = f.relative_to(classes_out).as_posix() dest = update_root / "BOOT-INF" / "classes" / rel dest.parent.mkdir(parents=True, exist_ok=True) shutil.copy2(f, dest) # jar uf from update_root entries = [ "BOOT-INF/classes/" + f.relative_to(classes_out).as_posix() for f in produced ] print("jar uf", len(entries), "entries ...") p2 = subprocess.run( [str(JAR_BIN), "uf", str(OUT_JAR), *entries], cwd=str(update_root), capture_output=True, text=True, encoding="utf-8", errors="replace", ) if p2.returncode != 0: print(p2.stdout) print(p2.stderr) raise SystemExit(f"jar uf failed: {p2.returncode}") with zipfile.ZipFile(OUT_JAR, "r") as z: sample = z.read( "BOOT-INF/classes/com/wyrs/pop/service/PopMediaPullService.class" ) if b"hasContactsConsent" not in sample and b"contactsConsented" not in sample: raise SystemExit("patched jar missing consent markers") print(f"OK {OUT_JAR} ({OUT_JAR.stat().st_size} bytes)") finally: shutil.rmtree(work, ignore_errors=True) if __name__ == "__main__": main()