Rename Matches to MatchesOrParentMatches

Signed-off-by: Aaron Lehmann <alehmann@netflix.com>
This commit is contained in:
Aaron Lehmann 2021-08-12 18:09:12 -07:00
parent 9bae4f2f24
commit 97ede9df26
4 changed files with 68 additions and 4 deletions

View file

@ -130,7 +130,7 @@ func removeDockerfile(c modifiableContext, filesToRemove ...string) error {
f.Close()
filesToRemove = append([]string{".dockerignore"}, filesToRemove...)
for _, fileToRemove := range filesToRemove {
if rm, _ := fileutils.Matches(fileToRemove, excludes); rm {
if rm, _ := fileutils.MatchesOrParentMatches(fileToRemove, excludes); rm {
if err := c.Remove(fileToRemove); err != nil {
logrus.Errorf("failed to remove %s: %v", fileToRemove, err)
}

View file

@ -860,7 +860,7 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error)
if len(parentMatched) != 0 {
skip, err = pm.MatchesUsingParentResult(relFilePath, parentMatched[len(parentMatched)-1])
} else {
skip, err = pm.Matches(relFilePath)
skip, err = pm.MatchesOrParentMatches(relFilePath)
}
if err != nil {
logrus.Errorf("Error matching %s: %v", relFilePath, err)

View file

@ -61,12 +61,56 @@ func NewPatternMatcher(patterns []string) (*PatternMatcher, error) {
// The "file" argument should be a slash-delimited path.
//
// Matches is not safe to call concurrently.
//
// This implementation is buggy (it only checks a single parent dir against the
// pattern) and will be removed soon. Use either MatchesOrParentMatches or
// MatchesUsingParentResult instead.
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))
for _, pattern := range pm.patterns {
// Skip evaluation if this is an inclusion and the filename
// already matched the pattern, or it's an exclusion and it has
// not matched the pattern yet.
if pattern.exclusion != matched {
continue
}
match, err := pattern.match(file)
if err != nil {
return false, 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 {
matched = !pattern.exclusion
}
}
return matched, nil
}
// MatchesOrParentMatches returns true if "file" matches any of the patterns
// and isn't excluded by any of the subsequent patterns.
//
// The "file" argument should be a slash-delimited path.
//
// Matches is not safe to call concurrently.
func (pm *PatternMatcher) MatchesOrParentMatches(file string) (bool, error) {
matched := false
file = filepath.FromSlash(file)
parentPath := filepath.Dir(file)
parentPathDirs := strings.Split(parentPath, string(os.PathSeparator))
for _, pattern := range pm.patterns {
// Skip evaluation if this is an inclusion and the filename
// already matched the pattern, or it's an exclusion and it has
@ -249,6 +293,9 @@ func (p *Pattern) compile() error {
// Matches returns true if file matches any of the patterns
// and isn't excluded by any of the subsequent patterns.
//
// This implementation is buggy (it only checks a single parent dir against the
// pattern) and will be removed soon. Use MatchesOrParentMatches instead.
func Matches(file string, patterns []string) (bool, error) {
pm, err := NewPatternMatcher(patterns)
if err != nil {
@ -264,6 +311,23 @@ func Matches(file string, patterns []string) (bool, error) {
return pm.Matches(file)
}
// MatchesOrParentMatches returns true if file matches any of the patterns
// and isn't excluded by any of the subsequent patterns.
func MatchesOrParentMatches(file string, patterns []string) (bool, error) {
pm, err := NewPatternMatcher(patterns)
if err != nil {
return false, err
}
file = filepath.Clean(file)
if file == "." {
// Don't let them exclude everything, kind of silly.
return false, nil
}
return pm.MatchesOrParentMatches(file)
}
// CopyFile copies from src to dst until either EOF is reached
// on src or an error occurs. It verifies src exists and removes
// the dst if it exists.

View file

@ -382,12 +382,12 @@ func TestMatches(t *testing.T) {
}...)
}
t.Run("Matches", func(t *testing.T) {
t.Run("MatchesOrParentMatches", func(t *testing.T) {
for _, test := range tests {
desc := fmt.Sprintf("pattern=%q text=%q", test.pattern, test.text)
pm, err := NewPatternMatcher([]string{test.pattern})
assert.NilError(t, err, desc)
res, _ := pm.Matches(test.text)
res, _ := pm.MatchesOrParentMatches(test.text)
assert.Check(t, is.Equal(test.pass, res), desc)
}
})