filepathfilter: handle prefix matches like '/foo'

This commit is contained in:
risk danger olson 2017-05-18 11:27:04 -06:00
parent 9ea035dfa5
commit ecf23ea343
2 changed files with 51 additions and 0 deletions

@ -100,6 +100,22 @@ func NewPattern(rawpattern string) Pattern {
}
}
if hasPathSep && strings.HasPrefix(cleanpattern, sep) {
rel := cleanpattern[1:len(cleanpattern)]
prefix := rel
if strings.HasSuffix(rel, sep) {
rel = rel[0 : len(rel)-1]
} else {
prefix += sep
}
return &pathPrefixPattern{
rawPattern: cleanpattern,
relative: rel,
prefix: prefix,
}
}
return &pathPattern{
rawPattern: cleanpattern,
prefix: cleanpattern + sep,
@ -116,6 +132,19 @@ func convertToPatterns(rawpatterns []string) []Pattern {
return patterns
}
type pathPrefixPattern struct {
rawPattern string
relative string
prefix string
}
// Match is a revised version of filepath.Match which makes it behave more
// like gitignore
func (p *pathPrefixPattern) Match(name string) bool {
matched, _ := filepath.Match(p.rawPattern, name)
return matched || name == p.relative || strings.HasPrefix(name, p.prefix)
}
type pathPattern struct {
rawPattern string
prefix string

@ -47,8 +47,18 @@ func TestPatternMatch(t *testing.T) {
assertPatternMatch(t, "sub/", "top/sub/filename.txt")
assertPatternMatch(t, "sub", "top/sub/")
assertPatternMatch(t, "sub", "top/sub")
assertPatternMatch(t, "/sub", "sub/")
assertPatternMatch(t, "/sub", "sub")
assertPatternMatch(t, "/sub", "sub/filename.txt")
assertPatternMatch(t, "/sub/", "sub/filename.txt")
refutePatternMatch(t, "/sub", "top/sub/filename.txt")
refutePatternMatch(t, "/sub/", "top/sub/filename.txt")
refutePatternMatch(t, "/sub", "top/sub/")
refutePatternMatch(t, "/sub", "top/sub")
refutePatternMatch(t, "sub", "subfilename.txt")
refutePatternMatch(t, "sub/", "subfilename.txt")
refutePatternMatch(t, "/sub", "subfilename.txt")
refutePatternMatch(t, "/sub/", "subfilename.txt")
// nested path
assertPatternMatch(t, "top/sub", "top/sub/filename.txt")
@ -59,6 +69,18 @@ func TestPatternMatch(t *testing.T) {
assertPatternMatch(t, "top/sub/", "root/top/sub/filename.txt")
assertPatternMatch(t, "top/sub", "root/top/sub/")
assertPatternMatch(t, "top/sub", "root/top/sub")
assertPatternMatch(t, "/top/sub", "top/sub/filename.txt")
assertPatternMatch(t, "/top/sub/", "top/sub/filename.txt")
assertPatternMatch(t, "/top/sub", "top/sub/")
assertPatternMatch(t, "/top/sub", "top/sub")
refutePatternMatch(t, "/top/sub", "root/top/sub/filename.txt")
refutePatternMatch(t, "/top/sub/", "root/top/sub/filename.txt")
refutePatternMatch(t, "/top/sub", "root/top/sub/")
refutePatternMatch(t, "/top/sub", "root/top/sub")
refutePatternMatch(t, "top/sub", "top/subfilename.txt")
refutePatternMatch(t, "top/sub/", "top/subfilename.txt")
refutePatternMatch(t, "/top/sub", "top/subfilename.txt")
refutePatternMatch(t, "/top/sub/", "top/subfilename.txt")
// Absolute
assertPatternMatch(t, "*.dat", "/path/to/sub/.git/test.dat")