Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 28 additions & 14 deletions scripts/research_baseline_sparse.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""Name the selected inputs a sparse checkout omits before research_baseline.py.
"""Name the selected inputs a sparse checkout omits before its baseline report.

In a sparse checkout, ``scripts/research_baseline.py`` stops at the first absent
In a sparse checkout, the selected baseline stops at the first absent
selected input with ``Invalid selected file: ...`` and does not say which
directories it needs. This read-only preflight lists every input that check
reads and prints the ``git sparse-checkout add`` command that materializes them.
Expand All @@ -10,7 +10,10 @@
contract (``choose_research_task.check_catalog_files``): a stage-zero regular
skip-worktree entry whose blob matches HEAD. An ordinary deletion, staged drift
or unknown path raises the same ``Invalid selected file`` error. Byte drift in
present files is left to ``research_baseline.py``. Nothing is verified here.
present files is left to the baseline. Nothing is verified here.

The certificate schema selects ``scripts/research_selected_baseline.py`` for
productive-helper claims; historical certificates keep ``research_baseline.py``.

This is a separate script so that the baseline and its tests, which research
packages pin as live inputs, keep their bytes.
Expand All @@ -27,24 +30,30 @@
import sys

from choose_research_task import check_catalog_files
from research_selected_baseline import SCHEMA as PRODUCTIVE_SCHEMA

ROOT = Path(__file__).resolve().parents[1]
SELECTED = "certificates/selected-result.json"


def selected_json(name, root):
"""Read present metadata, or its HEAD blob after validating a sparse omission."""
check_catalog_files(root, [(name, "Invalid selected file: " + name)])
path = root / name
if path.is_file():
raw = path.read_bytes()
else: # a sparse omission whose index blob matches HEAD (checked above)
raw = subprocess.run(["git", "cat-file", "blob", "HEAD:" + name],
cwd=root, check=True, capture_output=True).stdout
return json.loads(raw)


def selected_inputs(record, root=ROOT):
"""Repository paths the selected-record check reads, before it reads them."""
names = [record["certificate"], record["source_manifest"], record["proof"],
record["review"], record["validation"], *record["proof_supplements"]]
check_catalog_files(root, [(names[1], "Invalid selected file: " + names[1])])
manifest = root / record["source_manifest"]
if manifest.is_file():
raw = manifest.read_bytes()
else: # a sparse omission whose index blob matches HEAD (checked above)
raw = subprocess.run(["git", "cat-file", "blob", "HEAD:" + record["source_manifest"]],
cwd=root, check=True, capture_output=True).stdout
inventory = json.loads(raw)
if inventory.get("format") == "repository-packages-sha256-v1":
inventory = selected_json(record["source_manifest"], root)
if inventory.get("format") in {"repository-packages-sha256-v1", "repository-files-sha256-v1"}:
names += inventory["files"]
else:
parent = Path(record["source_manifest"]).parent
Expand Down Expand Up @@ -72,18 +81,23 @@ def materialize_command(omitted):

def report(record, root=ROOT):
omitted = sparse_omissions(record, root)
certificate = selected_json(record["certificate"], root)
baseline = ("scripts/research_selected_baseline.py" if certificate.get("schema") == PRODUCTIVE_SCHEMA
else "scripts/research_baseline.py")
next_command = ["python3", "-B", baseline]
if not omitted:
return 0, {
"status": "NO_SPARSE_SELECTED_OMISSIONS",
"next": ["python3", "-B", "scripts/research_baseline.py"],
"next": next_command,
"scope": "Every selected input is present. Nothing was verified; run the baseline next.",
}
return 2, {
"status": "SPARSE_SELECTED_INPUTS_ABSENT",
"omitted_files": len(omitted), "first_omitted": omitted[:5],
"materialize": materialize_command(omitted),
"next": next_command,
"scope": "This sparse checkout omits selected inputs (skip-worktree entries matching HEAD). "
"Run the materialize command, then scripts/research_baseline.py; nothing was verified.",
"Run the materialize command, then " + baseline + "; nothing was verified.",
}


Expand Down
51 changes: 51 additions & 0 deletions tests/test_research_baseline_sparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,61 @@ def run_main(self):
code = sparse.main(["--root", str(self.root)])
return code, json.loads(out.getvalue())

def productive_certificate(self):
(self.root / self.record["certificate"]).write_text(json.dumps({
"schema": "proposed-conditional-integer-multiplication-claim/1",
}), encoding="utf-8")

def explicit_manifest(self):
self.record = {**RECORD, "source_manifest": "certificates/source.json"}
(self.root / sparse.SELECTED).write_text(json.dumps(self.record), encoding="utf-8")
(self.root / "LICENSE").write_text("fixture license\n", encoding="utf-8")
(self.root / self.record["source_manifest"]).write_text(json.dumps({
"format": "repository-files-sha256-v1",
"files": {"LICENSE": "0", "research/pkg-a/data/x.json": "0"},
}), encoding="utf-8")
self.productive_certificate()
self.git("add", ".")
self.commit("explicit repository inventory")

def test_full_checkout_reports_nothing(self):
self.assertEqual(sparse.sparse_omissions(self.record, self.root), [])
code, result = self.run_main()
self.assertEqual((code, result["status"]), (0, "NO_SPARSE_SELECTED_OMISSIONS"))
self.assertEqual(result["next"], ["python3", "-B", "scripts/research_baseline.py"])

def test_full_explicit_inventory_keeps_repository_relative_paths(self):
self.explicit_manifest()
code, result = self.run_main()
self.assertEqual((code, result["status"]), (0, "NO_SPARSE_SELECTED_OMISSIONS"))
self.assertEqual(result["next"], ["python3", "-B", "scripts/research_selected_baseline.py"])

def test_sparse_explicit_inventory_and_certificate_read_from_head(self):
self.explicit_manifest()
self.git("sparse-checkout", "set", "--no-cone", "/*", "!/*/", "/scripts/", "/docs/",
"/certificates/selected-result.json")
self.assertFalse((self.root / self.record["source_manifest"]).exists())
self.assertFalse((self.root / self.record["certificate"]).exists())
self.assertTrue((self.root / "LICENSE").is_file())
omitted = sparse.sparse_omissions(self.record, self.root)
self.assertEqual(omitted, ["certificates/source.json", "research/audit/ASSEMBLY.json",
"research/pkg-a/PROOF.md", "research/pkg-a/data/x.json",
"research/pkg-b/NOTE.md"])
code, result = self.run_main()
self.assertEqual((code, result["status"], result["omitted_files"]),
(2, "SPARSE_SELECTED_INPUTS_ABSENT", 5))
self.assertEqual(result["next"], ["python3", "-B", "scripts/research_selected_baseline.py"])
self.git(*result["materialize"][1:])
self.assertEqual(sparse.sparse_omissions(self.record, self.root), [])
self.assertEqual(self.run_main()[0], 0)

def test_productive_schema_routes_package_inventory_to_selected_baseline(self):
self.productive_certificate()
self.commit("productive certificate", "-a")
self.git("sparse-checkout", "set", "--cone", "scripts", "docs", "certificates")
code, result = self.run_main()
self.assertEqual(code, 2)
self.assertEqual(result["next"], ["python3", "-B", "scripts/research_selected_baseline.py"])

def test_cone_sparse_names_packages_and_reads_manifest_from_head(self):
self.git("sparse-checkout", "set", "--cone", "scripts", "docs", "certificates")
Expand Down