go/packages: work around go list behavior for missing dependencies
If go/packages.Load tries to load a package with a missing dependency, it should not return an error, but a package with an error set on it. This is a workaround for go list -e -compiled (or even just go list -e) returning a non-zero exit status for packages with missing dependencies. Change-Id: I2d7d848ae5133235f595baf7b30296077e891ee3 Reviewed-on: https://go-review.googlesource.com/c/tools/+/170891 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:
parent
7be61e1b0e
commit
1a7b4747f5
|
@ -777,6 +777,22 @@ func invokeGo(cfg *Config, args ...string) (*bytes.Buffer, error) {
|
||||||
return bytes.NewBufferString(output), nil
|
return bytes.NewBufferString(output), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Workaround for an instance of golang.org/issue/26755: go list -e will return a non-zero exit
|
||||||
|
// status if there's a dependency on a package that doesn't exist. But it should return
|
||||||
|
// a zero exit status and set an error on that package.
|
||||||
|
if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "no Go files in") {
|
||||||
|
// try to extract package name from string
|
||||||
|
stderrStr := stderr.String()
|
||||||
|
var importPath string
|
||||||
|
colon := strings.Index(stderrStr, ":")
|
||||||
|
if colon > 0 && strings.HasPrefix(stderrStr, "go build ") {
|
||||||
|
importPath = stderrStr[len("go build "):colon]
|
||||||
|
}
|
||||||
|
output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
|
||||||
|
importPath, strings.Trim(stderrStr, "\n"))
|
||||||
|
return bytes.NewBufferString(output), nil
|
||||||
|
}
|
||||||
|
|
||||||
// Export mode entails a build.
|
// Export mode entails a build.
|
||||||
// If that build fails, errors appear on stderr
|
// If that build fails, errors appear on stderr
|
||||||
// (despite the -e flag) and the Export field is blank.
|
// (despite the -e flag) and the Export field is blank.
|
||||||
|
|
|
@ -1828,6 +1828,28 @@ func testReturnErrorWhenUsingNonGoFiles(t *testing.T, exporter packagestest.Expo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMissingDependency(t *testing.T) { packagestest.TestAll(t, testMissingDependency) }
|
||||||
|
func testMissingDependency(t *testing.T, exporter packagestest.Exporter) {
|
||||||
|
exported := packagestest.Export(t, exporter, []packagestest.Module{{
|
||||||
|
Name: "golang.org/fake",
|
||||||
|
Files: map[string]interface{}{
|
||||||
|
"a/a.go": `package a; import _ "this/package/doesnt/exist"`,
|
||||||
|
}}})
|
||||||
|
defer exported.Cleanup()
|
||||||
|
|
||||||
|
exported.Config.Mode = packages.LoadAllSyntax
|
||||||
|
pkgs, err := packages.Load(exported.Config, "golang.org/fake/a")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(pkgs) != 1 && pkgs[0].PkgPath != "golang.org/fake/a" {
|
||||||
|
t.Fatalf("packages.Load: want [golang.org/fake/a], got %v", pkgs)
|
||||||
|
}
|
||||||
|
if len(pkgs[0].Errors) == 0 {
|
||||||
|
t.Errorf("result of Load: want package with errors, got none: %+v", pkgs[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func errorMessages(errors []packages.Error) []string {
|
func errorMessages(errors []packages.Error) []string {
|
||||||
var msgs []string
|
var msgs []string
|
||||||
for _, err := range errors {
|
for _, err := range errors {
|
||||||
|
|
Loading…
Reference in New Issue