aboutsummaryrefslogtreecommitdiff
path: root/test/tools/vendor/github.com/vbatts/git-validation/validate
diff options
context:
space:
mode:
Diffstat (limited to 'test/tools/vendor/github.com/vbatts/git-validation/validate')
-rw-r--r--test/tools/vendor/github.com/vbatts/git-validation/validate/rules.go134
-rw-r--r--test/tools/vendor/github.com/vbatts/git-validation/validate/runner.go109
2 files changed, 243 insertions, 0 deletions
diff --git a/test/tools/vendor/github.com/vbatts/git-validation/validate/rules.go b/test/tools/vendor/github.com/vbatts/git-validation/validate/rules.go
new file mode 100644
index 000000000..38126a4f0
--- /dev/null
+++ b/test/tools/vendor/github.com/vbatts/git-validation/validate/rules.go
@@ -0,0 +1,134 @@
+package validate
+
+import (
+ "sort"
+ "strings"
+ "sync"
+
+ "github.com/vbatts/git-validation/git"
+)
+
+var (
+ // RegisteredRules are the avaible validation to perform on git commits
+ RegisteredRules = []Rule{}
+ registerRuleLock = sync.Mutex{}
+)
+
+// RegisterRule includes the Rule in the avaible set to use
+func RegisterRule(vr Rule) {
+ registerRuleLock.Lock()
+ defer registerRuleLock.Unlock()
+ RegisteredRules = append(RegisteredRules, vr)
+}
+
+// Rule will operate over a provided git.CommitEntry, and return a result.
+type Rule struct {
+ Name string // short name for reference in in the `-run=...` flag
+ Value string // value to configure for the rule (i.e. a regexp to check for in the commit message)
+ Description string // longer Description for readability
+ Run func(Rule, git.CommitEntry) Result
+ Default bool // whether the registered rule is run by default
+}
+
+// Commit processes the given rules on the provided commit, and returns the result set.
+func Commit(c git.CommitEntry, rules []Rule) Results {
+ results := Results{}
+ for _, r := range rules {
+ results = append(results, r.Run(r, c))
+ }
+ return results
+}
+
+// Result is the result for a single validation of a commit.
+type Result struct {
+ CommitEntry git.CommitEntry
+ Pass bool
+ Msg string
+}
+
+// Results is a set of results. This is type makes it easy for the following function.
+type Results []Result
+
+// PassFail gives a quick over/under of passes and failures of the results in this set
+func (vr Results) PassFail() (pass int, fail int) {
+ for _, res := range vr {
+ if res.Pass {
+ pass++
+ } else {
+ fail++
+ }
+ }
+ return pass, fail
+}
+
+// SanitizeFilters takes a comma delimited list and returns the trimmend and
+// split (on ",") items in the list
+func SanitizeFilters(filtStr string) (filters []string) {
+ for _, item := range strings.Split(filtStr, ",") {
+ filters = append(filters, strings.TrimSpace(item))
+ }
+ return
+}
+
+// FilterRules takes a set of rules and a list of short names to include, and
+// returns the reduced set. The comparison is case insensitive.
+//
+// Some `includes` rules have values assigned to them.
+// i.e. -run "dco,message_regexp='^JIRA-[0-9]+ [A-Z].*$'"
+//
+func FilterRules(rules []Rule, includes []string) []Rule {
+ ret := []Rule{}
+
+ for _, r := range rules {
+ for i := range includes {
+ if strings.Contains(includes[i], "=") {
+ chunks := strings.SplitN(includes[i], "=", 2)
+ if strings.ToLower(r.Name) == strings.ToLower(chunks[0]) {
+ // for these rules, the Name won't be unique per se. There may be
+ // multiple "regexp=" with different values. We'll need to set the
+ // .Value = chunk[1] and ensure r is dup'ed so they don't clobber
+ // each other.
+ newR := Rule(r)
+ newR.Value = chunks[1]
+ ret = append(ret, newR)
+ }
+ } else {
+ if strings.ToLower(r.Name) == strings.ToLower(includes[i]) {
+ ret = append(ret, r)
+ }
+ }
+ }
+ }
+
+ return ret
+}
+
+// StringsSliceEqual compares two string arrays for equality
+func StringsSliceEqual(a, b []string) bool {
+ if !sort.StringsAreSorted(a) {
+ sort.Strings(a)
+ }
+ if !sort.StringsAreSorted(b) {
+ sort.Strings(b)
+ }
+ for i := range b {
+ if !StringsSliceContains(a, b[i]) {
+ return false
+ }
+ }
+ for i := range a {
+ if !StringsSliceContains(b, a[i]) {
+ return false
+ }
+ }
+ return true
+}
+
+// StringsSliceContains checks for the presence of a word in string array
+func StringsSliceContains(a []string, b string) bool {
+ if !sort.StringsAreSorted(a) {
+ sort.Strings(a)
+ }
+ i := sort.SearchStrings(a, b)
+ return i < len(a) && a[i] == b
+}
diff --git a/test/tools/vendor/github.com/vbatts/git-validation/validate/runner.go b/test/tools/vendor/github.com/vbatts/git-validation/validate/runner.go
new file mode 100644
index 000000000..eea61fba1
--- /dev/null
+++ b/test/tools/vendor/github.com/vbatts/git-validation/validate/runner.go
@@ -0,0 +1,109 @@
+package validate
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+
+ "github.com/vbatts/git-validation/git"
+)
+
+// Runner is the for processing a set of rules against a range of commits
+type Runner struct {
+ Root string
+ Rules []Rule
+ Results Results
+ Verbose bool
+ CommitRange string // if this is empty, then it will default to FETCH_HEAD, then HEAD
+}
+
+// NewRunner returns an initiallized Runner.
+func NewRunner(root string, rules []Rule, commitrange string, verbose bool) (*Runner, error) {
+ newroot, err := filepath.Abs(root)
+ if err != nil {
+ return nil, fmt.Errorf("failed to get absolute path of %q: %s", root, err)
+ }
+ if commitrange == "" {
+ var err error
+ cwd, err := os.Getwd()
+ if err != nil {
+ return nil, err
+ }
+ defer os.Chdir(cwd)
+
+ if err := os.Chdir(newroot); err != nil {
+ return nil, err
+ }
+ commitrange, err = git.FetchHeadCommit()
+ if err != nil {
+ commitrange, err = git.HeadCommit()
+ if err != nil {
+ return nil, err
+ }
+ }
+ }
+ return &Runner{
+ Root: newroot,
+ Rules: rules,
+ CommitRange: commitrange,
+ Verbose: verbose,
+ }, nil
+}
+
+// Run processes the rules for each commit in the range provided
+func (r *Runner) Run() error {
+ cwd, err := os.Getwd()
+ if err != nil {
+ return err
+ }
+ defer os.Chdir(cwd)
+
+ if err := os.Chdir(r.Root); err != nil {
+ return err
+ }
+
+ // collect the entries
+ c, err := git.Commits(r.CommitRange)
+ if err != nil {
+ return err
+ }
+
+ // run them and show results
+ for _, commit := range c {
+ if os.Getenv("QUIET") == "" {
+ fmt.Printf(" * %s %q ... ", commit["abbreviated_commit"], commit["subject"])
+ }
+ vr := Commit(commit, r.Rules)
+ r.Results = append(r.Results, vr...)
+ _, fail := vr.PassFail()
+ if os.Getenv("QUIET") != "" {
+ if fail != 0 {
+ for _, res := range vr {
+ if !res.Pass {
+ fmt.Printf(" %s - FAIL - %s\n", commit["abbreviated_commit"], res.Msg)
+ }
+ }
+ }
+ // everything else in the loop is printing output.
+ // If we're quiet, then just continue
+ continue
+ }
+ if fail == 0 {
+ fmt.Println("PASS")
+ } else {
+ fmt.Println("FAIL")
+ }
+ for _, res := range vr {
+ if r.Verbose {
+ if res.Pass {
+ fmt.Printf(" - PASS - %s\n", res.Msg)
+ } else {
+ fmt.Printf(" - FAIL - %s\n", res.Msg)
+ }
+ } else if !res.Pass {
+ fmt.Printf(" - FAIL - %s\n", res.Msg)
+ }
+ }
+ }
+ return nil
+}