Skip to content

Commit eb6c19d

Browse files
authored
fix: orion SourceGlob of format a/**/b (#125)
### Changes are visible to end-users: no ### Test plan - Covered by existing test cases - New test cases added
1 parent ad074cb commit eb6c19d

File tree

2 files changed

+26
-12
lines changed

2 files changed

+26
-12
lines changed

common/glob.go

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ type GlobExpr func(string) bool
1515
var nonGlobRe = regexp.MustCompile(`^[\w./@-]+$`)
1616

1717
// Doublestar globs that can be simplified to only a prefix and suffix
18-
var prePostGlobRe = regexp.MustCompile(`^([\w./@-]*)\*\*(?:/\*?)?([\w./@-]+)$`)
18+
var prePostGlobRe = regexp.MustCompile(`^([\w./@-]*)\*\*(/\*?)?([\w./@-]+)$`)
1919

2020
// Globs with a prefix or postfix that can be checked before invoking the regex
2121
var preGlobRe = regexp.MustCompile(`^([\w./@-]+).*$`)
@@ -47,10 +47,14 @@ func parseGlobExpression(exp string) GlobExpr {
4747

4848
if extGlob := prePostGlobRe.FindStringSubmatch(exp); len(extGlob) > 0 {
4949
// Globs that can be expressed as pre + ** + ext
50-
pre, ext := extGlob[1], extGlob[2]
50+
pre, slashStar, ext := extGlob[1], extGlob[2], extGlob[3]
5151
minLen := len(pre) + len(ext)
52+
hasStar := slashStar == "/*"
5253
return func(p string) bool {
53-
return len(p) >= minLen && strings.HasPrefix(p, pre) && strings.HasSuffix(p, ext)
54+
if len(p) < minLen || !strings.HasPrefix(p, pre) {
55+
return false
56+
}
57+
return strings.HasSuffix(p, ext) && (hasStar || p == ext || p[len(p)-len(ext)-1] == '/')
5458
}
5559
}
5660

@@ -101,7 +105,7 @@ func ParseGlobExpressions(exps []string) (GlobExpr, error) {
101105

102106
func parseGlobExpressions(exps []string) (GlobExpr, error) {
103107
exacts := make(map[string]struct{})
104-
prePosts := make(map[string][]string)
108+
prePosts := make(map[string][][]string)
105109
preGlobs := make(map[string][]string)
106110
postGlobs := make(map[string][]string)
107111
globs := make([]string, 0)
@@ -115,8 +119,8 @@ func parseGlobExpressions(exps []string) (GlobExpr, error) {
115119
exacts[exp] = struct{}{}
116120
} else if extGlob := prePostGlobRe.FindStringSubmatch(exp); len(extGlob) > 0 {
117121
// Globs that can be expressed as pre + ** + ext
118-
pre, ext := extGlob[1], extGlob[2]
119-
prePosts[pre] = append(prePosts[pre], ext)
122+
pre, slashStar, ext := extGlob[1], extGlob[2], extGlob[3]
123+
prePosts[pre] = append(prePosts[pre], []string{slashStar, ext})
120124
} else if preGlob := preGlobRe.FindStringSubmatch(exp); len(preGlob) > 0 {
121125
pre := preGlob[1]
122126
preGlobs[pre] = append(preGlobs[pre], exp)
@@ -139,10 +143,14 @@ func parseGlobExpressions(exps []string) (GlobExpr, error) {
139143

140144
if len(prePosts) > 0 {
141145
exprFuncs = append(exprFuncs, func(p string) bool {
146+
lenP := len(p)
142147
for pre, exts := range prePosts {
143148
if strings.HasPrefix(p, pre) {
144-
for _, ext := range exts {
145-
if len(p) >= len(pre)+len(ext) && strings.HasSuffix(p, ext) {
149+
for _, extData := range exts {
150+
hasStar := extData[0] == "/*"
151+
ext := extData[1]
152+
153+
if lenP >= len(pre)+len(ext) && strings.HasSuffix(p, ext) && (hasStar || p == ext || p[lenP-len(ext)-1] == '/') {
146154
return true
147155
}
148156
}

common/glob_test.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,15 @@ func TestParseGlobExpressionVsDoublestar(t *testing.T) {
2828
"src/foo/**/*.go": {"src/main.go", "src/foo/main.go", "src/foo/bar/main.go", "foo/src/main.go", "main.go", "src/foo/src/main.go"},
2929

3030
// With prefix and suffix that are equal
31-
"foo/**/foo": {"foo", "foo/foo", "foo/bar/foo", "foo/foo/foo"},
31+
"foo/**/foo": {"foo", "foo/foo", "foo/bar/foo", "foo/bar/NOTfoo", "foo/foo/foo"},
32+
"src/**/important.ts": {"important.ts", "NOTimportant.ts", "NOT.important.ts", "important.NOT.ts", "src/important.ts", "src/NOTimportant.ts", "src/NOT.important.ts", "src/important.NOT.ts"},
3233

3334
// Body with doublestars
3435
"**/foo/**": {"foo/bar", "a/foo/baz", "a/b/c/foo/d/e", "foo", "a/b/c/foo", "foo/a/b/c"},
3536

3637
// Starting doublestars
37-
"**/WORKSPACE": {"WORKSPACE", "WORKSPACE.bazel", "a/WORKSPACE", "WORKSPACE.txt", "a/WORKSPACE.bazel"},
38-
"**/WORKSPACE.bazel": {"WORKSPACE", "WORKSPACE.bazel", "a/WORKSPACE", "WORKSPACE.txt", "a/WORKSPACE.bazel"},
38+
"**/WORKSPACE": {"WORKSPACE", "notWORKSPACE", "notWORKSPACE.bazel", "WORKSPACE.bazel", "a/WORKSPACE", "a/notWORKSPACE", "WORKSPACE.txt", "a/WORKSPACE.bazel", "a/notWORKSPACE.bazel"},
39+
"**/WORKSPACE.bazel": {"WORKSPACE", "notWORKSPACE", "notWORKSPACE.bazel", "WORKSPACE.bazel", "a/WORKSPACE", "a/notWORKSPACE", "WORKSPACE.txt", "a/WORKSPACE.bazel", "a/notWORKSPACE.bazel"},
3940
"**/@foo/bar": {"@foo/bar/baz", "@foo/bar", "foo/bar", "a/@foo/bar"},
4041
"**/*.go": {"main.go", "src/main.go", "src/deep/nested/file.go"},
4142
"**/*_test.go": {"src/test_file.go", "src/path/test_file.go", "deep/nested/test_file.go"},
@@ -57,7 +58,8 @@ func TestParseGlobExpressionVsDoublestar(t *testing.T) {
5758
}
5859

5960
for testPattern, testCases := range tests {
60-
expr, err := ParseGlobExpression(testPattern)
61+
expr := parseGlobExpression(testPattern)
62+
expr2, err := parseGlobExpressions([]string{testPattern})
6163

6264
// Verify doublestar agrees on validity
6365
if (err == nil) != doublestar.ValidatePattern(testPattern) {
@@ -69,6 +71,10 @@ func TestParseGlobExpressionVsDoublestar(t *testing.T) {
6971
if expr(c) != doublestar.MatchUnvalidated(testPattern, c) {
7072
t.Errorf("pattern %q did not align with doublestar with case %q", testPattern, c)
7173
}
74+
75+
if expr(c) != expr2(c) {
76+
t.Errorf("pattern %q did not align between ParseGlobExpression(s) with case %q", testPattern, c)
77+
}
7278
}
7379
}
7480
}

0 commit comments

Comments
 (0)