39 lines
1.5 KiB
Text
39 lines
1.5 KiB
Text
|
|
#!/usr/bin/env nu
|
||
|
|
|
||
|
|
# Verify every blog post that ships a graph sidecar (.ncl) is present in the
|
||
|
|
# generated content graph (site/public/r/content_graph.json). A sidecar with no
|
||
|
|
# entry means `just graph` was never re-run after the post was added — the post
|
||
|
|
# would render without its mini-graph and ONTOLOGY CONTEXT relations.
|
||
|
|
#
|
||
|
|
# Read-only. Exits non-zero on any gap, so it works as a CI gate.
|
||
|
|
#
|
||
|
|
# Usage (from outreach/site):
|
||
|
|
# nu scripts/build/check-graph-coverage.nu .
|
||
|
|
|
||
|
|
def main [root: string = "."] {
|
||
|
|
let graph_path = ($root | path join "site/public/r/content_graph.json")
|
||
|
|
if not ($graph_path | path exists) {
|
||
|
|
error make { msg: $"content_graph.json not found at ($graph_path) — run `just graph`" }
|
||
|
|
}
|
||
|
|
|
||
|
|
let keys = (open $graph_path | get mini | columns)
|
||
|
|
let sidecars = (glob $"($root)/site/content/blog/**/*.ncl" | where { |p| ($p | path basename) != "_index.ncl" })
|
||
|
|
mut missing = 0
|
||
|
|
|
||
|
|
for s in $sidecars {
|
||
|
|
let id = (open --raw $s | parse --regex 'id\s*=\s*"(?<id>[^"]+)"' | get id.0?)
|
||
|
|
if ($id == null) {
|
||
|
|
print $" ($s | path basename): no id field"
|
||
|
|
$missing = ($missing + 1)
|
||
|
|
} else if ($id not-in $keys) {
|
||
|
|
print $" MISSING in content graph: ($id) \(($s | path basename)\)"
|
||
|
|
$missing = ($missing + 1)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if $missing > 0 {
|
||
|
|
error make { msg: $"graph-coverage: ($missing) post sidecar\(s\) absent from content_graph.json — run `just graph`" }
|
||
|
|
}
|
||
|
|
print $"graph-coverage: ($sidecars | length) sidecar\(s\) present in content graph"
|
||
|
|
}
|