Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/tools/go/loader: fails to load packages that contain XTest files that use vendored imports #17556

Closed
nmiyake opened this issue Oct 23, 2016 · 2 comments
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done. Tools This label describes issues relating to any tools in the x/tools repository.
Milestone

Comments

@nmiyake
Copy link
Contributor

nmiyake commented Oct 23, 2016

What version of Go are you using (go version)?

go version go1.7.1 darwin/amd64

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"

What did you do?

  1. Create a directory that contains a vendor directory (mkdir -p foo/vendor/test.com)
  2. Create a vendored package (echo 'package bar' > foo/vendor/test.com/bar.go)
  3. Create a Go test file in the directory that imports a vendored package (echo 'package foo_test; import _ "test.com/bar"' > foo/foo_test.go
  4. Use loadcfg.ImportWithTests("./foo") to specify the package should be imported
  5. Call loadcfg.Load() to load the packages

Full Go test that reproduces the issue:

package main_test

import (
    "io/ioutil"
    "os"
    "path"
    "testing"

    "golang.org/x/tools/go/loader"
)

const (
    bar = `package bar`
    foo = `package foo; import _ "test.com/bar"`
    foo_test = `package foo_test; import _ "test.com/bar"`
)

func TestRepro(t *testing.T) {
    wd, _ := os.Getwd()
    tmpDir, _ := ioutil.TempDir(wd, "")
    defer func() { os.RemoveAll(tmpDir) }()

    ioutil.WriteFile(path.Join(tmpDir, "foo.go"), []byte(foo), 0644)
    barDir := path.Join(tmpDir, "vendor", "test.com", "bar")
    os.MkdirAll(barDir, 0755)
    ioutil.WriteFile(path.Join(barDir, "bar.go"), []byte(bar), 0644)

    loadcfg := loader.Config{}
    loadcfg.ImportWithTests("./" + path.Base(tmpDir))
    // succeeds if non-test file imports vendored package
    if _, err := loadcfg.Load(); err != nil {
        t.Errorf("Error loading package without test")
    }

    // add test file that imports the vendored directory
    ioutil.WriteFile(path.Join(tmpDir, "foo_test.go"), []byte(foo_test), 0644)

    loadcfg = loader.Config{}
    loadcfg.ImportWithTests("./" + path.Base(tmpDir))
    // fails -- only change was adding a test file that imports the same vendored package
    if _, err := loadcfg.Load(); err != nil {
        t.Errorf("Error loading package that contains test that imports vendored library")
    }

    loadcfg = loader.Config{}
    loadcfg.Cwd = tmpDir
    loadcfg.ImportWithTests(".")
    // succeeds with test file if Cwd is set to the directory that is at the same level as the "vendor" directory
    if _, err := loadcfg.Load(); err != nil {
        t.Errorf("Error loading package after Cwd is set")
    }
}

What did you expect to see?

The loadcfg.Load() call should succeed without errors

What did you see instead?

The loadcfg.Load() call returns the following error:

 could not import test.com/bar (cannot find package "test.com/bar" in any of:
        /usr/local/go/src/test.com/bar (from $GOROOT)
        /Volumes/git/go/src/test.com/bar (from $GOPATH))

Notes from investigation

  • This works correctly if the current working directory is at the same level as the "vendor" directory
  • The behavior appears to be correct for non-test files -- if step 3 in the repro steps is replaced with echo 'package foo; import _ "test.com/bar"' > foo/foo.go, then this works
  • This behavior only exists for external test files (package name *_test) -- if step 3 in the repro steps is replaced with echo 'package foo; import _ "test.com/bar"' > foo/foo_test.go, then this works

Seems to be an issue with how the vendor directory is processed, but the behavior of XTest files should match the behavior of non-test and same-package test files (especially since the built-in Go commands like go build and go test handle this correctly).

@nmiyake
Copy link
Contributor Author

nmiyake commented Oct 23, 2016

More concretely, this causes tools that use loader (for example, errcheck and varcheck) to fail when run on projects that have a layout that match the scenario described in this issue.

@nmiyake nmiyake changed the title x/tools/go/loader: fails to load packages that contain tests that use vendored imports x/tools/go/loader: fails to load packages that contain XTest files that use vendored imports Oct 23, 2016
@quentinmit quentinmit added this to the Unreleased milestone Oct 24, 2016
@quentinmit quentinmit added the NeedsFix The path to resolution is known, but the work has not been done. label Oct 24, 2016
@gopherbot gopherbot added the Tools This label describes issues relating to any tools in the x/tools repository. label Sep 12, 2019
@stamblerre
Copy link
Contributor

Since support golang.org/x/tools/go/loader is now deprecated, I'll go ahead and close this issue. Sorry that we never addressed it!

@golang golang locked and limited conversation to collaborators Apr 14, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done. Tools This label describes issues relating to any tools in the x/tools repository.
Projects
None yet
Development

No branches or pull requests

4 participants