]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: revise disallowInternal
authorRuss Cox <rsc@golang.org>
Wed, 6 Aug 2014 21:59:30 +0000 (17:59 -0400)
committerRuss Cox <rsc@golang.org>
Wed, 6 Aug 2014 21:59:30 +0000 (17:59 -0400)
This fixes two problems: x/internal/y/z was using parent = x/internal/y instead of x,
and hasPathPrefix only looks at /, not \ for Windows.

LGTM=bradfitz
R=bradfitz
CC=golang-codereviews
https://golang.org/cl/121280045

src/cmd/go/pkg.go

index d0dbefed01c3401316a940f9054dfc0ee59fc791..be691a6bc9afd79a6b339291642f4ca5639cee1e 100644 (file)
@@ -330,16 +330,18 @@ func disallowInternal(srcDir string, p *Package, stk *importStack) *Package {
        }
 
        // Check for "internal" element: four cases depending on begin of string and/or end of string.
-       if p.ImportPath != "internal" &&
-               !strings.HasPrefix(p.ImportPath, "internal/") &&
-               !strings.HasSuffix(p.ImportPath, "/internal") &&
-               !strings.Contains(p.ImportPath, "/internal/") {
+       i, ok := findInternal(p.ImportPath)
+       if !ok {
                return p
        }
 
-       // Internal is present. Check directory.
-       parent := filepath.Dir(p.Dir)
-       if hasPathPrefix(srcDir, parent) {
+       // Internal is present.
+       // Map import path back to directory corresponding to parent of internal.
+       if i > 0 {
+               i-- // rewind over slash in ".../internal"
+       }
+       parent := p.Dir[:i+len(p.Dir)-len(p.ImportPath)]
+       if hasPathPrefix(filepath.ToSlash(srcDir), filepath.ToSlash(parent)) {
                return p
        }
 
@@ -353,6 +355,25 @@ func disallowInternal(srcDir string, p *Package, stk *importStack) *Package {
        return &perr
 }
 
+// findInternal looks for the final "internal" path element in the given import path.
+// If there isn't one, findInternal returns ok=false.
+// Otherwise, findInternal returns ok=true and the index of the "internal".
+func findInternal(path string) (index int, ok bool) {
+       // Four cases, depending on internal at start/end of string or not.
+       // The order matters: we must return the index of the final element,
+       // because the final one produces the most restrictive requirement
+       // on the importer.
+       switch {
+       case strings.HasSuffix(path, "/internal"):
+               return len(path) - len("internal"), true
+       case strings.Contains(path, "/internal/"):
+               return strings.LastIndex(path, "/internal/") + 1, true
+       case path == "internal", strings.HasPrefix(path, "internal/"):
+               return 0, true
+       }
+       return 0, false
+}
+
 type targetDir int
 
 const (