Skip to content

Commit 9183d98

Browse files
committed
IncludeExcludeFilter: new way of selecting references
1 parent 09554d3 commit 9183d98

File tree

2 files changed

+52
-64
lines changed

2 files changed

+52
-64
lines changed

git-sizer.go

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -155,24 +155,20 @@ func mainImplementation() error {
155155

156156
var historySize sizes.HistorySize
157157

158-
var filter git.ReferenceFilter
158+
var filter git.IncludeExcludeFilter
159159
if processBranches || processTags || processRemotes {
160-
var filters []git.ReferenceFilter
161160
if processBranches {
162-
filters = append(filters, git.BranchesFilter)
161+
filter.Include(git.BranchesFilter)
163162
}
164163
if processTags {
165-
filters = append(filters, git.TagsFilter)
164+
filter.Include(git.TagsFilter)
166165
}
167166
if processRemotes {
168-
filters = append(filters, git.RemotesFilter)
167+
filter.Include(git.RemotesFilter)
169168
}
170-
filter = git.OrFilter(filters...)
171-
} else {
172-
filter = git.AllReferencesFilter
173169
}
174170

175-
historySize, err = sizes.ScanRepositoryUsingGraph(repo, filter, nameStyle, progress)
171+
historySize, err = sizes.ScanRepositoryUsingGraph(repo, filter.Filter, nameStyle, progress)
176172
if err != nil {
177173
return fmt.Errorf("error scanning repository: %s", err)
178174
}

git/ref_filter.go

Lines changed: 47 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,50 @@ func AllReferencesFilter(_ Reference) bool {
1010
return true
1111
}
1212

13+
type Polarity uint8
14+
15+
const (
16+
Include Polarity = iota
17+
Exclude
18+
)
19+
20+
// polarizedFilter is a filter that might match, in which case it
21+
// includes or excludes the reference (according to its polarity). If
22+
// it doesn't match, then it doesn't say anything about the reference.
23+
type polarizedFilter struct {
24+
polarity Polarity
25+
filter ReferenceFilter
26+
}
27+
28+
// IncludeExcludeFilter is a filter based on a bunch of
29+
// `polarizedFilter`s. The last one that matches a reference wins. If
30+
// none match, then the result is based on the polarity of the first
31+
// polarizedFilter: if it is `Include`, then return `false`; if it is
32+
// `Exclude`, then return `true`.
33+
type IncludeExcludeFilter struct {
34+
filters []polarizedFilter
35+
}
36+
37+
func (ief *IncludeExcludeFilter) Include(f ReferenceFilter) {
38+
ief.filters = append(ief.filters, polarizedFilter{Include, f})
39+
}
40+
41+
func (ief *IncludeExcludeFilter) Exclude(f ReferenceFilter) {
42+
ief.filters = append(ief.filters, polarizedFilter{Exclude, f})
43+
}
44+
45+
func (ief *IncludeExcludeFilter) Filter(r Reference) bool {
46+
for i := len(ief.filters); i > 0; i-- {
47+
f := ief.filters[i-1]
48+
if !f.filter(r) {
49+
continue
50+
}
51+
return f.polarity == Include
52+
}
53+
54+
return len(ief.filters) == 0 || ief.filters[0].polarity == Exclude
55+
}
56+
1357
// PrefixFilter returns a `ReferenceFilter` that matches references
1458
// whose names start with the specified `prefix`, which must match at
1559
// a component boundary. For example,
@@ -33,59 +77,7 @@ func PrefixFilter(prefix string) ReferenceFilter {
3377
}
3478

3579
var (
36-
BranchesFilter ReferenceFilter = PrefixFilter("refs/heads/")
37-
TagsFilter ReferenceFilter = PrefixFilter("refs/tags/")
38-
RemotesFilter ReferenceFilter = PrefixFilter("refs/remotes/")
80+
BranchesFilter = PrefixFilter("refs/heads/")
81+
TagsFilter = PrefixFilter("refs/tags/")
82+
RemotesFilter = PrefixFilter("refs/remotes/")
3983
)
40-
41-
func notNilFilters(filters ...ReferenceFilter) []ReferenceFilter {
42-
var ret []ReferenceFilter
43-
for _, filter := range filters {
44-
if filter != nil {
45-
ret = append(ret, filter)
46-
}
47-
}
48-
return ret
49-
}
50-
51-
func OrFilter(filters ...ReferenceFilter) ReferenceFilter {
52-
filters = notNilFilters(filters...)
53-
if len(filters) == 0 {
54-
return AllReferencesFilter
55-
} else if len(filters) == 1 {
56-
return filters[0]
57-
} else {
58-
return func(r Reference) bool {
59-
for _, filter := range filters {
60-
if filter(r) {
61-
return true
62-
}
63-
}
64-
return false
65-
}
66-
}
67-
}
68-
69-
func AndFilter(filters ...ReferenceFilter) ReferenceFilter {
70-
filters = notNilFilters(filters...)
71-
if len(filters) == 0 {
72-
return AllReferencesFilter
73-
} else if len(filters) == 1 {
74-
return filters[0]
75-
} else {
76-
return func(r Reference) bool {
77-
for _, filter := range filters {
78-
if !filter(r) {
79-
return false
80-
}
81-
}
82-
return true
83-
}
84-
}
85-
}
86-
87-
func NotFilter(filter ReferenceFilter) ReferenceFilter {
88-
return func(r Reference) bool {
89-
return !filter(r)
90-
}
91-
}

0 commit comments

Comments
 (0)