gopackagesdriver: dependencies missing from Imports of _xtest targets
What version of rules_go are you using?
v0.48.1
What version of gazelle are you using?
v0.35.0
What version of Bazel are you using?
7.2.1
Does this issue reproduce with the latest releases of all the above?
Yes.
What operating system and processor architecture are you using?
Darwin aarch64
Any other potentially useful information about your toolchain?
No.
What did you do?
A ready-to-run example of this minimal reproduction can be found at https://github.com/dt/externdemo but is described step by step below:
Create two packages, foo and bar, such that bar depends on foo.
foo/foo.go
package foo
func Foo() {}
bar/bar.go
package bar
import "github.com/dt/externdemo/foo"
func Bar() { foo.Foo() }
Now create two files in a test target, one in package foo and one in foo_test, i.e. an xtest package. Ensure that foo xtest file depends on the bar package, which transitively depends on foo:
foo/foo_test.go
package foo
func FooTest() {}
and then the external one:
foo/foo_external_test.go
package foo_test
import "github.com/dt/externdemo/bar"
func FooTestExt() {bar.Bar()}
Construct BUILD files accordingly, for example with bazel run :gazelle. Specifically, in foo/BUILD.bazel:
go_library(
name = "foo", srcs = ["foo.go"], ...
)
go_test(
name = "foo_test",
srcs = [
"foo_external_test.go",
"foo_test.go",
],
embed = [":foo"],
deps = ["//pkg/bar"],
)
Finally, ask gopackagesdriver about foo_external_test.go, e.g.
echo "{}" | bazel run -- @io_bazel_rules_go//go/tools/gopackagesdriver file=./foo/foo_external_test.go
What did you expect to see?
In the Imports section for the entry in Packages returned by gopackagesdriver, for package foo_xtest, I expected to see //bar. In my editor, I expected normal completions and type highlighting for bar.
What did you see instead?
bar is is not included in foo_test's deps.
e.g. echo "{}" | bazel run -- @io_bazel_rules_go//go/tools/gopackagesdriver file=./pkg/foo/foo_external_test.go 2>/dev/null | jq '.Packages | .[] | select(.ID | contains("/foo") ) | .ID, .Imports':
"@@//pkg/foo:foo_test_xtest"
{
"github.com/dt/externdemo/pkg/foo": "@@//pkg/foo:foo_test"
}
"@@//pkg/foo:foo_test"
null
In my editor (vscode) this then manifests as failing to resolve types or completions on bar and the import being shown with an error:
could not import github.com/dt/externdemo/bar (missing metadata for import of "github.com/dt/externdemo/bar")compiler[BrokenImport](https://pkg.go.dev/golang.org/x/tools/internal/typesinternal#BrokenImport)
Note that this seems to only happen when the package depended on by the xtest package in turn depends on the non-test package, i.e. that xtest is required to break the circular dep, and when there is also a non xtest test package.
If all test files declare the xtext package, the _xtest target isn't synthesized and the _test target does include the import of the library; the library import only vanishes (despite being the BUILD file) when there is a separate synthesized xtest target and is the library would be a circular dep with the non-test package.
I'm seeing the same in x_test style packages, no real workaround I've found so far has worked aside from splitting the go_test definitions manually in the BUILD.bazel files