diff options
| -rw-r--r-- | CHANGELOG.adoc | 5 | ||||
| -rw-r--r-- | lib/git/gitignore.go | 14 | ||||
| -rw-r--r-- | lib/git/ignore_pattern.go | 14 | ||||
| -rw-r--r-- | lib/git/ignore_pattern_test.go | 48 |
4 files changed, 45 insertions, 36 deletions
diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 2d640a1a..297a1e8e 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -55,6 +55,11 @@ This method accept second paramter "format", default to '%h,%at,%an,%ae,%s' which print short hash, author commit timestamp, author name, author email, and subject; respectively separated by comma. +**🌱 lib/git: expose the API for IgnorePattern** + +The IgnorePattern is not exclusive to git only. Some program, like +REUSE, use the same pattern in the REUSE.toml path configuration. + //}}} //{{{ [#v0_60_2] diff --git a/lib/git/gitignore.go b/lib/git/gitignore.go index e9313cd0..370ad6e6 100644 --- a/lib/git/gitignore.go +++ b/lib/git/gitignore.go @@ -23,11 +23,11 @@ type Gitignore struct { // excludePatterns contains list of excluded pattern from // ".gitignore" file. - excludePatterns []ignorePattern + excludePatterns []IgnorePattern // includePatterns contains list of include pattern, the one that // start with "!". - includePatterns []ignorePattern + includePatterns []IgnorePattern } // LoadGitignore load the gitignore file inside directory `dir`. @@ -62,8 +62,8 @@ func (ign *Gitignore) Parse(dir string, content []byte) { var lines = bytes.Split(content, []byte{'\n'}) var line []byte for _, line = range lines { - var pat ignorePattern - pat = parsePattern(line) + var pat IgnorePattern + pat = ParseIgnorePattern(line) if pat.pattern == nil { // Skip invalid pattern. continue @@ -91,14 +91,14 @@ func (ign *Gitignore) IsIgnored(path string) bool { path += "/" } } - var pat ignorePattern + var pat IgnorePattern for _, pat = range ign.includePatterns { - if pat.isMatch(path) { + if pat.IsMatch(path) { return false } } for _, pat = range ign.excludePatterns { - if pat.isMatch(path) { + if pat.IsMatch(path) { return true } } diff --git a/lib/git/ignore_pattern.go b/lib/git/ignore_pattern.go index 0fe161c9..37fc7035 100644 --- a/lib/git/ignore_pattern.go +++ b/lib/git/ignore_pattern.go @@ -9,16 +9,19 @@ import ( "regexp" ) -type ignorePattern struct { +// IgnorePattern is a type that store the parsed ignore pattern line from +// gitignore file. +type IgnorePattern struct { pattern *regexp.Regexp isDir bool // True if pattern end with '/'. isNegate bool // True if pattern start with '!'. } -// parsePattern parse the line from gitignore. +// ParseIgnorePattern parse the line from gitignore. // At this point, the line must be not empty and not a comment. -// If the pattern is invalid it return with nil [Gitignore.pattern]. -func parsePattern(line []byte) (ign ignorePattern) { +// If the pattern is invalid it will be ignored and [IsMatch] will always +// return false. +func ParseIgnorePattern(line []byte) (ign IgnorePattern) { line = bytes.TrimSpace(line) if len(line) == 0 { // Skip empty line. @@ -142,7 +145,8 @@ func removeComment(line []byte) []byte { return bytes.TrimSpace(line[:x]) } -func (pat *ignorePattern) isMatch(path string) bool { +// IsMatch return true if the `path` match with the pattern. +func (pat *IgnorePattern) IsMatch(path string) bool { if pat.pattern.MatchString(path) { return true } diff --git a/lib/git/ignore_pattern_test.go b/lib/git/ignore_pattern_test.go index ad1aeea7..c90620ba 100644 --- a/lib/git/ignore_pattern_test.go +++ b/lib/git/ignore_pattern_test.go @@ -10,113 +10,113 @@ import ( "git.sr.ht/~shulhan/pakakeh.go/lib/test" ) -func TestParsePattern(t *testing.T) { +func TestParseIgnorePattern(t *testing.T) { type testCase struct { pattern string - exp ignorePattern + exp IgnorePattern } var listCase = []testCase{{ pattern: `#`, - exp: ignorePattern{ + exp: IgnorePattern{ pattern: nil, }, }, { pattern: `a #`, - exp: ignorePattern{ + exp: IgnorePattern{ pattern: regexp.MustCompile(`^(.*/|/)?a/?$`), }, }, { pattern: `a \#`, - exp: ignorePattern{ + exp: IgnorePattern{ pattern: regexp.MustCompile(`^(.*/|/)?a \#/?$`), }, }, { pattern: `?`, - exp: ignorePattern{ + exp: IgnorePattern{ pattern: regexp.MustCompile(`^(.*/|/)?[^/]/?$`), }, }, { pattern: `!a`, - exp: ignorePattern{ + exp: IgnorePattern{ pattern: regexp.MustCompile(`^(.*/|/)?a/?$`), isNegate: true, }, }, { pattern: `*`, - exp: ignorePattern{ + exp: IgnorePattern{ pattern: regexp.MustCompile(`^/?.*$`), }, }, { pattern: `*/`, - exp: ignorePattern{ + exp: IgnorePattern{ pattern: regexp.MustCompile(`^/?.*$`), isDir: true, }, }, { pattern: `**`, - exp: ignorePattern{ + exp: IgnorePattern{ pattern: regexp.MustCompile(`^/?.*$`), }, }, { pattern: `***`, - exp: ignorePattern{ + exp: IgnorePattern{ pattern: regexp.MustCompile(`^/?.*$`), }, }, { pattern: `**/**`, - exp: ignorePattern{ + exp: IgnorePattern{ pattern: regexp.MustCompile(`^/?.*$`), }, }, { pattern: `**/**/`, - exp: ignorePattern{ + exp: IgnorePattern{ pattern: regexp.MustCompile(`^/?.*$`), isDir: true, }, }, { pattern: `**/**foo`, - exp: ignorePattern{ + exp: IgnorePattern{ pattern: regexp.MustCompile(`^(.*/|/)?[^/]*foo/?$`), }, }, { pattern: `foo`, - exp: ignorePattern{ + exp: IgnorePattern{ pattern: regexp.MustCompile(`^(.*/|/)?foo/?$`), }, }, { pattern: `foo/`, - exp: ignorePattern{ + exp: IgnorePattern{ pattern: regexp.MustCompile(`^(.*/|/)?foo/$`), isDir: true, }, }, { pattern: `/foo`, - exp: ignorePattern{ + exp: IgnorePattern{ pattern: regexp.MustCompile(`^/?foo/?$`), }, }, { pattern: `foo/**/bar`, - exp: ignorePattern{ + exp: IgnorePattern{ pattern: regexp.MustCompile(`^/?foo(/.*)?/bar/?$`), }, }, { pattern: `a+b|c`, - exp: ignorePattern{ + exp: IgnorePattern{ pattern: regexp.MustCompile(`^(.*/|/)?a\+b\|c/?$`), }, }, { pattern: `(a|b)`, - exp: ignorePattern{ + exp: IgnorePattern{ pattern: regexp.MustCompile(`^(.*/|/)?\(a\|b\)/?$`), }, }} for _, tc := range listCase { - var got = parsePattern([]byte(tc.pattern)) + var got = ParseIgnorePattern([]byte(tc.pattern)) test.Assert(t, tc.pattern, tc.exp, got) } } -func TestIgnorePattern_isMatch(t *testing.T) { +func TestIgnorePattern_IsMatch(t *testing.T) { type testCase struct { listCase map[string]bool pattern string @@ -281,9 +281,9 @@ func TestIgnorePattern_isMatch(t *testing.T) { }, }} for _, tc := range listCase { - var pat = parsePattern([]byte(tc.pattern)) + var pat = ParseIgnorePattern([]byte(tc.pattern)) for name, exp := range tc.listCase { - var got = pat.isMatch(name) + var got = pat.IsMatch(name) if exp != got { t.Fatalf("%q: on %q want %t, got %t", tc.pattern, name, exp, got) |
