1
0
mirror of https://github.com/golang/go synced 2024-10-01 05:28:33 -06:00

go/packages: include test deps in golist fallback

In Go 1.10 and earlier, the Deps field returned by go list does not
include the dependencies of any test files.  To get the dependencies
of the test packages, we need to run go list another time (for a total
of 3 calls to go list), to get the dependencies of the packages the
tests import.

Fixes golang/go#26753

Change-Id: Id3b424ac935e5ed459b4d4a55630715171bb9710
Reviewed-on: https://go-review.googlesource.com/127457
Reviewed-by: Ian Cottrell <iancottrell@google.com>
Reviewed-by: Michael Matloob <matloob@golang.org>
Run-TryBot: Michael Matloob <matloob@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Suzy Mueller 2018-08-01 21:38:32 -04:00
parent 681bc0c94c
commit 78b3e71765
2 changed files with 78 additions and 9 deletions

View File

@ -92,12 +92,18 @@ func golistPackagesFallback(ctx context.Context, cfg *raw.Config, words ...strin
if isRoot { if isRoot {
roots = append(roots, xtestID) roots = append(roots, xtestID)
} }
for i, imp := range p.XTestImports {
if imp == p.ImportPath {
p.XTestImports[i] = testID
break
}
}
result = append(result, &raw.Package{ result = append(result, &raw.Package{
ID: xtestID, ID: xtestID,
Name: p.Name + "_test", Name: p.Name + "_test",
GoFiles: absJoin(p.Dir, p.XTestGoFiles), GoFiles: absJoin(p.Dir, p.XTestGoFiles),
PkgPath: pkgpath, PkgPath: pkgpath,
Imports: importMap(append(p.XTestImports, testID)), Imports: importMap(p.XTestImports),
}) })
} }
} }
@ -137,6 +143,7 @@ func getDeps(ctx context.Context, cfg *raw.Config, words ...string) (originalSet
depsSet := make(map[string]bool) depsSet := make(map[string]bool)
originalSet = make(map[string]*jsonPackage) originalSet = make(map[string]*jsonPackage)
var testImports []string
// Extract deps from the JSON. // Extract deps from the JSON.
for dec := json.NewDecoder(buf); dec.More(); { for dec := json.NewDecoder(buf); dec.More(); {
@ -149,7 +156,36 @@ func getDeps(ctx context.Context, cfg *raw.Config, words ...string) (originalSet
for _, dep := range p.Deps { for _, dep := range p.Deps {
depsSet[dep] = true depsSet[dep] = true
} }
if cfg.Tests {
// collect the additional imports of the test packages.
pkgTestImports := append(p.TestImports, p.XTestImports...)
for _, imp := range pkgTestImports {
if depsSet[imp] {
continue
}
depsSet[imp] = true
testImports = append(testImports, imp)
}
}
} }
// Get the deps of the packages imported by tests.
if len(testImports) > 0 {
buf, err = golist(ctx, cfg, golistargs_fallback(cfg, testImports))
if err != nil {
return nil, nil, err
}
// Extract deps from the JSON.
for dec := json.NewDecoder(buf); dec.More(); {
p := new(jsonPackage)
if err := dec.Decode(p); err != nil {
return nil, nil, fmt.Errorf("JSON decoding failed: %v", err)
}
for _, dep := range p.Deps {
depsSet[dep] = true
}
}
}
for orig := range originalSet { for orig := range originalSet {
delete(depsSet, orig) delete(depsSet, orig)
} }

View File

@ -39,14 +39,14 @@ var usesOldGolist = false
// gracefully. // gracefully.
// - test more Flags. // - test more Flags.
// //
// TypeCheck & WholeProgram modes: // LoadSyntax & LoadAllSyntax modes:
// - Fset may be user-supplied or not. // - Fset may be user-supplied or not.
// - Packages.Info is correctly set. // - Packages.Info is correctly set.
// - typechecker configuration is honored // - typechecker configuration is honored
// - import cycles are gracefully handled in type checker. // - import cycles are gracefully handled in type checker.
// - test typechecking of generated test main and cgo. // - test typechecking of generated test main and cgo.
func TestMetadataImportGraph(t *testing.T) { func TestLoadImportsGraph(t *testing.T) {
if runtime.GOOS != "linux" { if runtime.GOOS != "linux" {
t.Skipf("TODO: skipping on non-Linux; fix this test to run everywhere. golang.org/issue/26387") t.Skipf("TODO: skipping on non-Linux; fix this test to run everywhere. golang.org/issue/26387")
} }
@ -131,8 +131,32 @@ func TestMetadataImportGraph(t *testing.T) {
subdir/d_test [subdir/d.test] -> subdir/d [subdir/d.test] subdir/d_test [subdir/d.test] -> subdir/d [subdir/d.test]
`[1:] `[1:]
// Legacy go list support does not create test main package.
wantOldGraph := `
a
b
* c
* e
errors
math/bits
* subdir/d
* subdir/d [subdir/d.test]
* subdir/d_test [subdir/d.test]
unsafe
b -> a
b -> errors
c -> b
c -> unsafe
e -> b
e -> c
subdir/d [subdir/d.test] -> math/bits
subdir/d_test [subdir/d.test] -> subdir/d [subdir/d.test]
`[1:]
if graph != wantGraph && !usesOldGolist { if graph != wantGraph && !usesOldGolist {
t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph) t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
} else if graph != wantOldGraph && usesOldGolist {
t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantOldGraph)
} }
// Check node information: kind, name, srcs. // Check node information: kind, name, srcs.
@ -190,11 +214,6 @@ func TestMetadataImportGraph(t *testing.T) {
} }
} }
if usesOldGolist {
// TODO(matloob): Wildcards are not yet supported.
return
}
// Wildcards // Wildcards
// See StdlibTest for effective test of "std" wildcard. // See StdlibTest for effective test of "std" wildcard.
// TODO(adonovan): test "all" returns everything in the current module. // TODO(adonovan): test "all" returns everything in the current module.
@ -220,8 +239,21 @@ func TestMetadataImportGraph(t *testing.T) {
subdir/d.test -> testing/internal/testdeps (pruned) subdir/d.test -> testing/internal/testdeps (pruned)
subdir/d_test [subdir/d.test] -> subdir/d [subdir/d.test] subdir/d_test [subdir/d.test] -> subdir/d [subdir/d.test]
`[1:] `[1:]
if graph != wantGraph {
// Legacy go list support does not create test main package.
wantOldGraph = `
math/bits
* subdir/d
* subdir/d [subdir/d.test]
* subdir/d_test [subdir/d.test]
* subdir/e
subdir/d [subdir/d.test] -> math/bits
subdir/d_test [subdir/d.test] -> subdir/d [subdir/d.test]
`[1:]
if graph != wantGraph && !usesOldGolist {
t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph) t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
} else if graph != wantOldGraph && usesOldGolist {
t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantOldGraph)
} }
} }
} }
@ -844,6 +876,7 @@ func errorMessages(errors []error) []string {
func srcs(p *packages.Package) (basenames []string) { func srcs(p *packages.Package) (basenames []string) {
files := append(p.GoFiles, p.OtherFiles...) files := append(p.GoFiles, p.OtherFiles...)
for i, src := range files { for i, src := range files {
// TODO(suzmue): make cache names predictable on all os.
if strings.Contains(src, ".cache/go-build") { if strings.Contains(src, ".cache/go-build") {
src = fmt.Sprintf("%d.go", i) // make cache names predictable src = fmt.Sprintf("%d.go", i) // make cache names predictable
} else { } else {