go/packages/golist: pass in -compiled to go list

This is mostly straightforward, except that go list -e -compiled
will now return errors if a package can't build. This is a bug.
We need to skip the errors test until that's fixed.

For now, don't try to run go list with no arguments because it will
fail. So when all arguments are contains, we will check for empty
patterns and skip running go list.

Change-Id: I7c92b1bf9448e5dbea22f9ade9fb9429945e3719
Reviewed-on: https://go-review.googlesource.com/127339
Run-TryBot: Michael Matloob <matloob@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
This commit is contained in:
Michael Matloob 2018-08-01 13:40:35 -04:00
parent 78b3e71765
commit 4a42e0a488
4 changed files with 73 additions and 50 deletions

View File

@ -57,16 +57,27 @@ func LoadRaw(ctx context.Context, cfg *raw.Config, patterns ...string) ([]string
patterns = restPatterns patterns = restPatterns
} }
listfunc := golistPackages // TODO(matloob): Remove the definition of listfunc and just use golistPackages once go1.12 is released.
var listfunc func(ctx context.Context, cfg *raw.Config, words ...string) ([]string, []*raw.Package, error)
listfunc = func(ctx context.Context, cfg *raw.Config, words ...string) ([]string, []*raw.Package, error) {
roots, pkgs, err := golistPackages(ctx, cfg, patterns...)
if _, ok := err.(goTooOldError); ok {
listfunc = golistPackagesFallback
roots, pkgs, err = listfunc(ctx, cfg, patterns...)
}
listfunc = golistPackages
return roots, pkgs, err
}
roots, pkgs, err := []string(nil), []*raw.Package(nil), error(nil)
// TODO(matloob): Patterns may now be empty, if it was solely comprised of contains: patterns. // TODO(matloob): Patterns may now be empty, if it was solely comprised of contains: patterns.
// See if the extra process invocation can be avoided. // See if the extra process invocation can be avoided.
roots, pkgs, err := listfunc(ctx, cfg, patterns...) if len(patterns) > 0 {
if _, ok := err.(goTooOldError); ok {
listfunc = golistPackagesFallback
roots, pkgs, err = listfunc(ctx, cfg, patterns...) roots, pkgs, err = listfunc(ctx, cfg, patterns...)
} if err != nil {
if err != nil { return nil, nil, err
return nil, nil, err }
} }
// Run go list for contains: patterns. // Run go list for contains: patterns.
@ -107,23 +118,24 @@ func LoadRaw(ctx context.Context, cfg *raw.Config, patterns ...string) ([]string
// Fields must match go list; // Fields must match go list;
// see $GOROOT/src/cmd/go/internal/load/pkg.go. // see $GOROOT/src/cmd/go/internal/load/pkg.go.
type jsonPackage struct { type jsonPackage struct {
ImportPath string ImportPath string
Dir string Dir string
Name string Name string
Export string Export string
GoFiles []string GoFiles []string
CFiles []string CompiledGoFiles []string
CgoFiles []string CFiles []string
SFiles []string CgoFiles []string
Imports []string SFiles []string
ImportMap map[string]string Imports []string
Deps []string ImportMap map[string]string
TestGoFiles []string Deps []string
TestImports []string TestGoFiles []string
XTestGoFiles []string TestImports []string
XTestImports []string XTestGoFiles []string
ForTest string // q in a "p [q.test]" package, else "" XTestImports []string
DepOnly bool ForTest string // q in a "p [q.test]" package, else ""
DepOnly bool
} }
// golistPackages uses the "go list" command to expand the // golistPackages uses the "go list" command to expand the
@ -230,13 +242,18 @@ func golistPackages(ctx context.Context, cfg *raw.Config, words ...string) ([]st
} }
pkg := &raw.Package{ pkg := &raw.Package{
ID: id, ID: id,
Name: p.Name, Name: p.Name,
GoFiles: absJoin(p.Dir, p.GoFiles, p.CgoFiles), GoFiles: absJoin(p.Dir, p.GoFiles, p.CgoFiles),
OtherFiles: absJoin(p.Dir, p.SFiles, p.CFiles), CompiledGoFiles: absJoin(p.Dir, p.CompiledGoFiles),
PkgPath: pkgpath, OtherFiles: absJoin(p.Dir, p.SFiles, p.CFiles),
Imports: imports, PkgPath: pkgpath,
Export: export, Imports: imports,
Export: export,
}
// TODO(matloob): Temporary hack since CompiledGoFiles isn't always set.
if len(pkg.CompiledGoFiles) == 0 {
pkg.CompiledGoFiles = pkg.GoFiles
} }
if !p.DepOnly { if !p.DepOnly {
roots = append(roots, pkg.ID) roots = append(roots, pkg.ID)
@ -262,7 +279,7 @@ func absJoin(dir string, fileses ...[]string) (res []string) {
func golistargs(cfg *raw.Config, words []string) []string { func golistargs(cfg *raw.Config, words []string) []string {
fullargs := []string{ fullargs := []string{
"list", "-e", "-json", "list", "-e", "-json", "-compiled",
fmt.Sprintf("-test=%t", cfg.Tests), fmt.Sprintf("-test=%t", cfg.Tests),
fmt.Sprintf("-export=%t", cfg.Export), fmt.Sprintf("-export=%t", cfg.Export),
fmt.Sprintf("-deps=%t", cfg.Deps), fmt.Sprintf("-deps=%t", cfg.Deps),

View File

@ -65,12 +65,13 @@ func golistPackagesFallback(ctx context.Context, cfg *raw.Config, words ...strin
roots = append(roots, id) roots = append(roots, id)
} }
result = append(result, &raw.Package{ result = append(result, &raw.Package{
ID: id, ID: id,
Name: p.Name, Name: p.Name,
GoFiles: absJoin(p.Dir, p.GoFiles, p.CgoFiles), GoFiles: absJoin(p.Dir, p.GoFiles, p.CgoFiles),
OtherFiles: absJoin(p.Dir, p.SFiles, p.CFiles), CompiledGoFiles: absJoin(p.Dir, p.GoFiles, p.CgoFiles), // TODO(matloob): Use cgo-processed Go files instead of p.GoFiles
PkgPath: pkgpath, OtherFiles: absJoin(p.Dir, p.SFiles, p.CFiles),
Imports: importMap(p.Imports), PkgPath: pkgpath,
Imports: importMap(p.Imports),
}) })
if cfg.Tests { if cfg.Tests {
testID := fmt.Sprintf("%s [%s.test]", id, id) testID := fmt.Sprintf("%s [%s.test]", id, id)
@ -79,12 +80,13 @@ func golistPackagesFallback(ctx context.Context, cfg *raw.Config, words ...strin
roots = append(roots, testID) roots = append(roots, testID)
} }
result = append(result, &raw.Package{ result = append(result, &raw.Package{
ID: testID, ID: testID,
Name: p.Name, Name: p.Name,
GoFiles: absJoin(p.Dir, p.GoFiles, p.TestGoFiles, p.CgoFiles), GoFiles: absJoin(p.Dir, p.GoFiles, p.TestGoFiles, p.CgoFiles),
OtherFiles: absJoin(p.Dir, p.SFiles, p.CFiles), CompiledGoFiles: absJoin(p.Dir, p.GoFiles, p.TestGoFiles, p.CgoFiles), // TODO(matloob): Use cgo-processed Go files instead of p.GoFiles
PkgPath: pkgpath, OtherFiles: absJoin(p.Dir, p.SFiles, p.CFiles),
Imports: importMap(append(p.Imports, p.TestImports...)), PkgPath: pkgpath,
Imports: importMap(append(p.Imports, p.TestImports...)),
}) })
} }
if len(p.XTestGoFiles) > 0 { if len(p.XTestGoFiles) > 0 {
@ -99,11 +101,12 @@ func golistPackagesFallback(ctx context.Context, cfg *raw.Config, words ...strin
} }
} }
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, CompiledGoFiles: absJoin(p.Dir, p.XTestGoFiles),
Imports: importMap(p.XTestImports), PkgPath: pkgpath,
Imports: importMap(p.XTestImports),
}) })
} }
} }

View File

@ -464,7 +464,7 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
lpkg.Errors = append(lpkg.Errors, err) lpkg.Errors = append(lpkg.Errors, err)
} }
files, errs := ld.parseFiles(lpkg.GoFiles) files, errs := ld.parseFiles(lpkg.raw.CompiledGoFiles)
for _, err := range errs { for _, err := range errs {
appendError(err) appendError(err)
} }

View File

@ -671,6 +671,9 @@ func TestWholeProgramOverlay(t *testing.T) {
} }
func TestWholeProgramImportErrors(t *testing.T) { func TestWholeProgramImportErrors(t *testing.T) {
// TODO(matloob): Remove this once go list -e -compiled is fixed. See golang.org/issue/26755
t.Skip("go list -compiled -e fails with non-zero exit status for empty packages")
if usesOldGolist { if usesOldGolist {
t.Skip("not yet supported in pre-Go 1.10.4 golist fallback implementation") t.Skip("not yet supported in pre-Go 1.10.4 golist fallback implementation")
} }