All checks were successful
Check / eval (push) Successful in 3m6s
Four new no-VM checks.* + CI py_compile expansion:
- hardware-db-modules: installer DB module names ∈ pinned
nixos-hardware.nixosModules (a lock bump can rename a module and break
profiled installs on just the matching DMI, invisible to any VM).
- installer-compose-lock: offline lock-composer contract on fixtures.
- installer-disko: pure Nix assert — swapSize "0"/"0G" → no @swap, "2G"
→ sized, withLuks wraps root (permanently guards the #46 install fix).
- windowrule-syntax: builds the generated hyprland.conf and fails on the
pre-0.53 grammar / windowrulev2 keyword (guards ed7fd93).
CI py_compile now covers all tracked *.py; docs/TESTING.md §1 synced.
Implemented by a worktree agent; diff reviewed. Verified V0 (flake check)
+ V1 (each checks.x86_64-linux.* built on main, exit 0); agent's negative
tests confirm each guard fails on a regression.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
54 lines
2.2 KiB
Python
Executable File
54 lines
2.2 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Installer hardware-DB ↔ nixos-hardware drift check (flake check
|
|
`hardware-db-modules`).
|
|
|
|
Usage: check-hardware-db.py <hardware-db.sh> <nixos-hardware-modules.txt>
|
|
|
|
Every nixos-hardware module name the installer references — the third
|
|
`|`-field of each HARDWARE_DB table row, plus the literal `common-*`
|
|
modules the CPU/GPU/chassis autodetect emits — must exist in the pinned
|
|
`nixos-hardware.nixosModules`. A lock bump can rename a module upstream
|
|
(the X1 Carbon → `x1-Nth-gen` churn is the canonical example) and silently
|
|
break profiled installs on exactly the machines whose DMI matches — a
|
|
class of bug that never shows up in a VM. `nixos-hardware-modules.txt` is
|
|
generated at eval time in flake.nix from `attrNames
|
|
nixos-hardware.nixosModules`, so the "what actually exists" side can't go
|
|
stale by itself.
|
|
"""
|
|
|
|
import re
|
|
import sys
|
|
|
|
db_file, modules_file = sys.argv[1], sys.argv[2]
|
|
|
|
available = {l.strip() for l in open(modules_file) if l.strip()}
|
|
db = open(db_file).read()
|
|
|
|
referenced = {} # module name -> short reason (first seen)
|
|
|
|
# HARDWARE_DB rows: "sys_vendor_regex | product_regex | module". The first
|
|
# two fields are bash regexes (may contain anything but a literal quote);
|
|
# the module name is a plain nixos-hardware attr (lower-case, dashes).
|
|
for vendor, product, module in re.findall(
|
|
r'"([^"|]*)\|([^"|]*)\|([a-z0-9][a-z0-9-]*)"', db
|
|
):
|
|
referenced.setdefault(module, f"HARDWARE_DB row ({vendor.strip()} {product.strip()})")
|
|
|
|
# Literal `common-*` (and any other bare-literal) modules emitted by the
|
|
# autodetect via `echo "MODULE <name>"`. The `$mod` variable form is the
|
|
# HARDWARE_DB table above and is skipped here.
|
|
for module in re.findall(r'echo "MODULE ([a-z0-9][a-z0-9-]*)"', db):
|
|
referenced.setdefault(module, "autodetect MODULE line")
|
|
|
|
if not referenced:
|
|
sys.exit("hardware-db: parsed no module references — parser or file changed")
|
|
|
|
missing = sorted(m for m in referenced if m not in available)
|
|
if missing:
|
|
print(f"hardware-db: {len(missing)} module(s) not in nixos-hardware.nixosModules")
|
|
for m in missing:
|
|
print(f" {m} — referenced by {referenced[m]}")
|
|
sys.exit(1)
|
|
|
|
print(f"hardware-db: all {len(referenced)} referenced modules exist in nixos-hardware")
|