bazel-contrib / bazel-gazelle

Gazelle is a Bazel build file generator for Bazel projects. It natively supports Go and protobuf, and it may be extended to support new languages and custom rule sets.
Apache License 2.0
1.19k stars 379 forks source link

Cyclical Indirect Dependencies & Go.work can cause divergence #1797

Open stefanpenner opened 5 months ago

stefanpenner commented 5 months ago

Note: There is a known limitation associated with PR #1731. After discussion, we've decided to proceed with that PR despite the limitation. This issue will serve as a placeholder for future exploration and work to address the limitation.

Also Note: it is strongly recommended, even once support is added, to avoid these Dependency Cycles, especially when they cross workspace boundaries. Debugging and resolving headaches due to such cycles is the leading cause of early aging in software developers...

What version of gazelle are you using?

908ba7429a903b10bc324cf624eb8517b528b7fa

What version of rules_go are you using?

N/A

What version of Bazel are you using?

7.1.x

Does this issue reproduce with the latest releases of all the above?

Yes

What operating system and processor architecture are you using?

N/A

What did you do?

Given Go Modules A, B, C, where:

What did you expect to see?

C's dependency on A should be that of A in specified in the go.work.

What did you see instead?

C's dependency on A is the version specified in C's go.mod, rather then A in the workspace.

stefanpenner commented 5 months ago

After exploring potential solutions, I believe it might be beneficial to expand Gazelle's capabilities to allow it to resolve a package within an indirect dependency, not as an external go.mod but as a target within the root workspace.

Then at the time go_repository invokes gazelle in external go.mod's we pass in the appropriate resolution parameters to ensure the right targets are used.

Although gazelle today does support resolution overrides, they today require exhaustive target lists, which if used as-is would greatly complicate the implementation. Alternatively, if we could instead merely adjust the resolution repo target root, we could keep this simple.

For instance, currently, the naming convention algorithm transforms a module identifier like my.go.mod.com/foo into com_mod_go_my_foo. However, by implementing a mapping override feature, we could directly link my.go.mod.com/foo to the corresponding go.mod label in our workspace.