@@ -1458,9 +1458,33 @@ func runValidate(args []string) int {
14581458 fs .SetOutput (os .Stderr )
14591459 quiet := fs .Bool ("quiet" , false , "print only errors" )
14601460 specVersion := fs .String ("spec" , "latest" , "OKF spec version" )
1461+ format := fs .String ("format" , "text" , "output format: text or json" )
1462+ out := fs .String ("out" , "" , "write a machine-readable JSON report to this file" )
1463+ asJSON := fs .Bool ("json" , false , "print the machine-readable JSON report" )
1464+ ruleOverrides := stringListFlag {}
1465+ fs .Var (& ruleOverrides , "rule" , "override validation rule severity as rule=off|warn|error; may be repeated" )
14611466 if err := fs .Parse (args ); err != nil {
14621467 return 2
14631468 }
1469+ if * asJSON {
1470+ * format = "json"
1471+ }
1472+ * format = strings .TrimSpace (strings .ToLower (* format ))
1473+ if * format == "" {
1474+ * format = "text"
1475+ }
1476+ if * format != "text" && * format != "json" {
1477+ fmt .Fprintf (os .Stderr , "unsupported validate format: %s\n " , * format )
1478+ return 2
1479+ }
1480+ if * quiet && * format == "json" {
1481+ fmt .Fprintln (os .Stderr , "--quiet cannot be combined with JSON validation output" )
1482+ return 2
1483+ }
1484+ if strings .TrimSpace (* out ) != "" && * format != "json" {
1485+ fmt .Fprintln (os .Stderr , "--out requires --format json or --json" )
1486+ return 2
1487+ }
14641488
14651489 root := "."
14661490 if fs .NArg () > 1 {
@@ -1477,12 +1501,42 @@ func runValidate(args []string) int {
14771501 return 2
14781502 }
14791503
1480- result , err := okf .ValidateWithVersion (root , * specVersion )
1504+ validationOptions , err := okf .LoadValidationOptions (root )
1505+ if err != nil {
1506+ fmt .Fprintln (os .Stderr , err )
1507+ return 2
1508+ }
1509+ cliOptions := okf.ValidationOptions {}
1510+ for _ , override := range ruleOverrides {
1511+ rule , severity , err := okf .ParseValidationRuleOverride (override )
1512+ if err != nil {
1513+ fmt .Fprintln (os .Stderr , err )
1514+ return 2
1515+ }
1516+ if err := okf .SetValidationRuleSeverity (& cliOptions , rule , severity ); err != nil {
1517+ fmt .Fprintln (os .Stderr , err )
1518+ return 2
1519+ }
1520+ }
1521+ validationOptions = okf .MergeValidationOptions (validationOptions , cliOptions )
1522+
1523+ result , err := okf .ValidateWithVersionAndOptions (root , * specVersion , validationOptions )
14811524 if err != nil {
14821525 fmt .Fprintln (os .Stderr , err )
14831526 return 2
14841527 }
14851528
1529+ if * format == "json" {
1530+ if err := printValidationJSONResult (result , strings .TrimSpace (* out )); err != nil {
1531+ fmt .Fprintln (os .Stderr , err )
1532+ return 1
1533+ }
1534+ if len (result .Errors ) > 0 {
1535+ return 1
1536+ }
1537+ return 0
1538+ }
1539+
14861540 if * quiet {
14871541 for _ , issue := range result .Errors {
14881542 fmt .Fprintln (os .Stderr , issue )
@@ -1500,6 +1554,25 @@ func runValidate(args []string) int {
15001554 return 0
15011555}
15021556
1557+ func printValidationJSONResult (result okf.Result , out string ) error {
1558+ data , err := json .MarshalIndent (result , "" , " " )
1559+ if err != nil {
1560+ return err
1561+ }
1562+ data = append (data , '\n' )
1563+ if out == "" {
1564+ fmt .Print (string (data ))
1565+ return nil
1566+ }
1567+ if err := os .WriteFile (out , data , 0644 ); err != nil {
1568+ return err
1569+ }
1570+ terminal .success ("Wrote validation report" )
1571+ fmt .Printf ("%s %s\n " , terminal .muted ("root" ), terminal .path (result .Root ))
1572+ fmt .Printf ("%s %s\n " , terminal .muted ("out" ), terminal .path (out ))
1573+ return nil
1574+ }
1575+
15031576func printValidationResult (result okf.Result ) {
15041577 terminal .title ("Open Knowledge Validate" , "against Open Knowledge Format v" + result .SpecVersion )
15051578
@@ -2005,6 +2078,8 @@ Usage:
20052078 openknowledge spec latest|<version>
20062079 openknowledge validate [key-or-path]
20072080 openknowledge validate --spec <version> [key-or-path]
2081+ openknowledge validate --format json [key-or-path]
2082+ openknowledge validate --rule <rule=off|warn|error> [key-or-path]
20082083 openknowledge list [key-or-path]
20092084 openknowledge list --spec <version> [key-or-path]
20102085 openknowledge list --json [key-or-path]
@@ -2460,6 +2535,9 @@ Validate a bundle against an Open Knowledge Format spec.
24602535Usage:
24612536 openknowledge validate [key-or-path]
24622537 openknowledge validate --spec <version> [key-or-path]
2538+ openknowledge validate --format json [key-or-path]
2539+ openknowledge validate --format json --out <file> [key-or-path]
2540+ openknowledge validate --rule <rule=off|warn|error> [key-or-path]
24632541 openknowledge validate --quiet [key-or-path]
24642542 openknowledge validate --help
24652543
@@ -2468,14 +2546,24 @@ Arguments:
24682546
24692547Flags:
24702548 --spec OKF spec version. Defaults to latest.
2549+ --format Output format: text or json. Defaults to text.
2550+ --json Alias for --format json.
2551+ --out Write a JSON validation report to a file. Requires JSON output.
2552+ --rule Override one validation rule severity as rule=off|warn|error.
2553+ May be repeated and overrides [validation.rules] config.
24712554 --quiet Print only validation errors.
24722555
2556+ Config:
2557+ openknowledge.toml may define [validation.rules] with rule severities:
2558+ link-target = "error"
2559+ markdown-syntax = "off"
2560+
24732561Versions:
24742562 %s
24752563
24762564Exit codes:
24772565 0 Validation passed, with or without warnings.
2478- 1 Validation found errors.
2566+ 1 Validation found errors after configured severity overrides .
24792567 2 Usage or setup error.
24802568` , supportedSpecVersionsText ())
24812569}
0 commit comments