Skip to content

Commit

Permalink
Add globbing pattern matching for search_path (Replaces #179) (#215)
Browse files Browse the repository at this point in the history
* add globbing pattern matching for search_path

* Update README.md
  • Loading branch information
anya004 authored Dec 17, 2024
1 parent 417171b commit 689525f
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 6 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ optional flags:
A comma separated list of file types to ignore
-groupby string
Group output by filetype, directory, pass-fail. Supported for Standard and JSON reports
-globbing bool
Set globbing to true to enable pattern matching for search paths. Enclose the pattern in double quotes. The flag is not compatible with -exclude-dirs and -exclude-file-types.
-quiet
If quiet flag is set. It doesn't print any output to stdout.
-reporter string
Expand Down Expand Up @@ -210,6 +212,23 @@ Passing the `--quiet` flag suppresses all output to stdout. If there are invalid
validator --quiet /path/to/search
```

### Search files using a glob pattern

Use the `-globbing` flag to validate files matching a specified pattern. Include the pattern as a positional argument in double quotes. Multiple glob patterns and direct file paths are supported. If invalid config files are detected, the validator tool exits with code 1, and errors (e.g., invalid patterns) are displayed.

[Learn more about glob patterns](https://www.digitalocean.com/community/tools/glob)

```
# Validate all `.json` files in a directory
validator -globbing "/path/to/files/*.json"
# Recursively validate all `.json` files in subdirectories
validator -globbing "/path/to/files/**/*.json"
# Mix glob patterns and paths
validator -globbing "/path/*.json" /path/to/search
```

#### Container Run
```
docker run -it --rm -v /path/to/config/files:/test config-file-validator:1.6.0 /test
Expand Down
54 changes: 48 additions & 6 deletions cmd/validator/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ optional flags:
Subdirectories to exclude when searching for configuration files
-exclude-file-types string
A comma separated list of file types to ignore
-globbing bool
Set globbing to true to enable pattern matching for search paths
-reporter string
A string representing report format and optional output file path separated by colon if present.
Usage: --reporter <format>:<optional_file_path>
Expand All @@ -39,6 +41,8 @@ import (
"sort"
"strings"

"github.com/bmatcuk/doublestar/v4"

configfilevalidator "github.com/Boeing/config-file-validator"
"github.com/Boeing/config-file-validator/pkg/cli"
"github.com/Boeing/config-file-validator/pkg/filetype"
Expand All @@ -55,6 +59,7 @@ type validatorConfig struct {
versionQuery *bool
groupOutput *string
quiet *bool
globbing *bool
}

type reporterFlags []string
Expand Down Expand Up @@ -121,6 +126,7 @@ func getFlags() (validatorConfig, error) {
versionPtr = flag.Bool("version", false, "Version prints the release version of validator")
groupOutputPtr = flag.String("groupby", "", "Group output by filetype, directory, pass-fail. Supported for Standard and JSON reports")
quietPtr = flag.Bool("quiet", false, "If quiet flag is set. It doesn't print any output to stdout.")
globbingPrt = flag.Bool("globbing", false, "If globbing flag is set, check for glob patterns in the arguments.")
)
flag.Var(
&reporterConfigFlags,
Expand All @@ -144,7 +150,14 @@ Supported formats: standard, json, junit (default: "standard")`,
return validatorConfig{}, err
}

searchPaths := parseSearchPath()
if err := validateGlobbing(globbingPrt); err != nil {
return validatorConfig{}, err
}

searchPaths, err := parseSearchPath(globbingPrt)
if err != nil {
return validatorConfig{}, err
}

err = validateReporterConf(reporterConf, groupOutputPtr)
if err != nil {
Expand Down Expand Up @@ -176,6 +189,7 @@ Supported formats: standard, json, junit (default: "standard")`,
versionPtr,
groupOutputPtr,
quietPtr,
globbingPrt,
}

return config, nil
Expand Down Expand Up @@ -221,19 +235,42 @@ func validateGroupByConf(groupBy *string) error {
return nil
}

func parseSearchPath() []string {
func validateGlobbing(globbingPrt *bool) error {
if *globbingPrt && (isFlagSet("exclude-dirs") || isFlagSet("exclude-file-types")) {
fmt.Println("The -globbing flag cannot be used with --exclude-dirs or --exclude-file-types")
flag.Usage()
return errors.New("the -globbing flag cannot be used with --exclude-dirs or --exclude-file-types")
}
return nil
}

func parseSearchPath(globbingPrt *bool) ([]string, error) {
searchPaths := make([]string, 0)

// If search path arg is empty, set it to the cwd
// if not, set it to the arg. Supports n number of
// paths
if flag.NArg() == 0 {
searchPaths = append(searchPaths, ".")
} else if *globbingPrt {
return handleGlobbing(searchPaths)
} else {
searchPaths = append(searchPaths, flag.Args()...)
}

return searchPaths
return searchPaths, nil
}

func handleGlobbing(searchPaths []string) ([]string, error) {
for _, flagArg := range flag.Args() {
if isGlobPattern(flagArg) {
matches, err := doublestar.Glob(os.DirFS("."), flagArg)
if err != nil {
return nil, errors.New("Glob matching error")
}
searchPaths = append(searchPaths, matches...)
} else {
searchPaths = append(searchPaths, flagArg)
}
}
return searchPaths, nil
}

func parseReporterFlags(flags reporterFlags) (map[string]string, error) {
Expand Down Expand Up @@ -332,6 +369,11 @@ func cleanString(command string) string {
return cleanedString
}

// Function to check if a string is a glob pattern
func isGlobPattern(s string) bool {
return strings.ContainsAny(s, "*?[]")
}

func mainInit() int {
validatorConfig, err := getFlags()
if err != nil {
Expand Down
6 changes: 6 additions & 0 deletions cmd/validator/validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ func Test_flags(t *testing.T) {
{"grouped sarif", []string{"-groupby=directory", "--reporter=sarif", "."}, 1},
{"groupby duplicate", []string{"--groupby=directory,directory", "."}, 1},
{"quiet flag", []string{"--quiet=true", "."}, 0},
{"globbing flag set", []string{"--globbing=true", "."}, 0},
{"globbing flag with a pattern", []string{"--globbing=true", "../../test/**/[m-t]*.json"}, 0},
{"globbing flag with no matches", []string{"--globbing=true", "../../test/**/*.nomatch"}, 0},
{"globbing flag not set", []string{"test/**/*.json", "."}, 1},
{"globbing flag with exclude-dirs", []string{"-globbing", "--exclude-dirs=subdir", "test/**/*.json", "."}, 1},
{"globbing flag with exclude-file-types", []string{"-globbing", "--exclude-file-types=hcl", "test/**/*.json", "."}, 1},
}
for _, tc := range cases {
// this call is required because otherwise flags panics,
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/Boeing/config-file-validator
go 1.21.0

require (
github.com/bmatcuk/doublestar/v4 v4.7.1
github.com/editorconfig/editorconfig-core-go/v2 v2.6.2
github.com/fatih/color v1.18.0
github.com/gurkankaymak/hocon v1.2.20
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
github.com/bmatcuk/doublestar/v4 v4.7.1 h1:fdDeAqgT47acgwd9bd9HxJRDmc9UAmPpc+2m0CXv75Q=
github.com/bmatcuk/doublestar/v4 v4.7.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/editorconfig/editorconfig-core-go/v2 v2.6.2 h1:dKG8sc7n321deIVRcQtwlMNoBEra7j0qQ8RwxO8RN0w=
Expand Down

0 comments on commit 689525f

Please sign in to comment.