diff --git a/gitrepo/gitrepo.go b/gitrepo/gitrepo.go index c35b4e2..42edd3e 100644 --- a/gitrepo/gitrepo.go +++ b/gitrepo/gitrepo.go @@ -190,16 +190,17 @@ func (repo GitRepo) CheckIfFileExists(fileName string) bool { // Matches states whether the addition matches the given pattern. // If the pattern ends in a path separator, then all files inside a directory with that name are matched. However, files with that name itself will not be matched. // If a pattern contains the path separator in any other location, the match works according to the pattern logic of the default golang glob mechanism -// If there is no path separator anywhere in the pattern, the pattern is matched against the base name of the file. Thus, the pattern will match files with that name anywhere in the repository. +// If there are other special characters in the pattern, the pattern is matched against the base name of the file. Thus, the pattern will match files with that pattern anywhere in the repository. +// If there are no special characters in the pattern, then it means exact filename is provided as pattern like file.txt. Thus, the pattern is matched against the file path so that not all files with the same name in the repo are not returned. func (a Addition) Matches(pattern string) bool { var result bool - if pattern[len(pattern)-1] == '/' { + if pattern[len(pattern)-1] == '/' { // If the pattern ends in a path separator, then all files inside a directory with that name are matched. However, files with that name itself will not be matched. result = strings.HasPrefix(string(a.Path), pattern) - } else if strings.ContainsRune(pattern, '/') { + } else if strings.ContainsRune(pattern, '/') { // If a pattern contains the path separator in any other location, the match works according to the pattern logic of the default golang glob mechanism result, _ = path.Match(pattern, string(a.Path)) - } else if strings.ContainsRune(pattern, '*') { + } else if strings.ContainsAny(pattern, "*?[]\\") { // If there are other special characters in the pattern, the pattern is matched against the base name of the file. Thus, the pattern will match files with that pattern anywhere in the repository. result, _ = path.Match(pattern, string(a.Name)) - } else { + } else { // If there are no special characters in the pattern, then it means exact filename is provided as pattern like file.txt. Thus, the pattern is matched against the file path so that not all files with the same name in the repo are not returned. result = strings.Compare(string(a.Path), pattern) == 0 } log.WithFields(log.Fields{ diff --git a/gitrepo/gitrepo_test.go b/gitrepo/gitrepo_test.go index 19d5256..deac2ba 100644 --- a/gitrepo/gitrepo_test.go +++ b/gitrepo/gitrepo_test.go @@ -232,6 +232,8 @@ func TestMatchShouldAllowStarPattern(t *testing.T) { file3 := Addition{Path: "GitRepoPath1/somefile", Name: "somefile"} file4 := Addition{Path: "somefile.jpg", Name: "somefile.jpg"} file5 := Addition{Path: "somefile.txt", Name: "somefile.txt"} + file6 := Addition{Path: "File1.txt", Name: "File1.txt"} + file7 := Addition{Path: "File3.txt", Name: "File3.txt"} pattern := "GitRepoPath1/*.txt" @@ -247,6 +249,26 @@ func TestMatchShouldAllowStarPattern(t *testing.T) { assert.False(t, file3.Matches(pattern1)) assert.False(t, file4.Matches(pattern1)) assert.True(t, file5.Matches(pattern1)) + + pattern2 := "File?.txt" + assert.True(t, file1.Matches(pattern2)) + assert.True(t, file2.Matches(pattern2)) + assert.True(t, file6.Matches(pattern2)) + + pattern3 := "File[1].txt" + assert.True(t, file1.Matches(pattern3)) + assert.False(t, file2.Matches(pattern3)) + assert.True(t, file6.Matches(pattern3)) + + pattern4 := "File[1-2].txt" + assert.True(t, file1.Matches(pattern4)) + assert.True(t, file2.Matches(pattern4)) + assert.True(t, file6.Matches(pattern4)) + assert.False(t, file7.Matches(pattern4)) + + pattern5 := "File\\1.txt" + assert.True(t, file1.Matches(pattern5)) + assert.True(t, file6.Matches(pattern5)) } func setupOriginAndClones(originLocation, cloneLocation string) (*git_testing.GitTesting, GitRepo) {