devapp/owners: use path prefixes instead of string prefixes for matching
Remove trailing slashes uniformly from table entries.
Previously, we used string prefixes, which could over-match if two
packages' final elements share a prefix, and used trailing slashes to
compensate, but it's remarkably easy to omit a trailing slash and end
up with a pattern that usually-but-not-always works.
Updates golang/go#27586
Change-Id: Id029a706653e2ba42e83d68f789b65fca34be623
Reviewed-on: https://go-review.googlesource.com/c/build/+/171242
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
diff --git a/devapp/owners/owners.go b/devapp/owners/owners.go
index c762740..9791fb5 100644
--- a/devapp/owners/owners.go
+++ b/devapp/owners/owners.go
@@ -10,7 +10,6 @@
"html/template"
"log"
"net/http"
- "strings"
)
type Owner struct {
@@ -43,13 +42,32 @@
func match(path string) *Entry {
var deepestPath string
for p := range entries {
- if strings.HasPrefix(path, p) && len(p) > len(deepestPath) {
+ if hasPathPrefix(path, p) && len(p) > len(deepestPath) {
deepestPath = p
}
}
return entries[deepestPath]
}
+// hasPathPrefix reports whether the slash-separated path s
+// begins with the elements in prefix.
+//
+// Copied from go/src/cmd/go/internal/str.HasPathPrefix.
+func hasPathPrefix(s, prefix string) bool {
+ if len(s) == len(prefix) {
+ return s == prefix
+ }
+ if prefix == "" {
+ return true
+ }
+ if len(s) > len(prefix) {
+ if prefix[len(prefix)-1] == '/' || s[len(prefix)] == '/' {
+ return s[:len(prefix)] == prefix
+ }
+ }
+ return false
+}
+
// Handler takes one or more paths and returns a map of each to a matching
// Entry struct. If no Entry is matched for the path, the value for the key
// is nil.
diff --git a/devapp/owners/owners_test.go b/devapp/owners/owners_test.go
index 2956ac2..56599a3 100644
--- a/devapp/owners/owners_test.go
+++ b/devapp/owners/owners_test.go
@@ -20,6 +20,12 @@
entry *Entry
}{
{
+ "sync",
+ &Entry{
+ Primary: []Owner{bcmills},
+ },
+ },
+ {
"crypto/chacha20poly1305/chacha20poly1305.go",
&Entry{
Primary: []Owner{filippo},
@@ -34,6 +40,13 @@
},
},
{
+ "go/src/cmd/compile",
+ &Entry{
+ Primary: []Owner{khr, gri},
+ Secondary: []Owner{josharian, mdempsky, martisch},
+ },
+ },
+ {
"go/path/with/no/owners",
&Entry{
Primary: []Owner{rsc, iant, bradfitz},
diff --git a/devapp/owners/table.go b/devapp/owners/table.go
index 8f9229e..283d943 100644
--- a/devapp/owners/table.go
+++ b/devapp/owners/table.go
@@ -74,20 +74,20 @@
// entries is a map of <repo name>/<path> to Owner entries.
// It should not be modified at runtime.
var entries = map[string]*Entry{
- "arch/": {
+ "arch": {
Primary: []Owner{cherryyz},
},
- "crypto/": {
+ "crypto": {
Primary: []Owner{filippo},
Secondary: []Owner{agl},
},
- "crypto/ssh/": {
+ "crypto/ssh": {
Primary: []Owner{hanwen},
Secondary: []Owner{filippo},
},
- "go/": {
+ "go": {
Primary: []Owner{rsc, iant, bradfitz},
},
"go/src/archive/tar": {
@@ -105,7 +105,7 @@
Primary: []Owner{},
Secondary: []Owner{bradfitz, iant},
},
- "go/src/cmd/compile/": {
+ "go/src/cmd/compile": {
Primary: []Owner{khr, gri},
Secondary: []Owner{josharian, mdempsky, martisch},
},
@@ -547,22 +547,22 @@
Secondary: []Owner{andybons},
},
- "gofrontend/": {
+ "gofrontend": {
Primary: []Owner{iant},
Secondary: []Owner{thanm},
},
- "gollvm/": {
+ "gollvm": {
Primary: []Owner{thanm},
Secondary: []Owner{cherryyz},
},
- "mobile/": {
+ "mobile": {
Primary: []Owner{eliasnaur},
Secondary: []Owner{hyangah},
},
- "net/": {
+ "net": {
Primary: []Owner{mikioh},
Secondary: []Owner{bradfitz, iant},
},
@@ -585,11 +585,11 @@
Primary: []Owner{mikioh, iant},
},
- "review/": {
+ "review": {
Secondary: []Owner{josharian, kevinburke},
},
- "sync/": {
+ "sync": {
Primary: []Owner{bcmills},
},
@@ -600,7 +600,7 @@
Primary: []Owner{alexbrainman, bradfitz},
},
- "text/": {
+ "text": {
Primary: []Owner{mpvl},
},