ontoref/install/check-config-sync.nu
Jesús Pérez d59644b96f
feat: unified auth model, project onboarding, install pipeline, config management
The full scope across this batch: POST /sessions key→token exchange, SessionStore dual-index with revoke_by_id, CLI Bearer injection (ONTOREF_TOKEN), ontoref setup
  --gen-keys, install scripts, daemon config form roundtrip, ADR-004/005, on+re self-description update (fully-self-described), and landing page refresh.
2026-03-13 20:56:31 +00:00

94 lines
4.1 KiB
Plaintext

#!/usr/bin/env nu
# Validate that reflection/forms/config.ncl and reflection/forms/config.ncl.j2
# are in sync: every form field with a nickel_path must have a {{ name }} reference
# in the template, and every {{ var }} in the template must map to a known form field.
#
# Run: nu install/check-config-sync.nu
# CI: just ci-check-config-sync
let form_path = "reflection/forms/config.ncl"
let template_path = "reflection/forms/config.ncl.j2"
# ── Extract field names that have nickel_path ─────────────────────────────────
# Strategy: scan the form for blocks containing both `name = "..."` and `nickel_path`.
# We do a two-pass: first collect all (line_number, name) pairs, then check which
# have a nickel_path within the same element block (lines up to the next `}`).
let form_lines = open --raw $form_path | lines | enumerate
# Collect all element start positions and their names
let elements = $form_lines | reduce --fold [] {|row, acc|
let line = $row.item
if ($line | str contains "name = \"") {
let name = try {
$line | parse --regex 'name\s*=\s*"(?P<n>[^"]+)"' | get n | first
} catch { "" }
if ($name | is-not-empty) {
$acc | append { idx: $row.index, name: $name }
} else {
$acc
}
} else {
$acc
}
}
# For each element, check if its block (from its line until the next element or EOF)
# contains a nickel_path. Collect names that have nickel_path.
let form_text = open --raw $form_path
let ncl_path_fields = $elements | reduce --fold [] {|el, acc|
# Find the substring from this element's line forward to end, check for nickel_path
# before the next `name =` (other than within nested structures)
let after = $form_lines
| skip $el.idx
| take while {|r| not ($r.item | str contains "name = \"") or $r.index == $el.idx }
| get item
| str join "\n"
if ($after | str contains "nickel_path") {
$acc | append $el.name
} else {
$acc
}
}
# ── Extract {{ var }} references from template ────────────────────────────────
let template_vars = open --raw $template_path
| parse --regex '\{\{\s*(?P<var>[a-zA-Z_][a-zA-Z0-9_]*)\s*[\|}\s]'
| get var
| uniq
| where {|v| $v != "if" and $v != "else" and $v != "endif" and $v != "for" and $v != "endfor"}
# ── Cross-check ───────────────────────────────────────────────────────────────
mut errors = []
# 1. Every nickel_path field must appear in template
for field in $ncl_path_fields {
if not ($template_vars | any {|v| $v == $field}) {
$errors = ($errors | append $"MISSING in template: form field '($field)' has nickel_path but no \{\{ ($field) \}\} in config.ncl.j2")
}
}
# 2. Every template var must exist as a form field name (excluding Tera filters/functions)
let all_form_names = $elements | get name
let tera_builtins = ["json", "trim", "split", "map", "attribute", "pat"]
for var in $template_vars {
if not ($all_form_names | any {|n| $n == $var}) and not ($tera_builtins | any {|b| $b == $var}) {
$errors = ($errors | append $"ORPHAN in template: \{\{ ($var) \}\} has no matching form field in config.ncl")
}
}
# ── Report ────────────────────────────────────────────────────────────────────
if ($errors | is-empty) {
print $"(ansi green)✓ config form/template in sync(ansi reset) ($ncl_path_fields | length) fields, ($template_vars | length) template vars"
} else {
print $"(ansi red)✗ config form/template DRIFT DETECTED(ansi reset)"
for e in $errors {
print $" (ansi yellow)→(ansi reset) ($e)"
}
print ""
print "Fix: update reflection/forms/config.ncl AND reflection/forms/config.ncl.j2 together."
exit 1
}