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
22 changes: 18 additions & 4 deletions internal/glob/glob.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,22 @@ import (
type Glob struct {
Pattern string
Negated bool

// compiled is the `gobwas/glob` form of Pattern, built once by NewGlob.
// It's nil for a `**` pattern, which doublestar matches instead.
compiled glob.Glob
}

// Match returns whether or not the Glob g matches the string query.
func (g Glob) Match(query string) bool {
q := filepath.ToSlash(query)

if strings.Contains(g.Pattern, "**") {
if g.compiled == nil {
matched, _ := doublestar.Match(g.Pattern, q)
return matched != g.Negated
}

p := glob.MustCompile(g.Pattern)
return p.Match(q) != g.Negated
return g.compiled.Match(q) != g.Negated
}

// MatchAny returns whether or not the Glob g matches any of the strings in
Expand All @@ -49,7 +52,18 @@ func NewGlob(pat string) (Glob, error) {
if err != nil {
return Glob{}, err
}
return Glob{Pattern: pat, Negated: negate}, nil

if strings.Contains(pat, "**") {
return Glob{Pattern: pat, Negated: negate}, nil
}

// doublestar accepts patterns gobwas/glob rejects, and Match used to
// compile there with MustCompile -- so `--glob='[a-]*'` panicked mid-walk.
compiled, err := glob.Compile(pat)
if err != nil {
return Glob{}, err
}
return Glob{Pattern: pat, Negated: negate, compiled: compiled}, nil
}

// Compile is a wrapper around NewGlobal for backwards compatibility.
Expand Down
14 changes: 14 additions & 0 deletions internal/glob/glob_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@ var globTests = []struct {
},
}

// Patterns doublestar accepts and gobwas/glob rejects. NewGlob has to report
// them, since Match can't: it used to compile with MustCompile and panicked
// partway through the walk.
var invalidGlobs = []string{`[a-]`, `[a-b-c]`}

func TestInvalidGlob(t *testing.T) {
for _, pat := range invalidGlobs {
g, err := NewGlob(pat)
if err == nil {
t.Errorf("%s: expected an error, got %+v", pat, g)
}
}
}

func TestGlob(t *testing.T) {
for _, tt := range globTests {
g, _ := NewGlob(tt.pattern)
Expand Down
8 changes: 8 additions & 0 deletions testdata/e2e/config-flags.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@ cases:
- py
requires: asciidoctor, dita, rst2html, xsltproc

- name: glob-invalid
about: "a pattern gobwas/glob rejects used to panic mid-walk"
dir: ../glob
args: "--glob=[a-]* ."
exit: 2
want: |
expected close range character

- name: no-config-found
dir: ../../../..
args: .
Expand Down
Loading