[helmignore] Support for '!' as a special leading sequence

.helmignore has "supported" negative matches uselessly for a long time, reported as an open ticket (https://github.com/helm/helm/issues/3622) as early as 2018. This revision implements negative matching correctly and usefully for the first time.

Signed-off-by: Talia Stocks <tstocks@hioscar.com>
pull/10293/head
Talia Stocks 4 years ago committed by Talia Stocks
parent dc912094b3
commit 04d3dbf2dd

@ -62,6 +62,5 @@ Notable differences from .gitignore:
- The globbing library is Go's 'filepath.Match', not fnmatch(3) - The globbing library is Go's 'filepath.Match', not fnmatch(3)
- Trailing spaces are always ignored (there is no supported escape sequence) - Trailing spaces are always ignored (there is no supported escape sequence)
- The evaluation of escape sequences has not been tested for compatibility - The evaluation of escape sequences has not been tested for compatibility
- There is no support for '\!' as a special leading sequence.
*/ */
package ignore // import "helm.sh/helm/v3/internal/ignore" package ignore // import "helm.sh/helm/v3/internal/ignore"

@ -100,22 +100,30 @@ func (r *Rules) Ignore(path string, fi os.FileInfo) bool {
if path == "." || path == "./" { if path == "." || path == "./" {
return false return false
} }
// Negative rules should only override positive ignore rules, rather
// than exclude everything aside from the pattern (e.g. Chart.yaml).
// See issue:
// 3622 Whitelisting in .helmignore with '/*' returns "chart metadata (Chart.yaml) missing"
positiveMatch := false
negativeMatch := false
for _, p := range r.patterns { for _, p := range r.patterns {
if p.match == nil { if p.match == nil {
log.Printf("ignore: no matcher supplied for %q", p.raw) log.Printf("ignore: no matcher supplied for %q", p.raw)
return false return false
} }
// For negative rules, we need to capture and return non-matches, // For negative rules, we need to continue for non-matches,
// and continue for matches. // and record matches.
if p.negate { if p.negate {
if p.mustDir && !fi.IsDir() { if p.mustDir && !fi.IsDir() {
return true continue
} }
if !p.match(path, fi) { if !p.match(path, fi) {
return true continue
} }
continue negativeMatch = true
} }
// If the rule is looking for directories, and this is not a directory, // If the rule is looking for directories, and this is not a directory,
@ -124,10 +132,11 @@ func (r *Rules) Ignore(path string, fi os.FileInfo) bool {
continue continue
} }
if p.match(path, fi) { if p.match(path, fi) {
return true positiveMatch = true
} }
} }
return false
return positiveMatch && !negativeMatch
} }
// parseRule parses a rule string and creates a pattern, which is then stored in the Rules object. // parseRule parses a rule string and creates a pattern, which is then stored in the Rules object.

Loading…
Cancel
Save