feat: add docs checker and record templates
docs new creates ADRs and plans from embedded templates; docs check reports path:line: message problems per docs/docs-format.md. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b0428256bd
commit
750b7449b0
15 files changed
+1856
No files matched your search
@@ -0,0 +1,45 @@
|
||||
package docs
|
||||
|
||||
import "time"
|
||||
|
||||
var (
|
||||
adrStatuses = []string{"proposed", "accepted", "rejected", "deprecated", "superseded"}
|
||||
adrImpls = []string{"not-started", "in-progress", "implemented", "deferred", "not-applicable"}
|
||||
adrRefs = []refSpec{
|
||||
{"supersedes", kAdr}, {"superseded_by", kAdr}, {"related", kAdr | kPlan},
|
||||
{"tracking", kPlan | kURL}, {"implemented_by", kURL | kFile},
|
||||
}
|
||||
)
|
||||
|
||||
// adr checks the ADR frontmatter and returns its title for the body check.
|
||||
func (c *checker) adr(r *record, m *fm) (string, bool) {
|
||||
m.keys("title", "date", "status", "implementation", "summary", "tags", "supersedes", "superseded_by", "related", "tracking", "implemented_by")
|
||||
title, titleOK := m.text("title")
|
||||
if d, line, ok := m.scalar("date"); ok {
|
||||
if _, err := time.Parse(time.DateOnly, d); err != nil || len(d) != len(time.DateOnly) {
|
||||
c.add(r.path, line, "date must be a valid YYYY-MM-DD date")
|
||||
} else if d != r.date {
|
||||
c.add(r.path, line, "date %s does not match the filename date %s", d, r.date)
|
||||
}
|
||||
}
|
||||
status, statusOK := m.enum("status", adrStatuses...)
|
||||
impl, implOK := m.enum("implementation", adrImpls...)
|
||||
m.text("summary")
|
||||
m.tags()
|
||||
m.refs(adrRefs...)
|
||||
r.status = status
|
||||
if statusOK {
|
||||
if n := len(r.lists["superseded_by"]); status == "superseded" && n == 0 {
|
||||
m.problemf("status", "status superseded requires superseded_by")
|
||||
} else if status != "superseded" && n > 0 {
|
||||
m.problemf("superseded_by", "superseded_by requires status superseded")
|
||||
}
|
||||
if status == "rejected" && implOK && impl != "not-applicable" {
|
||||
m.problemf("implementation", "status rejected requires implementation not-applicable")
|
||||
}
|
||||
}
|
||||
if implOK && impl == "implemented" && len(r.lists["implemented_by"]) == 0 {
|
||||
m.problemf("implementation", "implementation implemented requires implemented_by")
|
||||
}
|
||||
return title, titleOK
|
||||
}
|
||||
Reference in new issue
Block a user