internal/imports: don't prefix stdlib package with std/

When running in GOROOT/src, `go list -m all` shows the std package (or
cmd package) as the main module. This confuses goimports into adding
std/ or cmd/ at the beginning of import paths. Skip canonicalization for
paths under GOROOT.

Fixes golang/go#31814

Change-Id: Iff5cc7e2a2053e4cc87c1a579a4c47d856cd0a2e
Reviewed-on: https://go-review.googlesource.com/c/tools/+/195063
Run-TryBot: Heschi Kreinick <heschi@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
This commit is contained in:
Heschi Kreinick 2019-09-12 16:41:22 -04:00
Родитель 2c18af7e64
Коммит c886270503
2 изменённых файлов: 50 добавлений и 3 удалений

Просмотреть файл

@ -7,6 +7,7 @@ package imports
import (
"flag"
"fmt"
"go/build"
"path/filepath"
"runtime"
"strings"
@ -1538,6 +1539,39 @@ func TestFindStdlib(t *testing.T) {
}
}
// https://golang.org/issue/31814
func TestStdlibNotPrefixed(t *testing.T) {
const input = `package p
var _ = bytes.Buffer
`
const want = `package p
import "bytes"
var _ = bytes.Buffer
`
// Force a scan of the stdlib.
savedStdlib := stdlib
defer func() { stdlib = savedStdlib }()
stdlib = map[string]map[string]bool{}
testConfig{
module: packagestest.Module{
Name: "ignored.com",
},
}.test(t, func(t *goimportTest) {
// Run in GOROOT/src so that the std module shows up in go list -m all.
t.env.WorkingDir = filepath.Join(t.env.GOROOT, "src")
got, err := t.processNonModule(filepath.Join(t.env.GOROOT, "src/x.go"), []byte(input), nil)
if err != nil {
t.Fatalf("Process() = %v", err)
}
if string(got) != want {
t.Errorf("Got:\n%s\nWant:\n%s", got, want)
}
})
}
type testConfig struct {
gopathOnly bool
goPackagesIncompatible bool
@ -1609,6 +1643,11 @@ func (c testConfig) test(t *testing.T, fn func(*goimportTest)) {
},
exported: exported,
}
if it.env.GOROOT == "" {
// packagestest clears out GOROOT to work around https://golang.org/issue/32849,
// which isn't relevant here. Fill it back in so we can find the standard library.
it.env.GOROOT = build.Default.GOROOT
}
fn(it)
})
}

Просмотреть файл

@ -313,7 +313,7 @@ func (r *ModuleResolver) scan(_ references) ([]*pkg, error) {
// The rest of this function canonicalizes the packages using the results
// of initializing the resolver from 'go list -m'.
res, err := r.canonicalize(info.nonCanonicalImportPath, info.dir, info.needsReplace)
res, err := r.canonicalize(root.Type, info.nonCanonicalImportPath, info.dir, info.needsReplace)
if err != nil {
return
}
@ -335,7 +335,7 @@ func (r *ModuleResolver) scan(_ references) ([]*pkg, error) {
continue
}
res, err := r.canonicalize(info.nonCanonicalImportPath, info.dir, info.needsReplace)
res, err := r.canonicalize(gopathwalk.RootModuleCache, info.nonCanonicalImportPath, info.dir, info.needsReplace)
if err != nil {
continue
}
@ -347,7 +347,15 @@ func (r *ModuleResolver) scan(_ references) ([]*pkg, error) {
// canonicalize gets the result of canonicalizing the packages using the results
// of initializing the resolver from 'go list -m'.
func (r *ModuleResolver) canonicalize(importPath, dir string, needsReplace bool) (res *pkg, err error) {
func (r *ModuleResolver) canonicalize(rootType gopathwalk.RootType, importPath, dir string, needsReplace bool) (res *pkg, err error) {
// Packages in GOROOT are already canonical, regardless of the std/cmd modules.
if rootType == gopathwalk.RootGOROOT {
return &pkg{
importPathShort: importPath,
dir: dir,
}, nil
}
// Check if the directory is underneath a module that's in scope.
if mod := r.findModuleByDir(dir); mod != nil {
// It is. If dir is the target of a replace directive,