go/buildutil: ignore path letters case in ContainingPackage on windows

Fixes golang/go#13368

Change-Id: I4cee2078bc64b6f175f206daa9609246cc1b1f85
Reviewed-on: https://go-review.googlesource.com/17211
Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
Alex Brainman 2015-11-24 17:36:50 +11:00
parent 977844c7af
commit fff8fd7b19
2 changed files with 58 additions and 1 deletions

View File

@ -15,6 +15,7 @@ import (
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
"runtime"
"strings" "strings"
) )
@ -72,7 +73,7 @@ func ContainingPackage(ctxt *build.Context, dir, filename string) (*build.Packag
// We assume that no source root (GOPATH[i] or GOROOT) contains any other. // We assume that no source root (GOPATH[i] or GOROOT) contains any other.
for _, srcdir := range ctxt.SrcDirs() { for _, srcdir := range ctxt.SrcDirs() {
srcdirSlash := filepath.ToSlash(srcdir) + "/" srcdirSlash := filepath.ToSlash(srcdir) + "/"
if strings.HasPrefix(dirSlash, srcdirSlash) { if dirHasPrefix(dirSlash, srcdirSlash) {
importPath := dirSlash[len(srcdirSlash) : len(dirSlash)-len("/")] importPath := dirSlash[len(srcdirSlash) : len(dirSlash)-len("/")]
return ctxt.Import(importPath, dir, build.FindOnly) return ctxt.Import(importPath, dir, build.FindOnly)
} }
@ -81,6 +82,14 @@ func ContainingPackage(ctxt *build.Context, dir, filename string) (*build.Packag
return nil, fmt.Errorf("can't find package containing %s", filename) return nil, fmt.Errorf("can't find package containing %s", filename)
} }
// dirHasPrefix tests whether the directory dir begins with prefix.
func dirHasPrefix(dir, prefix string) bool {
if runtime.GOOS != "windows" {
return strings.HasPrefix(dir, prefix)
}
return len(dir) >= len(prefix) && strings.EqualFold(dir[:len(prefix)], prefix)
}
// -- Effective methods of file system interface ------------------------- // -- Effective methods of file system interface -------------------------
// (go/build.Context defines these as methods, but does not export them.) // (go/build.Context defines these as methods, but does not export them.)

View File

@ -0,0 +1,48 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package buildutil_test
import (
"fmt"
"go/build"
"path/filepath"
"runtime"
"strings"
"testing"
"golang.org/x/tools/go/buildutil"
)
func testContainingPackageCaseFold(file, want string) error {
bp, err := buildutil.ContainingPackage(&build.Default, ".", file)
if err != nil {
return err
}
if got := bp.ImportPath; got != want {
return fmt.Errorf("ContainingPackage(%q) = %s, want %s", file, got, want)
}
return nil
}
func TestContainingPackageCaseFold(t *testing.T) {
path := filepath.Join(runtime.GOROOT(), `src\fmt\print.go`)
err := testContainingPackageCaseFold(path, "fmt")
if err != nil {
t.Error(err)
}
vol := filepath.VolumeName(path)
if len(vol) != 2 || vol[1] != ':' {
t.Fatalf("GOROOT path has unexpected volume name: %v", vol)
}
rest := path[len(vol):]
err = testContainingPackageCaseFold(strings.ToUpper(vol)+rest, "fmt")
if err != nil {
t.Error(err)
}
err = testContainingPackageCaseFold(strings.ToLower(vol)+rest, "fmt")
if err != nil {
t.Error(err)
}
}