-
Notifications
You must be signed in to change notification settings - Fork 115
/
regexpchangematcher.go
107 lines (94 loc) · 3.44 KB
/
regexpchangematcher.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package job
import (
"fmt"
"regexp"
)
// RegexpChangeMatcher is for code shared between jobs that run only when certain files are changed.
type RegexpChangeMatcher struct {
// RunIfChanged defines a regex used to select which subset of file changes should trigger this job.
// If any file in the changeset matches this regex, the job will be triggered
RunIfChanged string `json:"run_if_changed,omitempty"`
// IgnoreChanges defines a regex used to select which file changes should be ignored
IgnoreChanges string `json:"ignore_changes,omitempty"`
reChanges *regexp.Regexp // from RunIfChanged
reIgnoreChanges *regexp.Regexp // from IgnoreChanges
}
// CouldRun determines if its possible for a set of changes to trigger this condition
func (cm RegexpChangeMatcher) CouldRun() bool {
return cm.RunIfChanged != "" || cm.IgnoreChanges != ""
}
// ShouldRun determines if we can know for certain that the job should run. We can either
// know for certain that the job should or should not run based on the matcher, or we can
// not be able to determine that fact at all.
func (cm RegexpChangeMatcher) ShouldRun(changes ChangedFilesProvider) (determined bool, shouldRun bool, err error) {
if cm.CouldRun() {
changeList, err := changes()
if err != nil {
return true, false, err
}
return true, cm.RunsAgainstChanges(changeList), nil
}
return false, false, nil
}
// RunsAgainstChanges returns true if any of the changed input paths match the run_if_changed regex.
func (cm RegexpChangeMatcher) RunsAgainstChanges(changes []string) bool {
for _, change := range changes {
if cm.IgnoreChanges != "" && cm.GetIgnoreRE().MatchString(change) {
continue
}
if cm.RunIfChanged == "" || cm.GetRE().MatchString(change) {
return true
}
}
return false
}
// SetChangeRegexes validates and compiles internal regexes
func (cm RegexpChangeMatcher) SetChangeRegexes() (RegexpChangeMatcher, error) {
if cm.RunIfChanged != "" {
re, err := regexp.Compile(cm.RunIfChanged)
if err != nil {
return cm, fmt.Errorf("could not compile run_if_changed regex: %v", err)
}
cm.reChanges = re
}
return cm, nil
}
// SetChangeRegexes validates and compiles internal regexes
func (cm RegexpChangeMatcher) SetIgnoreChangeRegexes() (RegexpChangeMatcher, error) {
if cm.IgnoreChanges != "" {
re, err := regexp.Compile(cm.IgnoreChanges)
if err != nil {
return cm, fmt.Errorf("could not compile ignore_changes regex: %v", err)
}
cm.reIgnoreChanges = re
}
return cm, nil
}
// GetRE lazily creates the regex
func (cm RegexpChangeMatcher) GetRE() *regexp.Regexp {
if cm.reChanges == nil {
cm2, _ := cm.SetChangeRegexes()
return cm2.reChanges
}
return cm.reChanges
}
// GetIgnoreRE lazily creates the regex
func (cm RegexpChangeMatcher) GetIgnoreRE() *regexp.Regexp {
if cm.reIgnoreChanges == nil {
cm2, _ := cm.SetIgnoreChangeRegexes()
return cm2.reIgnoreChanges
}
return cm.reIgnoreChanges
}