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

go/packages: add a work around for go list behavior for missing ad-hoc package

If a file in an ad-hoc package doesn't exist, go list should exit 0 and
return an dummy package with an error set on it. Since it doesn't do that
yet, add a work-around.

Updates golang/go#29280

Change-Id: I6019f28ce4770582f274919d1aa35d85a634687e
Reviewed-on: https://go-review.googlesource.com/c/tools/+/171018
Run-TryBot: Michael Matloob <matloob@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
This commit is contained in:
Michael Matloob 2019-04-05 17:46:00 -04:00
parent 0fdf0c7385
commit cb42bbeb79
2 changed files with 50 additions and 26 deletions

View File

@ -761,8 +761,15 @@ func invokeGo(cfg *Config, args ...string) (*bytes.Buffer, error) {
// the error in the Err section of stdout in case -e option is provided.
// This fix is provided for backwards compatibility.
if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "named files must be .go files") {
output := fmt.Sprintf(`{"ImportPath": "","Incomplete": true,"Error": {"Pos": "","Err": %s}}`,
strconv.Quote(strings.Trim(stderr.String(), "\n")))
output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
strings.Trim(stderr.String(), "\n"))
return bytes.NewBufferString(output), nil
}
// Workaround for #29280: go list -e has incorrect behavior when an ad-hoc package doesn't exist.
if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "no such file or directory") {
output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
strings.Trim(stderr.String(), "\n"))
return bytes.NewBufferString(output), nil
}

View File

@ -313,29 +313,6 @@ func TestLoadAbsolutePath(t *testing.T) {
}
}
func TestReturnErrorWhenUsingNonGoFiles(t *testing.T) {
exported := packagestest.Export(t, packagestest.GOPATH, []packagestest.Module{{
Name: "golang.org/gopatha",
Files: map[string]interface{}{
"a/a.go": `package a`,
}}, {
Name: "golang.org/gopathb",
Files: map[string]interface{}{
"b/b.c": `package b`,
}}})
defer exported.Cleanup()
config := packages.Config{}
_, err := packages.Load(&config, "a/a.go", "b/b.c")
if err == nil {
t.Fatalf("should have failed with an error")
}
got := err.Error()
want := "named files must be .go files"
if !strings.Contains(got, want) {
t.Fatalf("want error message: %s, got: %s", want, got)
}
}
func TestVendorImports(t *testing.T) {
exported := packagestest.Export(t, packagestest.GOPATH, []packagestest.Module{{
Name: "golang.org/fake",
@ -1723,7 +1700,47 @@ func testErrorMissingFile(t *testing.T, exporter packagestest.Exporter) {
if err != nil {
t.Fatal(err)
}
t.Log(pkgs)
if len(pkgs) == 0 && runtime.GOOS == "windows" {
t.Skip("Issue #31344: the ad-hoc command-line-arguments package isn't created on windows")
}
if len(pkgs) != 1 || pkgs[0].PkgPath != "command-line-arguments" {
t.Fatalf("packages.Load: want [command-line-arguments], got %v", pkgs)
}
if len(pkgs[0].Errors) == 0 {
t.Errorf("result of Load: want package with errors, got none: %+v", pkgs[0])
}
}
func TestReturnErrorWhenUsingNonGoFiles(t *testing.T) {
packagestest.TestAll(t, testReturnErrorWhenUsingNonGoFiles)
}
func testReturnErrorWhenUsingNonGoFiles(t *testing.T, exporter packagestest.Exporter) {
exported := packagestest.Export(t, exporter, []packagestest.Module{{
Name: "golang.org/gopatha",
Files: map[string]interface{}{
"a/a.go": `package a`,
}}, {
Name: "golang.org/gopathb",
Files: map[string]interface{}{
"b/b.c": `package b`,
}}})
defer exported.Cleanup()
config := packages.Config{}
pkgs, err := packages.Load(&config, "a/a.go", "b/b.c")
if err != nil {
t.Fatal(err)
}
if len(pkgs) != 1 || pkgs[0].PkgPath != "command-line-arguments" {
t.Fatalf("packages.Load: want [command-line-arguments], got %v", pkgs)
}
if len(pkgs[0].Errors) != 1 {
t.Fatalf("result of Load: want package with one error, got: %+v", pkgs[0])
}
got := pkgs[0].Errors[0].Error()
want := "named files must be .go files"
if !strings.Contains(got, want) {
t.Fatalf("want error message: %s, got: %s", want, got)
}
}
func errorMessages(errors []packages.Error) []string {