Skip to content

Commit

Permalink
Add support to expand glob patterns
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastien-rosset committed Jun 30, 2022
1 parent 4cc10d8 commit 80f9b24
Show file tree
Hide file tree
Showing 9 changed files with 150 additions and 9 deletions.
33 changes: 30 additions & 3 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"errors"
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
"time"
Expand All @@ -36,6 +37,7 @@ import (
"github.com/get-woke/woke/pkg/parser"
"github.com/get-woke/woke/pkg/printer"

"github.com/bmatcuk/doublestar/v4"
"github.com/mitchellh/go-homedir"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
Expand Down Expand Up @@ -121,7 +123,11 @@ func rootRunE(cmd *cobra.Command, args []string) error {
return err
}

findings := p.ParsePaths(print, parseArgs(args)...)
files, err := parseArgs(args)
if err != nil {
return err
}
findings := p.ParsePaths(print, files...)

if exitOneOnFailure && findings > 0 {
// We intentionally return an error if exitOneOnFailure is true, but don't want to show usage
Expand Down Expand Up @@ -162,16 +168,37 @@ func GetRootCmd() cobra.Command {
return *rootCmd
}

func parseArgs(args []string) []string {
func parseArgs(args []string) ([]string, error) {
if len(args) == 0 {
args = parser.DefaultPath
}

if stdin {
args = []string{os.Stdin.Name()}
}
// Perform glob expansion.
var files []string
for _, arg := range args {
var f []string
var err error
if strings.Contains(arg, "**") {
// Double star glob expansion.
base, pattern := doublestar.SplitPattern(arg)
fsys := os.DirFS(base)
f, err = doublestar.Glob(fsys, pattern)
for i := range f {
f[i] = filepath.Join(base, f[i])
}
} else {
f, err = filepath.Glob(arg)
}
if err != nil {
return nil, err
}
files = append(files, f...)
}

return args
return files, nil
}

func setDebugLogLevel() {
Expand Down
93 changes: 88 additions & 5 deletions cmd/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import (
"bytes"
"io"
"os"
"path/filepath"
"regexp"
"strings"
"testing"

"github.com/get-woke/woke/pkg/output"
Expand Down Expand Up @@ -70,12 +72,93 @@ func TestParseArgs(t *testing.T) {
t.Cleanup(func() {
stdin = false
})
assert.Equal(t, parser.DefaultPath, parseArgs([]string{}))
assert.Equal(t, []string{"../.."}, parseArgs([]string{"../.."}))
tests := []struct {
stdin bool
args []string
expectedArgs []string
expectedError error
}{
{
stdin: false,
args: []string{},
expectedArgs: parser.DefaultPath,
expectedError: nil,
},
{
stdin: false,
args: []string{"../.."},
expectedArgs: []string{"../.."},
expectedError: nil,
},

// Test glob expansion
{
stdin: false,
args: []string{"../testdata/*.yml"},
expectedArgs: []string{"../testdata/good.yml", "../testdata/whitelist.yml"},
expectedError: nil,
},
{
stdin: false,
args: []string{"../testdata/g??d.yml"},
expectedArgs: []string{"../testdata/good.yml"},
expectedError: nil,
},
{
stdin: false,
args: []string{"../testdata/[a-z]ood.yml"},
expectedArgs: []string{"../testdata/good.yml"},
expectedError: nil,
},
{
stdin: false,
args: []string{"../testdata/*/*.yml"},
expectedArgs: []string{"../testdata/subdir1/good.yml", "../testdata/subdir1/whitelist.yml"},
expectedError: nil,
},
{
stdin: false,
args: []string{"../testdata/**/*.yml"},
expectedArgs: []string{
"../testdata/good.yml",
"../testdata/whitelist.yml",
"../testdata/subdir1/good.yml",
"../testdata/subdir1/whitelist.yml",
"../testdata/subdir1/subdir2/good.yml",
"../testdata/subdir1/subdir2/whitelist.yml",
},
expectedError: nil,
},

stdin = true
assert.Equal(t, []string{os.Stdin.Name()}, parseArgs([]string{}))
assert.Equal(t, []string{os.Stdin.Name()}, parseArgs([]string{"../.."}))
// Bad glob pattern
{
stdin: false,
args: []string{"r[.go"},
expectedArgs: nil,
expectedError: filepath.ErrBadPattern,
},

{
stdin: true,
args: []string{},
expectedArgs: []string{os.Stdin.Name()},
expectedError: nil,
},
{
stdin: true,
args: []string{"../.."},
expectedArgs: []string{os.Stdin.Name()},
expectedError: nil,
},
}
for _, tt := range tests {
t.Run(strings.Join(tt.args, " "), func(t *testing.T) {
stdin = tt.stdin
files, err := parseArgs(tt.args)
assert.ErrorIs(t, err, tt.expectedError)
assert.Equal(t, tt.expectedArgs, files)
})
}
}

func TestRunE(t *testing.T) {
Expand Down
22 changes: 21 additions & 1 deletion docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,30 @@ No findings found.
### File globs

By default, `woke` will run against all text files in your current directory.
To change this, supply a space-separated list of globs as the first argument.
To change this, supply a space-separated list of file glob patterns.
`woke` supports the following glob pattern:

```
pattern:
{ term }
term:
'*' matches any sequence of non-Separator characters
'?' matches any single non-Separator character
'[' [ '^' ] { character-range } ']'
character class (must be non-empty)
c matches character c (c != '*', '?', '\\', '[')
'\\' c matches character c
character-range:
c matches character c (c != '\\', '-', ']')
'\\' c matches character c
lo '-' hi matches character c for lo <= c <= hi
```

This can be something like `**/*.go`, or a space-separated list of filenames.

If `woke` is invoked from a shell, the invoking shell performs file glob pattern expansion according to the shell glob rules.

```bash
$ woke test.txt
test.txt:2:2-11: `Blacklist` may be insensitive, use `denylist`, `blocklist` instead (warning)
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ require (

require (
github.com/acomagu/bufpipe v1.0.3 // indirect
github.com/bmatcuk/doublestar/v4 v4.0.2 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fsnotify/fsnotify v1.5.1 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgI
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
github.com/bmatcuk/doublestar/v4 v4.0.2 h1:X0krlUVAVmtr2cRoTqR8aDMrDqnB36ht8wpWTiQ3jsA=
github.com/bmatcuk/doublestar/v4 v4.0.2/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
github.com/caitlinelfring/go-env-default v1.0.0 h1:DY8qY3OKb9PrGe+sjop7dw7tOKh6kV8cdZONlESSbZc=
github.com/caitlinelfring/go-env-default v1.0.0/go.mod h1:vY8iS64s+wIBKayqiNGJsWMwc19NrxaNNTyWzuPvE44=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
Expand Down
2 changes: 2 additions & 0 deletions testdata/subdir1/good.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
this file has no findings.
2 changes: 2 additions & 0 deletions testdata/subdir1/subdir2/good.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
this file has no findings.
2 changes: 2 additions & 0 deletions testdata/subdir1/subdir2/whitelist.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
this file also has a whitelist finding
2 changes: 2 additions & 0 deletions testdata/subdir1/whitelist.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
this file also has a whitelist finding

0 comments on commit 80f9b24

Please sign in to comment.