mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-04 10:48:20 +00:00
111 lines
6.2 KiB
Bash
111 lines
6.2 KiB
Bash
#!/usr/bin/env bash
|
|
# Exercise the real production Make rules with tiny C fixtures. CodeQL starts
|
|
# tracing after cbm-third-party, so every affected object must compile again,
|
|
# while unrelated objects must remain reused. No dry-run/timestamp assertions.
|
|
set -euo pipefail
|
|
ROOT="${1:-$(cd "$(dirname "$0")/.." && pwd)}"
|
|
python3 - "$ROOT" "$BASH" <<'PY'
|
|
import os
|
|
import pathlib
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
|
|
root, bash = pathlib.Path(sys.argv[1]), sys.argv[2]
|
|
failures = []
|
|
with tempfile.TemporaryDirectory(prefix="cbm-codeql-retrace-") as directory:
|
|
work = pathlib.Path(directory)
|
|
|
|
def write(path, text):
|
|
dest = work / path
|
|
dest.parent.mkdir(parents=True, exist_ok=True)
|
|
dest.write_text(text, encoding="utf-8")
|
|
|
|
for path in ("Makefile.cbm", "scripts/ci/codeql-retrace-vendored.sh",
|
|
"scripts/ci/select-lanes.sh", ".github/codeql/codeql-config.yml"):
|
|
write(path, (root / path).read_text(encoding="utf-8"))
|
|
|
|
# Nested and aliased includes deliberately escape the Makefile's shallow
|
|
# wildcard dependencies. The compiler really compiles these translation units.
|
|
write("vendored/mimalloc/src/static.c",
|
|
'#include "mimalloc/internal.h"\n#include "prim/osx/prim.c"\n')
|
|
write("vendored/mimalloc/include/mimalloc/internal.h", "#define MI_VALUE 7\n")
|
|
write("vendored/mimalloc/src/prim/osx/prim.c", '#include "../unix/prim.c"\n')
|
|
write("vendored/mimalloc/src/prim/unix/prim.c", "int mi_value(void) { return MI_VALUE; }\n")
|
|
write("internal/cbm/vendored/common/scanner.h", "#define SHARED_VALUE 3\n")
|
|
for language in ("go", "json"):
|
|
write(f"internal/cbm/grammar_{language}.c",
|
|
f'#include "vendored/grammars/{language}/parser.c"\n')
|
|
write(f"internal/cbm/vendored/grammars/{language}/parser.c",
|
|
'#include "nested/value.h"\n#include "../../common/scanner.h"\n'
|
|
f'int grammar_{language}(void) {{ return VALUE + SHARED_VALUE; }}\n')
|
|
write(f"internal/cbm/vendored/grammars/{language}/nested/value.h", "#define VALUE 2\n")
|
|
write("internal/cbm/vendored/grammars/shared/shared.h", "/* future shared grammar helper */\n")
|
|
write("internal/cbm/ts_runtime.c", '#include "vendored/ts_runtime/src/lib.c"\n')
|
|
write("internal/cbm/vendored/ts_runtime/src/lib.c", "int runtime_value(void) { return 1; }\n")
|
|
for path, symbol in (("vendored/sqlite3/sqlite3.c", "sqlite_value"),
|
|
("vendored/tre/tre_all.c", "tre_value"),
|
|
("internal/cbm/vendored/lz4/lz4.c", "lz4_value"),
|
|
("internal/cbm/vendored/lz4/lz4hc.c", "lz4hc_value"),
|
|
("internal/cbm/vendored/zstd/zstd.c", "zstd_value")):
|
|
write(path, f"int {symbol}(void) {{ return 1; }}\n")
|
|
write("internal/cbm/vendored/lz4/lz4.h", "/* shared LZ4 header */\n")
|
|
write("vendored/sqlite3/sqlite3.h", "/* sqlite header */\n")
|
|
write("internal/cbm/vendored/zstd/zstd.h", "/* zstd header */\n")
|
|
write("vendored/nomic/code_vectors_blob.S", ".text\n")
|
|
write("vendored/nomic/code_vectors.bin", "")
|
|
write("src/main.c", "int main(void) { return 0; }\n")
|
|
|
|
def run(args):
|
|
proc = subprocess.run(args, cwd=work, capture_output=True, text=True)
|
|
if proc.returncode:
|
|
raise RuntimeError(f"{args}: exit {proc.returncode}\n{proc.stdout}\n{proc.stderr}")
|
|
return proc.stdout
|
|
|
|
make = ["make", "--no-print-directory", "-f", "Makefile.cbm", "cbm-third-party",
|
|
"BUILD_DIR=build/c", "CC=" + os.environ.get("CC", "cc")]
|
|
|
|
def compiled(output):
|
|
return set(re.findall(r" -c -o build/c/([^\s]+\.o)(?:\s|$)", output))
|
|
|
|
prebuilt = compiled(run(make))
|
|
expected = {"prod_mimalloc.o", "prod_sqlite3.o", "prod_grammar_go.o",
|
|
"prod_grammar_json.o", "prod_ts_runtime.o", "prod_lz4.o",
|
|
"prod_lz4hc.o", "prod_zstd.o", "unixcoder_blob.o"}
|
|
# TRE is a Windows-only production object. All other objects are mandatory.
|
|
if prebuilt not in (expected, expected | {"prod_tre.o"}):
|
|
raise RuntimeError(f"incomplete prebuild: {sorted(prebuilt)}")
|
|
if compiled(run(make)):
|
|
raise RuntimeError("unchanged prebuild is not reused")
|
|
|
|
cases = [
|
|
("nested allocator header", ["vendored/mimalloc/include/mimalloc/internal.h"], {"prod_mimalloc.o"}),
|
|
("aliased allocator source", ["vendored/mimalloc/src/prim/unix/prim.c"], {"prod_mimalloc.o"}),
|
|
("nested grammar header", ["internal/cbm/vendored/grammars/go/nested/value.h"], {"prod_grammar_go.o"}),
|
|
("grammar wrapper", ["internal/cbm/grammar_go.c"], {"prod_grammar_go.o"}),
|
|
("runtime wrapper", ["internal/cbm/ts_runtime.c"], {"prod_ts_runtime.o"}),
|
|
("runtime source", ["internal/cbm/vendored/ts_runtime/src/lib.c"], {"prod_ts_runtime.o"}),
|
|
("shared grammar header", ["internal/cbm/vendored/common/scanner.h"], {"prod_grammar_go.o", "prod_grammar_json.o"}),
|
|
("unknown grammar family", ["internal/cbm/vendored/grammars/shared/shared.h"], {"prod_grammar_go.o", "prod_grammar_json.o"}),
|
|
("LZ4 header", ["internal/cbm/vendored/lz4/lz4.h"], {"prod_lz4.o", "prod_lz4hc.o"}),
|
|
("SQLite header", ["vendored/sqlite3/sqlite3.h"], {"prod_sqlite3.o"}),
|
|
("zstd header", ["internal/cbm/vendored/zstd/zstd.h"], {"prod_zstd.o"}),
|
|
("first-party only", ["src/main.c"], set()),
|
|
("duplicate changes", ["internal/cbm/grammar_go.c", "internal/cbm/grammar_go.c"], {"prod_grammar_go.o"}),
|
|
]
|
|
for label, paths, expected_objects in cases:
|
|
write("changed.txt", "\n".join(paths) + "\n")
|
|
run([bash, "scripts/ci/codeql-retrace-vendored.sh", "--changed", "changed.txt", "retrace.txt"])
|
|
retrace = (work / "retrace.txt").read_text(encoding="utf-8").splitlines()
|
|
actual = compiled(run(make + [arg for path in retrace for arg in ("-W", path)]))
|
|
if actual != expected_objects:
|
|
failures.append(f"{label}: expected {sorted(expected_objects)}, compiled {sorted(actual)}")
|
|
else:
|
|
print(f"PASS {label}: {len(actual)}/{len(prebuilt)} third-party objects retraced")
|
|
if failures:
|
|
print("CODEQL RETRACE CONTRACT VIOLATED:\n " + "\n ".join(failures))
|
|
sys.exit(1)
|
|
print("CodeQL retrace contract OK (real compiler + production Make rules)")
|
|
PY
|