From f4e1414d676b19c3f241041fc08552ae9a2c495f Mon Sep 17 00:00:00 2001 From: Zbigniew Mandziejewicz Date: Fri, 14 Dec 2018 16:24:38 +0100 Subject: [PATCH 1/3] Use doublestar for glob matching --- go.mod | 1 + go.sum | 2 ++ match.go | 5 +++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index f159292..4bff399 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,7 @@ module github.com/cespare/reflex require ( + github.com/bmatcuk/doublestar v1.1.1 github.com/fsnotify/fsnotify v1.4.7 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/kr/pretty v0.1.0 diff --git a/go.sum b/go.sum index 9d13366..fc18fa1 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/bmatcuk/doublestar v1.1.1 h1:YroD6BJCZBYx06yYFEWvUuKVWQn3vLLQAVmDmvTSaiQ= +github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= diff --git a/match.go b/match.go index 1bc4b59..8760874 100644 --- a/match.go +++ b/match.go @@ -2,11 +2,12 @@ package main import ( "fmt" - "path/filepath" "regexp" "regexp/syntax" "strings" "sync" + + "github.com/bmatcuk/doublestar" ) // A Matcher decides whether some filename matches its set of patterns. @@ -67,7 +68,7 @@ type globMatcher struct { } func (m *globMatcher) Match(name string) bool { - matches, err := filepath.Match(m.glob, name) + matches, err := doublestar.PathMatch(m.glob, name) if err != nil { return false } From c281b3b195005af5167f6d7f47e70ee3d3bb0f5d Mon Sep 17 00:00:00 2001 From: Zbigniew Mandziejewicz Date: Thu, 2 May 2019 12:05:34 +0200 Subject: [PATCH 2/3] feat: add globMatcher.ExceludePrefix impl --- match.go | 28 +++++++++++++++++++++++++++- match_test.go | 28 +++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/match.go b/match.go index 8760874..46b6bfe 100644 --- a/match.go +++ b/match.go @@ -75,7 +75,33 @@ func (m *globMatcher) Match(name string) bool { return matches != m.inverse } -func (m *globMatcher) ExcludePrefix(prefix string) bool { return false } +func (m *globMatcher) ExcludePrefix(prefix string) bool { + if !m.inverse || len(m.glob) == 0 { + return false + } + + matches, err := doublestar.PathMatch(m.glob, prefix) + if err != nil || matches { + return false + } + + var i = 0 + for { + if m.glob[i] == '/' { + i++ + } + pos := strings.Index(m.glob[i:], "/") + if pos == -1 { + return true + } + i += pos + + matches, _ := doublestar.PathMatch(m.glob[:i], prefix) + if matches { + return false + } + } +} func (m *globMatcher) String() string { s := "Glob" diff --git a/match_test.go b/match_test.go index 5024306..aaf4ce3 100644 --- a/match_test.go +++ b/match_test.go @@ -49,7 +49,33 @@ func TestMatchers(t *testing.T) { } } -func TestExcludePrefix(t *testing.T) { +func TestExcludePrefixGlob(t *testing.T) { + m := &globMatcher{glob: "foo"} + if m.ExcludePrefix("bar") { + t.Error("m.ExcludePrefix gave true for non-inverted matcher") + } + + for _, tt := range []struct { + glob string + prefix string + want bool + }{ + {"foo", "foo", false}, + {"foo/*", "foo/bar", false}, + {"foo/**", "foo/bar/baz", false}, + {"foo/*", "foo/bar/baz", true}, + {"bar/*", "foo", true}, + {"bar", "foo", true}, + } { + m := &globMatcher{glob: tt.glob, inverse: true} + if got := m.ExcludePrefix(tt.prefix); got != tt.want { + t.Errorf("(%v).ExcludePrefix(%q): got %t; want %t", + m, tt.prefix, got, tt.want) + } + } +} + +func TestExcludePrefixRegex(t *testing.T) { m := newRegexMatcher(regexp.MustCompile("foo"), false) if m.ExcludePrefix("bar") { t.Error("m.ExcludePrefix gave true for a non-inverted matcher") From 4b25b49abd36af78e7d194726b9a33218f69154c Mon Sep 17 00:00:00 2001 From: Zbigniew Mandziejewicz Date: Sun, 12 May 2019 22:19:57 +0200 Subject: [PATCH 3/3] fix: invalid glob ExcludePrefix --- match.go | 19 +++++++++++++------ match_test.go | 12 ++++++------ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/match.go b/match.go index 46b6bfe..fdb0804 100644 --- a/match.go +++ b/match.go @@ -81,26 +81,33 @@ func (m *globMatcher) ExcludePrefix(prefix string) bool { } matches, err := doublestar.PathMatch(m.glob, prefix) - if err != nil || matches { + switch { + case err != nil: return false + case matches: + return true } var i = 0 - for { + for i != len(m.glob) { if m.glob[i] == '/' { i++ } pos := strings.Index(m.glob[i:], "/") - if pos == -1 { - return true + switch { + case pos == -1: + i = len(m.glob) + default: + i += pos } - i += pos matches, _ := doublestar.PathMatch(m.glob[:i], prefix) if matches { - return false + return true } } + + return false } func (m *globMatcher) String() string { diff --git a/match_test.go b/match_test.go index aaf4ce3..b93055a 100644 --- a/match_test.go +++ b/match_test.go @@ -60,12 +60,12 @@ func TestExcludePrefixGlob(t *testing.T) { prefix string want bool }{ - {"foo", "foo", false}, - {"foo/*", "foo/bar", false}, - {"foo/**", "foo/bar/baz", false}, - {"foo/*", "foo/bar/baz", true}, - {"bar/*", "foo", true}, - {"bar", "foo", true}, + {"foo", "foo", true}, + {"foo/*", "foo/bar", true}, + {"foo/**", "foo/bar/baz", true}, + {"foo/*", "foo/bar/baz", false}, + {"bar/*", "foo", false}, + {"bar", "foo", false}, } { m := &globMatcher{glob: tt.glob, inverse: true} if got := m.ExcludePrefix(tt.prefix); got != tt.want {