mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-11 05:11:49 +01:00
64 lines
3.1 KiB
Python
64 lines
3.1 KiB
Python
#!/usr/bin/env python3
|
|
"""Read-only Git comparison for the native-ingestion delivery branches."""
|
|
import argparse
|
|
import hashlib
|
|
import json
|
|
import re
|
|
import subprocess
|
|
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--repo", required=True)
|
|
parser.add_argument("--frozen", required=True)
|
|
parser.add_argument("--delivery", required=True)
|
|
args = parser.parse_args()
|
|
for ref in [args.frozen, args.delivery]:
|
|
if not re.fullmatch(r"[a-f0-9]{40}", ref):
|
|
parser.error("Use immutable full commit IDs")
|
|
|
|
CI_BASE = "8ab89f41e499032e3e55d261f457a3463d754a1d"
|
|
SCRIPT_EXCEPTIONS = {"test:e2e:runner:typecheck", "test:lifecycle-baseline:typecheck"}
|
|
CI_ONLY_SERVER_FILES = {"server/scripts/typecheck-layers.mjs"}
|
|
|
|
def git(*parts):
|
|
return subprocess.check_output(["git", *parts], cwd=args.repo)
|
|
|
|
def is_runtime(path, expanded=False):
|
|
prefixes = ("server/" if expanded else "server/src/", "packages/", "ui/", "cli/", "skills/")
|
|
return (path.startswith(prefixes)
|
|
and not any(part in ("__tests__", "tests", "test") for part in path.split("/"))
|
|
and not path.endswith((".test.ts", ".test.tsx", ".test.js", ".test.mjs", ".spec.ts", ".spec.tsx", ".spec.js"))
|
|
and path not in CI_ONLY_SERVER_FILES)
|
|
|
|
def manifest(ref, expanded=False):
|
|
rows = []
|
|
for entry in git("ls-tree", "-r", "-z", ref).split(b"\0"):
|
|
if not entry:
|
|
continue
|
|
metadata, name = entry.split(b"\t", 1)
|
|
path = name.decode()
|
|
if is_runtime(path, expanded):
|
|
rows.append([path, *metadata.decode().split(" ")])
|
|
rows.sort()
|
|
package = json.loads(git("show", ref + ":package.json"))
|
|
content = {"files": rows,
|
|
"rootPackageNonScripts": {key: value for key, value in package.items() if key != "scripts"},
|
|
"rootScriptsExceptTwoTestTypechecks": {key: value for key, value in package["scripts"].items() if key not in SCRIPT_EXCEPTIONS}}
|
|
digest = hashlib.sha256(json.dumps(content, sort_keys=True, separators=(",", ":")).encode()).hexdigest()
|
|
return {"count": len(rows), "sha256": digest}
|
|
|
|
output = {"frozen": args.frozen, "delivery": args.delivery, "sourceMutation": False}
|
|
for name, expanded in [("approvedScope", False), ("expandedServerBuildInputs", True)]:
|
|
frozen, delivery = manifest(args.frozen, expanded), manifest(args.delivery, expanded)
|
|
assert frozen == delivery, (name, frozen, delivery)
|
|
output[name] = {"equal": True, "frozen": frozen, "delivery": delivery}
|
|
|
|
approved_package = json.loads(git("show", CI_BASE + ":package.json"))
|
|
delivery_package = json.loads(git("show", args.delivery + ":package.json"))
|
|
for key in SCRIPT_EXCEPTIONS:
|
|
assert delivery_package["scripts"][key] == approved_package["scripts"][key], key
|
|
for path in ["scripts/typecheck-low-memory.mjs", "scripts/typecheck-test-projects.mjs", *CI_ONLY_SERVER_FILES]:
|
|
assert git("show", args.delivery + ":" + path) == git("show", CI_BASE + ":" + path), path
|
|
output["realCiHelpersMatchApproved8ab"] = True
|
|
output["allChangedPaths"] = git("diff", "--name-only", args.frozen, args.delivery).decode().splitlines()
|
|
print(json.dumps(output, indent=2))
|