Skip to content

Commit 92250d6

Browse files
committed
feat: separate multiple validation errors across all reporters
- Standard: each error on its own indented line - JSON: errors as an array instead of a single joined string - SARIF: each error as its own result entry for per-error annotations - JUnit: each error on its own line within the failure message Add SchemaErrors type to carry individual error messages from JSONSchemaValidate, ValidateXSD, and SARIF schema validation. The CLI populates ValidationErrors slice on Report for reporters to consume.
1 parent b3a4bbf commit 92250d6

19 files changed

+183
-143
lines changed

cmd/validator/testdata/json_schema.txtar

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ stdout '✓'
1111
# Invalid package.json (version must be string)
1212
! exec validator invalid_package.json
1313
stdout '×'
14-
stdout 'schema validation failed'
14+
stdout 'error:'
1515

1616
# --- tsconfig.json schema ---
1717

@@ -22,7 +22,7 @@ stdout '✓'
2222
# Invalid tsconfig.json (target must be string)
2323
! exec validator invalid_tsconfig.json
2424
stdout '×'
25-
stdout 'schema validation failed'
25+
stdout 'error:'
2626

2727
# --- eslintrc schema ---
2828

@@ -39,7 +39,7 @@ stdout '✓'
3939
# Invalid workflow (missing required jobs)
4040
! exec validator invalid_workflow.json
4141
stdout '×'
42-
stdout 'schema validation failed'
42+
stdout 'error:'
4343

4444
# --- Strict config schema ---
4545

@@ -50,27 +50,27 @@ stdout '✓'
5050
# Missing required field
5151
! exec validator missing_required.json
5252
stdout '×'
53-
stdout 'schema validation failed'
53+
stdout 'error:'
5454

5555
# Wrong type
5656
! exec validator wrong_type.json
5757
stdout '×'
58-
stdout 'schema validation failed'
58+
stdout 'error:'
5959

6060
# Extra property not allowed
6161
! exec validator extra_property.json
6262
stdout '×'
63-
stdout 'schema validation failed'
63+
stdout 'error:'
6464

6565
# Value out of range
6666
! exec validator out_of_range.json
6767
stdout '×'
68-
stdout 'schema validation failed'
68+
stdout 'error:'
6969

7070
# Enum violation
7171
! exec validator bad_enum.json
7272
stdout '×'
73-
stdout 'schema validation failed'
73+
stdout 'error:'
7474

7575
# --- Array schema ---
7676

@@ -81,12 +81,12 @@ stdout '✓'
8181
# Too few items
8282
! exec validator too_few_items.json
8383
stdout '×'
84-
stdout 'schema validation failed'
84+
stdout 'error:'
8585

8686
# Wrong item type
8787
! exec validator wrong_item_type.json
8888
stdout '×'
89-
stdout 'schema validation failed'
89+
stdout 'error:'
9090

9191
# --- Mixed: files with and without $schema ---
9292

cmd/validator/testdata/no_schema.txtar

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ stdout '✓'
66
# Without --no-schema it fails
77
! exec validator bad_with_schema.json
88
stdout '×'
9-
stdout 'schema validation failed'
9+
stdout 'error:'
1010

1111
# --no-schema with YAML schema comment — skips validation
1212
exec validator --no-schema bad_with_schema.yaml

cmd/validator/testdata/schema_map.txtar

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ stdout '✓'
55
# --schema-map with invalid data fails
66
! exec validator --schema-map=bad.json:schema.json bad.json
77
stdout '×'
8-
stdout 'schema validation failed'
8+
stdout 'error:'
99

1010
# --schema-map with glob pattern
1111
exec validator --schema-map=**/*.json:schema.json subdir/config.json

cmd/validator/testdata/schemastore.txtar

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ stdout '✓'
1414
# Invalid package.json (version must be string)
1515
! exec validator --schemastore schemastore invalid/package.json
1616
stdout '×'
17-
stdout 'schema validation failed'
17+
stdout 'error:'
1818

1919
# Valid nodemon.json
2020
exec validator --schemastore schemastore valid/nodemon.json
@@ -23,7 +23,7 @@ stdout '✓'
2323
# Invalid nodemon.json (unknown field, additionalProperties: false)
2424
! exec validator --schemastore schemastore invalid/nodemon.json
2525
stdout '×'
26-
stdout 'schema validation failed'
26+
stdout 'error:'
2727

2828
# ============================================================
2929
# PART 2: --schemastore automatic matching (YAML)
@@ -36,7 +36,7 @@ stdout '✓'
3636
# Invalid GitHub workflow (missing required 'jobs')
3737
! exec validator --schemastore schemastore invalid/.github/workflows/ci.yml
3838
stdout '×'
39-
stdout 'schema validation failed'
39+
stdout 'error:'
4040

4141
# Valid artifacthub-repo.yml
4242
exec validator --schemastore schemastore valid/artifacthub-repo.yml
@@ -45,7 +45,7 @@ stdout '✓'
4545
# Invalid artifacthub-repo.yml (additionalProperties: false)
4646
! exec validator --schemastore schemastore invalid/artifacthub-repo.yml
4747
stdout '×'
48-
stdout 'schema validation failed'
48+
stdout 'error:'
4949

5050
# ============================================================
5151
# PART 3: --schemastore automatic matching (TOML)
@@ -58,7 +58,7 @@ stdout '✓'
5858
# Invalid stylua.toml (column_width must be integer)
5959
! exec validator --schemastore schemastore invalid/stylua.toml
6060
stdout '×'
61-
stdout 'schema validation failed'
61+
stdout 'error:'
6262

6363
# ============================================================
6464
# PART 4: --schemastore automatic matching (TOON)
@@ -71,7 +71,7 @@ stdout '✓'
7171
# Invalid app.toon (port out of range)
7272
! exec validator --schemastore schemastore invalid/app.toon
7373
stdout '×'
74-
stdout 'schema validation failed'
74+
stdout 'error:'
7575

7676
# ============================================================
7777
# PART 5: Unmatched files pass syntax-only
@@ -115,7 +115,7 @@ stdout '✓'
115115
# schema-map points to strict schema that rejects the file
116116
! exec validator --schema-map=package.json:strict_schema.json --schemastore schemastore valid/package.json
117117
stdout '×'
118-
stdout 'schema validation failed'
118+
stdout 'error:'
119119

120120
# ============================================================
121121
# PART 9: --schema-map with YAML
@@ -126,7 +126,7 @@ stdout '✓'
126126

127127
! exec validator --schema-map=config.yaml:server_schema.json invalid/config.yaml
128128
stdout '×'
129-
stdout 'schema validation failed'
129+
stdout 'error:'
130130

131131
# ============================================================
132132
# PART 10: --schema-map with TOML
@@ -137,7 +137,7 @@ stdout '✓'
137137

138138
! exec validator --schema-map=config.toml:server_schema.json invalid/config.toml
139139
stdout '×'
140-
stdout 'schema validation failed'
140+
stdout 'error:'
141141

142142
# ============================================================
143143
# PART 11: --schema-map with TOON
@@ -148,7 +148,7 @@ stdout '✓'
148148

149149
! exec validator --schema-map=config.toon:server_schema.json invalid/config.toon
150150
stdout '×'
151-
stdout 'schema validation failed'
151+
stdout 'error:'
152152

153153
# ============================================================
154154
# PART 12: --schema-map with glob patterns
@@ -159,7 +159,7 @@ stdout '✓'
159159

160160
! exec validator --schema-map=**/configs/*.json:server_schema.json invalid/configs/db.json
161161
stdout '×'
162-
stdout 'schema validation failed'
162+
stdout 'error:'
163163

164164
# ============================================================
165165
# PART 13: Multiple files, mixed results

cmd/validator/testdata/toml_schema.txtar

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ stdout '✓'
55
# TOML with invalid data fails schema validation
66
! exec validator invalid.toml
77
stdout '×'
8-
stdout 'schema validation failed'
8+
stdout 'error:'
99

1010
# TOML without $schema passes (syntax only)
1111
exec validator plain.toml

cmd/validator/testdata/toon_schema.txtar

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ stdout '✓'
55
# TOON with invalid data fails schema validation
66
! exec validator invalid.toon
77
stdout '×'
8-
stdout 'schema validation failed'
8+
stdout 'error:'
99

1010
# TOON without $schema passes (syntax only)
1111
exec validator plain.toon

cmd/validator/testdata/xml_schema.txtar

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ stdout '✓'
6161
# Invalid type
6262
! exec validator xsd_invalid.xml
6363
stdout '×'
64-
stdout 'schema validation failed'
64+
stdout 'error:'
6565

6666
# No schema passes syntax-only
6767
exec validator plain.xml
@@ -87,7 +87,7 @@ stdout '✓'
8787
# --schema-map with XSD invalid
8888
! exec validator --schema-map=mapped_bad.xml:schema.xsd mapped_bad.xml
8989
stdout '×'
90-
stdout 'schema validation failed'
90+
stdout 'error:'
9191

9292
# ============================================================
9393
# DTD + XSD together
@@ -100,7 +100,7 @@ stdout '✓'
100100
# DTD valid but XSD fails (wrong type)
101101
! exec validator dtd_ok_xsd_bad.xml
102102
stdout '×'
103-
stdout 'schema validation failed'
103+
stdout 'error:'
104104

105105
# DTD fails (missing element) — never reaches XSD
106106
! exec validator dtd_bad_xsd_ok.xml

cmd/validator/testdata/yaml_schema.txtar

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ stdout '✓'
55
# YAML with invalid data fails schema validation
66
! exec validator invalid.yaml
77
stdout '×'
8-
stdout 'schema validation failed'
8+
stdout 'error:'
99

1010
# YAML without schema comment passes (syntax only)
1111
exec validator plain.yaml

pkg/cli/cli.go

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,23 @@ func (c CLI) Run() (int, error) {
130130
col = ve.Column
131131
}
132132

133+
var validationErrors []string
134+
var se *validator.SchemaErrors
135+
if errors.As(err, &se) {
136+
validationErrors = se.Errors()
137+
} else if err != nil {
138+
validationErrors = []string{err.Error()}
139+
}
140+
133141
report := reporter.Report{
134-
FileName: fileToValidate.Name,
135-
FilePath: fileToValidate.Path,
136-
IsValid: isValid,
137-
ValidationError: err,
138-
IsQuiet: Quiet,
139-
StartLine: line,
140-
StartColumn: col,
142+
FileName: fileToValidate.Name,
143+
FilePath: fileToValidate.Path,
144+
IsValid: isValid,
145+
ValidationError: err,
146+
ValidationErrors: validationErrors,
147+
IsQuiet: Quiet,
148+
StartLine: line,
149+
StartColumn: col,
141150
}
142151
if !isValid {
143152
errorFound = true

pkg/reporter/json_reporter.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ func NewJSONReporter(outputDest string) *JSONReporter {
1717
}
1818

1919
type fileStatus struct {
20-
Path string `json:"path"`
21-
Status string `json:"status"`
22-
Error string `json:"error,omitempty"`
20+
Path string `json:"path"`
21+
Status string `json:"status"`
22+
Errors []string `json:"errors,omitempty"`
2323
}
2424

2525
type summary struct {
@@ -202,10 +202,10 @@ func createJSONReport(reports []Report) (reportJSON, error) {
202202

203203
for _, report := range reports {
204204
status := "passed"
205-
errorStr := ""
205+
var errs []string
206206
if !report.IsValid {
207207
status = "failed"
208-
errorStr = report.ValidationError.Error()
208+
errs = report.ValidationErrors
209209
}
210210

211211
// Convert Windows-style file paths.
@@ -216,7 +216,7 @@ func createJSONReport(reports []Report) (reportJSON, error) {
216216
jsonReport.Files = append(jsonReport.Files, fileStatus{
217217
Path: report.FilePath,
218218
Status: status,
219-
Error: errorStr,
219+
Errors: errs,
220220
})
221221

222222
currentPassed := 0

0 commit comments

Comments
 (0)