Files
member-console/cmd/lint.go
T
cgalo5758 408fa6f5a6 Add page anatomy parts and UI quality gate
- Add shared ui_*.html parts (pageHeader, sectionHeader, statusBadge,
  emptyState) parsed into every template set
- Add anatomy lint rules with a shrinking allowlist and screen-coverage
  check
- Add make screens capture harness with contact sheets and baseline diff
- Compose member and FedWiki regions server-side so pages arrive
  complete
- Rebuild Domains and Integrations on the parts as pilots
2026-08-30 04:05:31 -05:00

65 lines
2.7 KiB
Go

package cmd
import (
"fmt"
"os"
"github.com/spf13/cobra"
"git.coopcloud.tech/wiki-cafe/member-console/internal/lint"
)
var lintCmd = &cobra.Command{
Use: "lint",
Short: "Static checks for operator UI integrity (M7f.1)",
Long: `lint walks the Go source under internal/server/ and the templates
under internal/embeds/templates/ and reports:
- dead routes: routeURL patterns with no registered handler
- dead swap targets: hx-target="#X" with no matching id="X"
- stale tab references: ?tab= was retired in M7d (operator-mpa-conversion)
- banned literal URLs: interpolated hx-* URL strings must use routeURL
Exits 0 on a clean tree, 1 on violations, 2 on internal errors. Safe to wire
into CI or a pre-commit hook. See status/milestones.md (M7f.1) and
docs/operator-ux-conventions.md §9.`,
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
serverDir, _ := cmd.Flags().GetString("server-dir")
templateDir, _ := cmd.Flags().GetString("template-dir")
walkthroughDir, _ := cmd.Flags().GetString("walkthrough-dir")
allowlistPath, _ := cmd.Flags().GetString("anatomy-allowlist")
manifestPath, _ := cmd.Flags().GetString("screens-manifest")
res, err := lint.Run(lint.Config{
ServerDir: serverDir,
TemplateDir: templateDir,
WalkthroughDir: walkthroughDir,
AllowlistPath: allowlistPath,
ManifestPath: manifestPath,
})
if err != nil {
fmt.Fprintf(os.Stderr, "lint: %v\n", err)
os.Exit(2)
}
for _, v := range res.Violations {
fmt.Fprintf(os.Stderr, "%s:%d: [%s] %s\n", v.File, v.Line, v.Rule, v.Message)
}
if len(res.Violations) > 0 {
fmt.Fprintf(os.Stderr, "\nlint: %d violation(s) across %d routes / %d URL refs\n",
len(res.Violations), res.RoutesScanned, res.URLRefsScanned)
os.Exit(1)
}
fmt.Fprintf(os.Stderr, "lint: ok (%d routes, %d URL refs; %d anatomy violation(s) allowlisted pending the 10k.2 sweep)\n", res.RoutesScanned, res.URLRefsScanned, res.Allowlisted)
},
}
func init() {
lintCmd.Flags().String("server-dir", "internal/server", "Go source directory containing mux.HandleFunc registrations")
lintCmd.Flags().String("template-dir", "internal/embeds/templates", "Embedded templates directory")
lintCmd.Flags().String("anatomy-allowlist", "internal/lint/anatomy_allowlist.txt", `Templates not yet rebuilt on the page-anatomy parts ("-" disables the anatomy rules)`)
lintCmd.Flags().String("screens-manifest", "test/e2e/screens/manifest.go", `Screens manifest for the screen-coverage rule ("-" disables it)`)
lintCmd.Flags().String("walkthrough-dir", "test/e2e/operator-walkthroughs", `Walkthrough directory for coverage rule (set "-" to disable)`)
rootCmd.AddCommand(lintCmd)
}