go/packages: report a distinguished ErrGoTooOld error for older go commands

We should add support for older go commands using the multiple-calls
approach of earlier drafts of go/packages.

Also, tag tests for go1.11 to make 1.10 builder happy.

Change-Id: Ia04979528af25cbcd4b4fa5b21cb91d014d530c1
Reviewed-on: https://go-review.googlesource.com/123756
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Alan Donovan 2018-07-13 11:49:34 -04:00
parent 2087f8c107
commit 9d3ae49c73
5 changed files with 44 additions and 2 deletions

View File

@ -13,6 +13,9 @@ recursively loading dependencies from source code.
THIS INTERFACE IS EXPERIMENTAL AND IS LIKELY TO CHANGE. THIS INTERFACE IS EXPERIMENTAL AND IS LIKELY TO CHANGE.
This package currently requires a go1.11 version of go list;
its functions will return a GoTooOldError for older toolchains.
This package is intended to replace golang.org/x/tools/go/loader. This package is intended to replace golang.org/x/tools/go/loader.
It provides a simpler interface to the same functionality and serves It provides a simpler interface to the same functionality and serves
as a foundation for analysis tools that work with 'go build', as a foundation for analysis tools that work with 'go build',

View File

@ -1,3 +1,7 @@
// Copyright 2018 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 packages package packages
// This file defines the "go list" implementation of the Packages metadata query. // This file defines the "go list" implementation of the Packages metadata query.
@ -13,6 +17,12 @@ import (
"strings" "strings"
) )
// A GoTooOldError indicates that the go command predates the Go
// 1.11 features needed by this package. This error is a stopgap measure
// until the necessary features can be emulated in terms of an older go
// command, at which point this error will no longer be used.
type GoTooOldError struct{ error }
// golistPackages uses the "go list" command to expand the // golistPackages uses the "go list" command to expand the
// pattern words and return metadata for the specified packages. // pattern words and return metadata for the specified packages.
func golistPackages(ctx context.Context, gopath string, cgo, export bool, words []string) ([]*Package, error) { func golistPackages(ctx context.Context, gopath string, cgo, export bool, words []string) ([]*Package, error) {
@ -201,7 +211,7 @@ func golist(ctx context.Context, gopath string, cgo, export bool, args []string)
// Old go list? // Old go list?
if strings.Contains(fmt.Sprint(cmd.Stderr), "flag provided but not defined") { if strings.Contains(fmt.Sprint(cmd.Stderr), "flag provided but not defined") {
return nil, fmt.Errorf("unsupported version of go list: %s: %s", exitErr, cmd.Stderr) return nil, GoTooOldError{fmt.Errorf("unsupported version of go list: %s: %s", exitErr, cmd.Stderr)}
} }
// Export mode entails a build. // Export mode entails a build.

View File

@ -0,0 +1,21 @@
// Copyright 2018 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.
// +build !go1.11
package packages_test
import (
"testing"
"golang.org/x/tools/go/packages"
)
func TestGoIsTooOld(t *testing.T) {
_, err := packages.Metadata(nil, "errors")
if _, ok := err.(packages.GoTooOldError); !ok {
t.Fatalf("using go/packages with pre-Go 1.11 go: err=%v, want ErrGoTooOld", err)
}
}

View File

@ -1,3 +1,9 @@
// Copyright 2018 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.
// +build go1.11
package packages_test package packages_test
import ( import (

View File

@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build go1.11
package packages_test package packages_test
import ( import (