Pin b594d743, typecheck the checkout, and keep the corpus and assets out of this repo. Leave screenshots and the production build open. Assistant: grok Assistant-Session: 01a130f1-abfb-7d71-9cd6-a8b75ec7f95a
129 lines
4.5 KiB
Python
129 lines
4.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Read-only inventory of a local OnCo checkout. Writes nothing into the checkout.
|
|
|
|
The checkout stays gitignored. This script counts files and import edges so the
|
|
baseline report can be committed without copying upstream source or corpus text.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
from collections import Counter
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parent.parent
|
|
UPSTREAM = Path(sys.argv[1] if len(sys.argv) > 1 else ROOT / "upstream-onco")
|
|
|
|
CODE_DIRS = ("src/components", "src/lib", "src/app", "scripts", "packages", "mcp")
|
|
NAME_TOKENS = re.compile(
|
|
r"cancer|oncolog|drug|target|trial|biomarker|tumou?r|adc|payload",
|
|
re.I,
|
|
)
|
|
IMPORT_RE = re.compile(
|
|
r"""^import\s+(?:type\s+)?(?:[\w*\s{},]+\s+from\s+)?["']([^"']+)["']""",
|
|
re.M,
|
|
)
|
|
KIND_LITERAL = re.compile(r"""kind\s*===?\s*["']([a-z0-9-]+)["']""")
|
|
|
|
|
|
def git(*args: str) -> str:
|
|
proc = subprocess.run(
|
|
["git", "-C", str(UPSTREAM), *args],
|
|
capture_output=True,
|
|
text=True,
|
|
check=False,
|
|
)
|
|
return proc.stdout.strip() if proc.returncode == 0 else ""
|
|
|
|
|
|
def rel_files(folder: str) -> list[Path]:
|
|
base = UPSTREAM / folder
|
|
if not base.is_dir():
|
|
return []
|
|
return [p for p in base.rglob("*") if p.is_file()]
|
|
|
|
|
|
def imports_of(path: Path) -> list[str]:
|
|
try:
|
|
text = path.read_text(encoding="utf-8", errors="replace")
|
|
except OSError:
|
|
return []
|
|
return IMPORT_RE.findall(text)
|
|
|
|
|
|
def main() -> int:
|
|
if not (UPSTREAM / ".git").is_dir():
|
|
print(f"missing checkout: {UPSTREAM}", file=sys.stderr)
|
|
return 1
|
|
sha = git("rev-parse", "HEAD")
|
|
subject = git("log", "-1", "--format=%ci %s")
|
|
print(f"pin {sha}")
|
|
print(f"commit {subject}")
|
|
print(f"license_exists { (UPSTREAM / 'LICENSE').is_file() }")
|
|
print(f"license_data_exists { (UPSTREAM / 'LICENSE-DATA').is_file() }")
|
|
print(f"notice_exists { (UPSTREAM / 'NOTICE').is_file() }")
|
|
|
|
for folder in ("src", "src/data", "src/components", "src/lib", "src/app", "public", "scripts"):
|
|
files = rel_files(folder) if folder != "src" else [
|
|
p for p in (UPSTREAM / "src").rglob("*") if p.is_file()
|
|
]
|
|
code = [p for p in files if p.suffix in {".ts", ".tsx", ".js", ".mjs"}]
|
|
print(f"count {folder} files={len(files)} code={len(code)}")
|
|
|
|
named = []
|
|
for folder in ("src/components", "src/lib", "src/app"):
|
|
for path in rel_files(folder):
|
|
if path.suffix not in {".ts", ".tsx"}:
|
|
continue
|
|
if NAME_TOKENS.search(path.name):
|
|
named.append(str(path.relative_to(UPSTREAM)))
|
|
print(f"oncology_named_code {len(named)}")
|
|
for item in sorted(named)[:40]:
|
|
print(f" named {item}")
|
|
if len(named) > 40:
|
|
print(f" named … {len(named) - 40} more")
|
|
|
|
focus = [
|
|
"src/components/EntityBrowser.tsx",
|
|
"src/components/EntityDetail.tsx",
|
|
"src/lib/graph.ts",
|
|
"src/lib/schema.ts",
|
|
"src/lib/kinds.ts",
|
|
"src/app/[kind]/page.tsx",
|
|
"src/lib/nav.ts",
|
|
"src/lib/tables/kinds.ts",
|
|
]
|
|
for rel in focus:
|
|
path = UPSTREAM / rel
|
|
print(f"focus {rel} exists={path.is_file()} bytes={path.stat().st_size if path.is_file() else 0}")
|
|
if not path.is_file():
|
|
continue
|
|
imps = imports_of(path)
|
|
local = [i for i in imps if i.startswith(".") or i.startswith("@/")]
|
|
print(f" imports {len(imps)} local={len(local)}")
|
|
for item in local:
|
|
print(f" {item}")
|
|
text = path.read_text(encoding="utf-8", errors="replace")
|
|
kinds = Counter(KIND_LITERAL.findall(text))
|
|
if kinds:
|
|
print(" kind_branches " + ", ".join(f"{k}:{v}" for k, v in kinds.most_common(12)))
|
|
|
|
# Kind enum from schema if present.
|
|
schema = UPSTREAM / "src/lib/schema.ts"
|
|
if schema.is_file():
|
|
text = schema.read_text(encoding="utf-8", errors="replace")
|
|
kinds_block = re.search(r"KINDS\s*=\s*\[(.*?)\]\s*as\s+const", text, re.S)
|
|
if kinds_block:
|
|
kinds = re.findall(r"""["']([a-z0-9-]+)["']""", kinds_block.group(1))
|
|
print(f"kinds {len(kinds)} " + " ".join(kinds))
|
|
rels = re.search(r"REL_FIELDS\s*=\s*\[(.*?)\]\s*as\s+const", text, re.S)
|
|
if rels:
|
|
fields = re.findall(r"""["']([A-Za-z0-9_]+)["']""", rels.group(1))
|
|
print(f"rel_fields {len(fields)} " + " ".join(fields[:40]))
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|