From fff8fd7b194011cfedeafda246f0bfc275abb904 Mon Sep 17 00:00:00 2001 From: Alex Brainman Date: Tue, 24 Nov 2015 17:36:50 +1100 Subject: [PATCH] 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 --- go/buildutil/util.go | 11 ++++++- go/buildutil/util_windows_test.go | 48 +++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 go/buildutil/util_windows_test.go diff --git a/go/buildutil/util.go b/go/buildutil/util.go index 60eeae25..0e093fc0 100644 --- a/go/buildutil/util.go +++ b/go/buildutil/util.go @@ -15,6 +15,7 @@ import ( "os" "path" "path/filepath" + "runtime" "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. for _, srcdir := range ctxt.SrcDirs() { srcdirSlash := filepath.ToSlash(srcdir) + "/" - if strings.HasPrefix(dirSlash, srcdirSlash) { + if dirHasPrefix(dirSlash, srcdirSlash) { importPath := dirSlash[len(srcdirSlash) : len(dirSlash)-len("/")] 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) } +// 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 ------------------------- // (go/build.Context defines these as methods, but does not export them.) diff --git a/go/buildutil/util_windows_test.go b/go/buildutil/util_windows_test.go new file mode 100644 index 00000000..86fe9c71 --- /dev/null +++ b/go/buildutil/util_windows_test.go @@ -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) + } +}