test(install): #72 installer ↔ template SoT parity check
Guard that nomarchy-install share/template ships byte-identical flake.nix/system.nix/home.nix/theme-state.json to templates/downstream (the single machine-seed SoT; default.nix copy list). - tools/check-template-sot.py — share vs SoT file-set + content - checks.template-sot — pure python + package path (theme-contrast pattern) - BACKLOG #72 removed; JOURNAL entry Verified (V0): python3 tools/check-template-sot.py <share/template> templates/downstream nix build .#checks.x86_64-linux.template-sot
This commit is contained in:
13
flake.nix
13
flake.nix
@@ -294,6 +294,19 @@
|
|||||||
touch $out
|
touch $out
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
# Installer share ↔ templates/downstream SoT (item 72): the four
|
||||||
|
# files default.nix copies into share/.../template/ must stay
|
||||||
|
# byte-identical to the checkout template (single machine-seed
|
||||||
|
# SoT; no thinner second catalog). Cheap package build + cmp.
|
||||||
|
template-sot = pkgs.runCommand "nomarchy-template-sot"
|
||||||
|
{ nativeBuildInputs = [ pkgs.python3 ]; }
|
||||||
|
''
|
||||||
|
python3 ${./tools/check-template-sot.py} \
|
||||||
|
${nomarchyInstall}/share/nomarchy-install/template \
|
||||||
|
${./templates/downstream}
|
||||||
|
touch $out
|
||||||
|
'';
|
||||||
|
|
||||||
# The installer's disko arg contract (item 49): swapSize "0"/"0G"
|
# The installer's disko arg contract (item 49): swapSize "0"/"0G"
|
||||||
# (bare "0" is what the swap=0 install passes) must yield NO @swap
|
# (bare "0" is what the swap=0 install passes) must yield NO @swap
|
||||||
# subvolume, a sized value a correctly-sized one, and withLuks must
|
# subvolume, a sized value a correctly-sized one, and withLuks must
|
||||||
|
|||||||
96
tools/check-template-sot.py
Executable file
96
tools/check-template-sot.py
Executable file
@@ -0,0 +1,96 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Installer ↔ templates/downstream SoT parity (flake check `template-sot`).
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
check-template-sot.py <install-share-template> <templates/downstream>
|
||||||
|
|
||||||
|
Asserts the files nomarchy-install ships under
|
||||||
|
$out/share/nomarchy-install/template/ are byte-identical to the same
|
||||||
|
names in templates/downstream — the single source of truth for machine
|
||||||
|
flake seed files (see pkgs/nomarchy-install/default.nix installPhase).
|
||||||
|
|
||||||
|
The package copies a fixed file list (not a recursive tree copy):
|
||||||
|
|
||||||
|
flake.nix system.nix home.nix theme-state.json
|
||||||
|
|
||||||
|
README.md and hardware-configuration.nix stay repo-only (docs /
|
||||||
|
nixos-generate-config at install time) and are intentionally absent
|
||||||
|
from the share.
|
||||||
|
|
||||||
|
Wired as `checks.template-sot` in flake.nix; also runnable after a local
|
||||||
|
package build:
|
||||||
|
|
||||||
|
share=$(nix build --no-link --print-out-paths .#nomarchy-install)
|
||||||
|
python3 tools/check-template-sot.py \
|
||||||
|
"$share/share/nomarchy-install/template" templates/downstream
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
# Must match the cp list in pkgs/nomarchy-install/default.nix installPhase.
|
||||||
|
SHIPPED = ("flake.nix", "system.nix", "home.nix", "theme-state.json")
|
||||||
|
|
||||||
|
|
||||||
|
def fail(msg: str) -> None:
|
||||||
|
print(f"template-sot: {msg}", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
if len(sys.argv) != 3:
|
||||||
|
print(
|
||||||
|
f"usage: {sys.argv[0]} <install-share-template> <templates/downstream>",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
return 2
|
||||||
|
|
||||||
|
share = Path(sys.argv[1])
|
||||||
|
sot = Path(sys.argv[2])
|
||||||
|
|
||||||
|
if not share.is_dir():
|
||||||
|
fail(f"install share template dir missing: {share}")
|
||||||
|
if not sot.is_dir():
|
||||||
|
fail(f"templates/downstream dir missing: {sot}")
|
||||||
|
|
||||||
|
share_names = sorted(p.name for p in share.iterdir() if p.is_file())
|
||||||
|
expected = sorted(SHIPPED)
|
||||||
|
|
||||||
|
if share_names != expected:
|
||||||
|
fail(
|
||||||
|
"install share template file set drifted from default.nix copy list:\n"
|
||||||
|
f" share: {share_names}\n"
|
||||||
|
f" expected: {expected}\n"
|
||||||
|
" (update SHIPPED here and the cp in pkgs/nomarchy-install/default.nix together)"
|
||||||
|
)
|
||||||
|
|
||||||
|
mismatches = []
|
||||||
|
for name in SHIPPED:
|
||||||
|
src = sot / name
|
||||||
|
dst = share / name
|
||||||
|
if not src.is_file():
|
||||||
|
fail(f"SoT missing shipped file: {src}")
|
||||||
|
a = src.read_bytes()
|
||||||
|
b = dst.read_bytes()
|
||||||
|
if a != b:
|
||||||
|
mismatches.append(
|
||||||
|
f"{name}: share ({len(b)} bytes) != SoT ({len(a)} bytes)"
|
||||||
|
)
|
||||||
|
|
||||||
|
if mismatches:
|
||||||
|
print("template-sot: content mismatch(es):", file=sys.stderr)
|
||||||
|
for m in mismatches:
|
||||||
|
print(f" {m}", file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"template-sot: {len(SHIPPED)} files match "
|
||||||
|
f"{sot} ↔ {share}"
|
||||||
|
)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
Reference in New Issue
Block a user