Problem
When a scala_binary and scala_library exist in the same package and share source files (via overlapping srcs globs), the binary target can be picked during ambiguous symbol resolution. This causes incorrect dep labels to be emitted — consumers get a dep on the binary instead of the library.
Example
# BUILD
scala_library(
name = "search",
srcs = glob(["*.scala"]),
deps = [...],
)
scala_binary(
name = "opensearch-tester.sh",
srcs = glob(["*.scala"]),
main_class = "com.asana.lunadb.search.OpenSearchTester",
deps = [...],
)
A different package that imports com.asana.lunadb.search.SomeClass may get resolved to //path/to:opensearch-tester.sh instead of //path/to:search.
Root Cause
In scala_rule.go, isImportable() correctly returns false for binary rules (line ~509), which prevents putExports() from being called during rule construction. However, during the resolve phase, the symbol index still sees both targets as providing symbols from the shared source files.
The conflict resolution logic in pkg/resolver/symbol.go has no mechanism to filter out non-importable targets when choosing between conflicting providers. It picks one without checking whether the target is a binary/test rule that shouldn't be importable.
Expected Behavior
Binary and test targets should never win ambiguous resolution against a library target in the same package. Ideally, they should be excluded from the symbol provider index entirely.
Workaround
Users can add explicit # gazelle:resolve directives for affected packages:
# gazelle:resolve scala com.asana.lunadb.search //path/to:search
Environment
- scala-gazelle v0.1.1
- bazel-gazelle v0.45.0
- Affects ~17 packages in our monorepo where binary and library targets share srcs
Problem
When a
scala_binaryandscala_libraryexist in the same package and share source files (via overlappingsrcsglobs), the binary target can be picked during ambiguous symbol resolution. This causes incorrect dep labels to be emitted — consumers get a dep on the binary instead of the library.Example
A different package that imports
com.asana.lunadb.search.SomeClassmay get resolved to//path/to:opensearch-tester.shinstead of//path/to:search.Root Cause
In
scala_rule.go,isImportable()correctly returnsfalsefor binary rules (line ~509), which preventsputExports()from being called during rule construction. However, during the resolve phase, the symbol index still sees both targets as providing symbols from the shared source files.The conflict resolution logic in
pkg/resolver/symbol.gohas no mechanism to filter out non-importable targets when choosing between conflicting providers. It picks one without checking whether the target is a binary/test rule that shouldn't be importable.Expected Behavior
Binary and test targets should never win ambiguous resolution against a library target in the same package. Ideally, they should be excluded from the symbol provider index entirely.
Workaround
Users can add explicit
# gazelle:resolvedirectives for affected packages:Environment