aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.adoc5
-rw-r--r--lib/git/gitignore.go14
-rw-r--r--lib/git/ignore_pattern.go14
-rw-r--r--lib/git/ignore_pattern_test.go48
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)