internal/ci/paths.go

5ffa892991a5437dc53680ea1609fabee4b85d42
gitbay/internal/ci/paths.go history · blame · raw

67 lines · 1816 bytes

 1package ci
 2
 3import (
 4	"path"
 5	"strings"
 6)
 7
 8// zeroSHA is git's null object id: the old side of a ref update that
 9// created the ref, carrying no diff base.
10const zeroSHA = "0000000000000000000000000000000000000000"
11
12// Match reports whether a changed file path matches a job's glob.
13// A trailing /** matches the directory and everything below it at any
14// depth; anything else goes to path.Match, whose * stops at a separator.
15func Match(pattern, file string) bool {
16	if prefix, ok := strings.CutSuffix(pattern, "/**"); ok {
17		return file == prefix || strings.HasPrefix(file, prefix+"/")
18	}
19	ok, err := path.Match(pattern, file)
20	return err == nil && ok
21}
22
23// Selected reports whether a job's path filters admit a push that
24// changed the given files. Call it only once the changed-file list is
25// known; a caller that cannot compute one must run the job instead of
26// calling this.
27//
28// The job runs when Paths is empty or at least one file matches one of
29// its patterns, and is then held back only if PathsIgnore is non-empty
30// and every file matches one of its patterns.
31func Selected(j Job, files []string) bool {
32	if len(j.Paths) > 0 {
33		hit := false
34		for _, f := range files {
35			for _, p := range j.Paths {
36				if Match(p, f) {
37					hit = true
38				}
39			}
40		}
41		if !hit {
42			return false
43		}
44	}
45	if len(j.PathsIgnore) > 0 {
46		for _, f := range files {
47			ignored := false
48			for _, p := range j.PathsIgnore {
49				if Match(p, f) {
50					ignored = true
51				}
52			}
53			if !ignored {
54				return true
55			}
56		}
57		return false
58	}
59	return true
60}
61
62// HasDiffBase reports whether old names a commit a diff can start from.
63// A branch's first push carries an empty or all-zero old sha, so there
64// is nothing to compare the new commit against.
65func HasDiffBase(old string) bool {
66	return old != "" && old != zeroSHA
67}