Add indicator for last matched result
This information is needed as well if we want to match in a way that the last match has the highest priority. We now introduce a new method `MatchesResult` to not break the previous API. Signed-off-by: Sascha Grunert <sgrunert@suse.com>
This commit is contained in:
parent
01ea27db51
commit
5e07044cf0
|
|
@ -57,11 +57,11 @@ func NewPatternMatcher(patterns []string) (*PatternMatcher, error) {
|
|||
return pm, nil
|
||||
}
|
||||
|
||||
// Matches verifies the provided filepath against all patterns.
|
||||
// It returns the amount of `matches` and `excludes` for the patterns on
|
||||
// success, otherwise an error.
|
||||
// It is not safe to be called concurrently.
|
||||
func (pm *PatternMatcher) Matches(file string) (matches, excludes uint, err error) {
|
||||
// Deprecated: Please use the `MatchesResult` method instead.
|
||||
// Matches matches path against all the patterns. Matches is not safe to be
|
||||
// called concurrently
|
||||
func (pm *PatternMatcher) Matches(file string) (bool, error) {
|
||||
matched := false
|
||||
file = filepath.FromSlash(file)
|
||||
parentPath := filepath.Dir(file)
|
||||
parentPathDirs := strings.Split(parentPath, string(os.PathSeparator))
|
||||
|
|
@ -75,7 +75,7 @@ func (pm *PatternMatcher) Matches(file string) (matches, excludes uint, err erro
|
|||
|
||||
match, err := pattern.match(file)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
return false, err
|
||||
}
|
||||
|
||||
if !match && parentPath != "." {
|
||||
|
|
@ -86,35 +86,94 @@ func (pm *PatternMatcher) Matches(file string) (matches, excludes uint, err erro
|
|||
}
|
||||
|
||||
if match {
|
||||
matched = !negative
|
||||
}
|
||||
}
|
||||
|
||||
if matched {
|
||||
logrus.Debugf("Skipping excluded path: %s", file)
|
||||
}
|
||||
|
||||
return matched, nil
|
||||
}
|
||||
|
||||
type MatchResult struct {
|
||||
isMatched bool
|
||||
matches, excludes uint
|
||||
}
|
||||
|
||||
// Excludes returns true if the overall result is matched
|
||||
func (m *MatchResult) IsMatched() bool {
|
||||
return m.isMatched
|
||||
}
|
||||
|
||||
// Excludes returns the amount of matches of an MatchResult
|
||||
func (m *MatchResult) Matches() uint {
|
||||
return m.matches
|
||||
}
|
||||
|
||||
// Excludes returns the amount of excludes of an MatchResult
|
||||
func (m *MatchResult) Excludes() uint {
|
||||
return m.excludes
|
||||
}
|
||||
|
||||
// MatchesResult verifies the provided filepath against all patterns.
|
||||
// It returns the `*MatchResult` result for the patterns on success, otherwise
|
||||
// an error. This method is not safe to be called concurrently.
|
||||
func (pm *PatternMatcher) MatchesResult(file string) (res *MatchResult, err error) {
|
||||
file = filepath.FromSlash(file)
|
||||
parentPath := filepath.Dir(file)
|
||||
parentPathDirs := strings.Split(parentPath, string(os.PathSeparator))
|
||||
res = &MatchResult{false, 0, 0}
|
||||
|
||||
for _, pattern := range pm.patterns {
|
||||
negative := false
|
||||
|
||||
if pattern.exclusion {
|
||||
negative = true
|
||||
}
|
||||
|
||||
match, err := pattern.match(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !match && parentPath != "." {
|
||||
// Check to see if the pattern matches one of our parent dirs.
|
||||
if len(pattern.dirs) <= len(parentPathDirs) {
|
||||
match, _ = pattern.match(strings.Join(
|
||||
parentPathDirs[:len(pattern.dirs)],
|
||||
string(os.PathSeparator)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if match {
|
||||
res.isMatched = !negative
|
||||
if negative {
|
||||
excludes++
|
||||
res.excludes++
|
||||
} else {
|
||||
matches++
|
||||
res.matches++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if matches > 0 {
|
||||
if res.matches > 0 {
|
||||
logrus.Debugf("Skipping excluded path: %s", file)
|
||||
}
|
||||
|
||||
return matches, excludes, nil
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// IsMatch verifies the provided filepath against all patterns and returns true
|
||||
// if it matches. A match is valid if the amount of positive matches is larger
|
||||
// than the negative (excludes) ones.
|
||||
// if it matches. A match is valid if the last match is a positive one.
|
||||
// It returns an error on failure and is not safe to be called concurrently.
|
||||
func (pm *PatternMatcher) IsMatch(file string) (matched bool, err error) {
|
||||
matches, excludes, err := pm.Matches(file)
|
||||
res, err := pm.MatchesResult(file)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if matches > excludes && matches-excludes > 0 {
|
||||
matched = true
|
||||
}
|
||||
return matched, nil
|
||||
return res.isMatched, nil
|
||||
}
|
||||
|
||||
// Exclusions returns true if any of the patterns define exclusions
|
||||
|
|
|
|||
|
|
@ -225,11 +225,11 @@ func TestPatternMatches(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// An exclusion followed by an inclusion should return true.
|
||||
// An exclusion followed by an inclusion should return false.
|
||||
func TestExclusionPatternMatchesPatternBefore(t *testing.T) {
|
||||
match, _ := Matches("fileutils.go", []string{"!fileutils.go", "*.go"})
|
||||
if match {
|
||||
t.Errorf("failed to get true match on exclusion pattern, got %v", match)
|
||||
if !match {
|
||||
t.Errorf("failed to get false match on exclusion pattern, got %v", match)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -385,8 +385,9 @@ func TestMatches(t *testing.T) {
|
|||
desc := fmt.Sprintf("pattern=%q text=%q", test.pattern, test.text)
|
||||
pm, err := NewPatternMatcher([]string{test.pattern})
|
||||
require.NoError(t, err, desc)
|
||||
res, _, _ := pm.Matches(test.text)
|
||||
assert.Equal(t, test.pass, res > 0, desc)
|
||||
res, err := pm.MatchesResult(test.text)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, test.pass, res.isMatched, desc)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -611,11 +612,12 @@ func TestMatchesAmount(t *testing.T) {
|
|||
for _, testCase := range testData {
|
||||
pm, err := NewPatternMatcher(testCase.patterns)
|
||||
require.NoError(t, err)
|
||||
matches, excludes, err := pm.Matches(testCase.input)
|
||||
res, err := pm.MatchesResult(testCase.input)
|
||||
require.NoError(t, err)
|
||||
desc := fmt.Sprintf("pattern=%q input=%q", testCase.patterns, testCase.input)
|
||||
assert.Equal(t, testCase.excludes, excludes, desc)
|
||||
assert.Equal(t, testCase.matches, matches, desc)
|
||||
assert.Equal(t, testCase.excludes, res.Excludes(), desc)
|
||||
assert.Equal(t, testCase.matches, res.Matches(), desc)
|
||||
assert.Equal(t, testCase.isMatch, res.IsMatched(), desc)
|
||||
|
||||
isMatch, err := pm.IsMatch(testCase.input)
|
||||
assert.Equal(t, testCase.isMatch, isMatch, desc)
|
||||
|
|
|
|||
Loading…
Reference in New Issue