@@ -10,6 +10,50 @@ func AllReferencesFilter(_ Reference) bool {
10
10
return true
11
11
}
12
12
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
+
13
57
// PrefixFilter returns a `ReferenceFilter` that matches references
14
58
// whose names start with the specified `prefix`, which must match at
15
59
// a component boundary. For example,
@@ -33,59 +77,7 @@ func PrefixFilter(prefix string) ReferenceFilter {
33
77
}
34
78
35
79
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/" )
39
83
)
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