93 lines
2.8 KiB
Python
93 lines
2.8 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
import argparse
|
|
import base64
|
|
import re
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
|
|
def sh(args, cwd=None):
|
|
proc = subprocess.run(
|
|
args, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
|
|
)
|
|
if proc.returncode != 0:
|
|
err = proc.stderr.strip() or proc.stdout.strip()
|
|
cmd = " ".join(args)
|
|
raise SystemExit(f"command failed: {cmd}\n{err}")
|
|
return proc.stdout.strip()
|
|
|
|
|
|
def default_clone_dir(repo_url, base_dir):
|
|
name = repo_url.rstrip("/").split("/")[-1]
|
|
if name.endswith(".git"):
|
|
name = name[:-4]
|
|
return base_dir / (name or "repo")
|
|
|
|
|
|
def commit_candidates(repo_dir):
|
|
patterns = ("vendor-note", "OH-21B4")
|
|
for pattern in patterns:
|
|
out = sh(["git", "log", "-S", pattern, "--all", "--pretty=%H"], cwd=repo_dir)
|
|
commits = [line.strip() for line in out.splitlines() if line.strip()]
|
|
if commits:
|
|
return commits
|
|
return []
|
|
|
|
|
|
def find_vendor_note(repo_dir):
|
|
for commit in commit_candidates(repo_dir):
|
|
try:
|
|
src = sh(["git", "show", f"{commit}:router/server.js"], cwd=repo_dir)
|
|
except subprocess.CalledProcessError:
|
|
continue
|
|
match = re.search(r"vendor-note:\s*([A-Za-z0-9+/=]+)", src)
|
|
if not match:
|
|
continue
|
|
b64_note = match.group(1)
|
|
flag = base64.b64decode(b64_note).decode("utf-8", "replace")
|
|
return commit, b64_note, flag
|
|
raise SystemExit("vendor-note not found in history")
|
|
|
|
|
|
def dump_sources(repo_dir, commit):
|
|
paths = [
|
|
"router/server.js",
|
|
"router/config/router.json",
|
|
"printer/server.js",
|
|
"kettle/server.js",
|
|
"nas/server.js",
|
|
]
|
|
for rel in paths:
|
|
content = sh(["git", "show", f"{commit}:{rel}"], cwd=repo_dir)
|
|
print(f"\n--- {rel} @ {commit} ---")
|
|
print(content.rstrip("\n"))
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("repo", help="Git URL or local path")
|
|
parser.add_argument("--dest", default=None, help="Clone directory (default: <script_dir>/<repo>)")
|
|
args = parser.parse_args()
|
|
|
|
base_dir = Path(__file__).resolve().parent
|
|
clone_dir = Path(args.dest).resolve() if args.dest else default_clone_dir(args.repo, base_dir)
|
|
|
|
if clone_dir.exists():
|
|
print(f"[i] using existing repo: {clone_dir}")
|
|
else:
|
|
print(f"[i] cloning into: {clone_dir}")
|
|
sh(["git", "clone", args.repo, str(clone_dir)])
|
|
sh(["git", "fetch", "--all", "--prune"], cwd=clone_dir)
|
|
|
|
commit, b64_note, flag = find_vendor_note(clone_dir)
|
|
print(f"[ok] clone_dir: {clone_dir}")
|
|
print(f"[ok] commit: {commit}")
|
|
print(f"[ok] vendor_note_b64: {b64_note}")
|
|
print(f"[ok] flag: {flag}")
|
|
dump_sources(clone_dir, commit)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|