Skip to content

Commit 9ee5241

Browse files
committed
Allow arbitrary references to be included/excluded by regexp
1 parent d8b2507 commit 9ee5241

File tree

2 files changed

+60
-13
lines changed

2 files changed

+60
-13
lines changed

git-sizer.go

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,15 @@ const Usage = `usage: git-sizer [OPTS]
4545
--remotes process remote refs
4646
--include prefix process references with the specified prefix
4747
(e.g., '--include=refs/remotes/origin')
48+
--include-regexp pattern process references matching the specified
49+
regular expression (e.g.,
50+
'--include-regexp=refs/tags/release-.*')
4851
--exclude prefix don't process references with the specified
4952
prefix (e.g., '--exclude=refs/notes')
53+
--exclude-regexp pattern don't process references matching the specified
54+
regular expression
55+
56+
Regular expression patterns must match the full reference name.
5057
5158
`
5259

@@ -82,18 +89,25 @@ func (v *NegatedBoolValue) Type() string {
8289
type filterValue struct {
8390
filter *git.IncludeExcludeFilter
8491
polarity git.Polarity
85-
prefix string
92+
pattern string
93+
regexp bool
8694
}
8795

8896
func (v *filterValue) Set(s string) error {
89-
var prefix string
9097
var polarity git.Polarity
98+
var filter git.ReferenceFilter
9199

92-
if v.prefix == "" {
93-
prefix = s
100+
if v.regexp {
94101
polarity = v.polarity
102+
var err error
103+
filter, err = git.RegexpFilter(s)
104+
if err != nil {
105+
return fmt.Errorf("invalid regexp: %q", s)
106+
}
107+
} else if v.pattern == "" {
108+
polarity = v.polarity
109+
filter = git.PrefixFilter(s)
95110
} else {
96-
prefix = v.prefix
97111
// Allow a boolean value to alter the polarity:
98112
b, err := strconv.ParseBool(s)
99113
if err != nil {
@@ -104,13 +118,14 @@ func (v *filterValue) Set(s string) error {
104118
} else {
105119
polarity = git.Exclude
106120
}
121+
filter = git.PrefixFilter(v.pattern)
107122
}
108123

109124
switch polarity {
110125
case git.Include:
111-
v.filter.Include(git.PrefixFilter(prefix))
126+
v.filter.Include(filter)
112127
case git.Exclude:
113-
v.filter.Exclude(git.PrefixFilter(prefix))
128+
v.filter.Exclude(filter)
114129
}
115130

116131
return nil
@@ -125,7 +140,9 @@ func (v *filterValue) String() string {
125140
}
126141

127142
func (v *filterValue) Type() string {
128-
if v.prefix == "" {
143+
if v.regexp {
144+
return "regexp"
145+
} else if v.pattern == "" {
129146
return "prefix"
130147
} else {
131148
return ""
@@ -155,23 +172,37 @@ func mainImplementation() error {
155172
fmt.Print(Usage)
156173
}
157174

158-
flags.Var(&filterValue{&filter, git.Include, ""}, "include", "include specified references")
159-
flags.Var(&filterValue{&filter, git.Exclude, ""}, "exclude", "exclude specified references")
175+
flags.Var(
176+
&filterValue{&filter, git.Include, "", false}, "include",
177+
"include specified references",
178+
)
179+
flags.Var(
180+
&filterValue{&filter, git.Include, "", true}, "include-regexp",
181+
"include references matching the specified regular expression",
182+
)
183+
flags.Var(
184+
&filterValue{&filter, git.Exclude, "", false}, "exclude",
185+
"exclude specified references",
186+
)
187+
flags.Var(
188+
&filterValue{&filter, git.Exclude, "", true}, "exclude-regexp",
189+
"exclude references matching the specified regular expression",
190+
)
160191

161192
flag := flags.VarPF(
162-
&filterValue{&filter, git.Include, "refs/heads/"}, "branches", "",
193+
&filterValue{&filter, git.Include, "refs/heads/", false}, "branches", "",
163194
"process all branches",
164195
)
165196
flag.NoOptDefVal = "true"
166197

167198
flag = flags.VarPF(
168-
&filterValue{&filter, git.Include, "refs/tags/"}, "tags", "",
199+
&filterValue{&filter, git.Include, "refs/tags/", false}, "tags", "",
169200
"process all tags",
170201
)
171202
flag.NoOptDefVal = "true"
172203

173204
flag = flags.VarPF(
174-
&filterValue{&filter, git.Include, "refs/remotes/"}, "remotes", "",
205+
&filterValue{&filter, git.Include, "refs/remotes/", false}, "remotes", "",
175206
"process all remotes",
176207
)
177208
flag.NoOptDefVal = "true"

git/ref_filter.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package git
22

33
import (
4+
"regexp"
45
"strings"
56
)
67

@@ -75,3 +76,18 @@ func PrefixFilter(prefix string) ReferenceFilter {
7576
(len(r.Refname) == len(prefix) || r.Refname[len(prefix)] == '/')
7677
}
7778
}
79+
80+
// RegexpFilter returns a `ReferenceFilter` that matches references
81+
// whose names match the specified `prefix`, which must match the
82+
// whole reference name.
83+
func RegexpFilter(pattern string) (ReferenceFilter, error) {
84+
pattern = "^" + pattern + "$"
85+
re, err := regexp.Compile(pattern)
86+
if err != nil {
87+
return nil, err
88+
}
89+
90+
return func(r Reference) bool {
91+
return re.MatchString(r.Refname)
92+
}, nil
93+
}

0 commit comments

Comments
 (0)