Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- Repeating the same `--reporter` type with different output paths now writes each requested output.
- KnownFiles now take priority over extension matching in the finder, so `tsconfig.json` resolves to JSONC (not JSON)
- Extension exclusion cache no longer prevents known files from being found
- Linguist known files that conflict with dedicated validators are automatically excluded (e.g. `.editorconfig` stays with EditorConfig, not INI)
Expand Down
11 changes: 11 additions & 0 deletions cmd/validator/testdata/reporters.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ exec validator --reporter=json:multi.json --reporter=standard:- good.json
stdout '✓'
exists multi.json

# Duplicate reporter type to separate files
exec validator --reporter=json:first.json --reporter=json:second.json good.json
exists first.json
exists second.json

# Duplicate reporter type to the same file leaves one valid report
exec validator --reporter=json:same.json --reporter=json:same.json good.json
exists same.json
exec validator same.json
stdout '✓'

# Invalid reporter
! exec validator --reporter=bad good.json

Expand Down
39 changes: 22 additions & 17 deletions cmd/validator/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ type validatorConfig struct {
excludeDirs *string
excludeFileTypes *string
fileTypes *string
reportType map[string]string
reportType []reporterConfig
depth *int
versionQuery *bool
groupOutput *string
Expand All @@ -83,6 +83,11 @@ type validatorConfig struct {

type reporterFlags []string

type reporterConfig struct {
reportType string
outputDest string
}

func (rf *reporterFlags) String() string {
return fmt.Sprint(*rf)
}
Expand Down Expand Up @@ -286,7 +291,7 @@ func getFlags(args []string) (validatorConfig, error) {
return config, nil
}

func validateFlagValues(excludeFileTypesPtr, fileTypesPtr *string, depthPtr *int, reporterConf map[string]string, groupOutputPtr *string) error {
func validateFlagValues(excludeFileTypesPtr, fileTypesPtr *string, depthPtr *int, reporterConf []reporterConfig, groupOutputPtr *string) error {
if err := validateReporterConf(reporterConf, groupOutputPtr); err != nil {
return err
}
Expand Down Expand Up @@ -321,17 +326,17 @@ func validateFileTypeFlags(excludeFileTypesPtr, fileTypesPtr *string) error {
return nil
}

func validateReporterConf(conf map[string]string, groupBy *string) error {
func validateReporterConf(conf []reporterConfig, groupBy *string) error {
acceptedReportTypes := map[string]bool{"standard": true, "json": true, "junit": true, "sarif": true, "github": true}
groupOutputReportTypes := map[string]bool{"standard": true, "json": true}

for reportType := range conf {
_, ok := acceptedReportTypes[reportType]
for _, reporterConf := range conf {
_, ok := acceptedReportTypes[reporterConf.reportType]
if !ok {
return errors.New("wrong parameter value for reporter, only supports standard, json, junit, sarif, or github")
}

if !groupOutputReportTypes[reportType] && groupBy != nil && *groupBy != "" {
if !groupOutputReportTypes[reporterConf.reportType] && groupBy != nil && *groupBy != "" {
return errors.New("wrong parameter value for reporter, groupby is only supported for standard and JSON reports")
}
}
Expand Down Expand Up @@ -397,26 +402,26 @@ func handleGlobbing(searchPaths []string) ([]string, error) {
return searchPaths, nil
}

func parseReporterFlags(flags reporterFlags) (map[string]string, error) {
conf := make(map[string]string)
func parseReporterFlags(flags reporterFlags) ([]reporterConfig, error) {
conf := make([]reporterConfig, 0, len(flags))
for _, reportFlag := range flags {
parts := strings.Split(reportFlag, ":")
parts := strings.SplitN(reportFlag, ":", 2)
switch len(parts) {
case 1:
conf[parts[0]] = ""
conf = append(conf, reporterConfig{reportType: parts[0]})
case 2:
if parts[1] == "-" {
conf[parts[0]] = ""
conf = append(conf, reporterConfig{reportType: parts[0]})
} else {
conf[parts[0]] = parts[1]
conf = append(conf, reporterConfig{reportType: parts[0], outputDest: parts[1]})
}
default:
return nil, errors.New("wrong parameter value format for reporter, expected format is `report_type:optional_file_path`")
}
}

if len(conf) == 0 {
conf["standard"] = ""
conf = append(conf, reporterConfig{reportType: "standard"})
}

return conf, nil
Expand Down Expand Up @@ -642,10 +647,10 @@ func buildCLI(rc *resolvedConfig) *cli.CLI {
return cli.Init(opts...)
}

func buildReporters(reportType map[string]string) ([]reporter.Reporter, error) {
reporters := make([]reporter.Reporter, 0, len(reportType))
for rt, of := range reportType {
reporters = append(reporters, getReporter(rt, of))
func buildReporters(reporterConfigs []reporterConfig) ([]reporter.Reporter, error) {
reporters := make([]reporter.Reporter, 0, len(reporterConfigs))
for _, rc := range reporterConfigs {
reporters = append(reporters, getReporter(rc.reportType, rc.outputDest))
}
return reporters, nil
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/validator/validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func Test_getFlags(t *testing.T) {
// Invalid flag combinations
{"negative depth", []string{"-depth=-1", "."}, true},
{"wrong reporter", []string{"--reporter=wrong", "."}, true},
{"bad reporter format", []string{"--reporter", "json:/a:/b", "."}, true},
{"reporter output path with colon", []string{"--reporter", "json:/a:/b", "."}, false},
{"invalid groupby", []string{"-groupby=badgroup", "."}, true},
{"groupby duplicate", []string{"--groupby=directory,directory", "."}, true},
{"grouped junit", []string{"-groupby=directory", "--reporter=junit", "."}, true},
Expand Down
6 changes: 6 additions & 0 deletions website/docs/guides/output-reporters.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ Append `:<path>` to the reporter name to write results to a file:
validator --reporter=json:output.json .
```

Repeat the same reporter type with different paths to write the same format to more than one file:

```shell
validator --reporter=json:summary.json --reporter=json:artifacts/summary.json .
```

Use `:-` to explicitly direct output to stdout (useful when combining reporters):

```shell
Expand Down
Loading