Hand-authored and promoted notes skip pipeline.BuildPages, so nothing quotes their scalars. A title carrying an unescaped ": " yields a block yaml.Unmarshal rejects, and every consumer that reads frontmatter drops the note silently — 18 files repo-wide today, up from the 8 in #90. frontmatter.Lint reports it; frontmatter.Fix quotes only what quoting can rescue and refuses to return a document that still fails to parse, so an unfixable file comes back byte-identical rather than half-repaired. Scan walks a tree and reports an unreadable file as a finding instead of aborting, so one poisoned note cannot hide the rest. Sequence items are deliberately left alone: "- foo: bar" is valid YAML that silently becomes a map, which is a type corruption rather than a parse failure, and repairing it would rewrite notes that currently load. task lint:frontmatter # report task lint:frontmatter FIX=1 # repair in place Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BeAp5LTscnz2W7Ubt4eJ6m
54 lines
1.3 KiB
Go
54 lines
1.3 KiB
Go
// Command frontmatterlint reports markdown notes whose YAML frontmatter does
|
|
// not parse, and optionally repairs the ones that only need quoting.
|
|
//
|
|
// go run ./cmd/frontmatterlint ../../brain # report
|
|
// go run ./cmd/frontmatterlint -fix ../../brain # repair in place
|
|
//
|
|
// Exit codes: 0 clean (or everything repaired), 1 findings remain, 2 the scan
|
|
// itself failed.
|
|
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/mathiasbq/hyperguild/ingestion/internal/frontmatter"
|
|
)
|
|
|
|
func main() {
|
|
fix := flag.Bool("fix", false, "repair files that quoting can rescue, in place")
|
|
flag.Parse()
|
|
|
|
root := "."
|
|
if flag.NArg() > 0 {
|
|
root = flag.Arg(0)
|
|
}
|
|
|
|
findings, err := frontmatter.Scan(root, *fix)
|
|
if err != nil {
|
|
fmt.Fprintln(os.Stderr, "frontmatterlint:", err)
|
|
os.Exit(2)
|
|
}
|
|
|
|
var unresolved int
|
|
for _, f := range findings {
|
|
if f.Repaired {
|
|
fmt.Printf("repaired %s\n", f.Path)
|
|
continue
|
|
}
|
|
unresolved++
|
|
fmt.Printf("BROKEN %s: %v\n", f.Path, f.Err)
|
|
}
|
|
|
|
if unresolved > 0 {
|
|
fmt.Fprintf(os.Stderr, "\n%d file(s) with unparseable frontmatter", unresolved)
|
|
if !*fix {
|
|
fmt.Fprint(os.Stderr, " — re-run with -fix")
|
|
}
|
|
fmt.Fprintln(os.Stderr)
|
|
os.Exit(1)
|
|
}
|
|
fmt.Printf("✓ frontmatter: %d file(s) repaired, none broken\n", len(findings))
|
|
}
|