Replies: 3 comments 8 replies
-
Thanks for compiling this great summary! I have a few points to add: Without update-repos
With update-repos
But even considering them, at least for languages other than Go, the I think that we should aim to improve the situation by reducing the friction of the "without update-repos" approach, which I believe can be achieved rather easily:
I would be very interested in hearing your thoughts on this. My hope is that this approach allows us to achieve the best outcome for both target demographics: Very low friction for developers that is consistent across rulesets and low maintenance overhead for ruleset maintainers by having everything in Starlark without the need to write a Gazelle plugin for dependency management (BUILD file generation is of course a different story). For the meantime, |
Beta Was this translation helpful? Give feedback.
-
Does this trigger the missing |
Beta Was this translation helpful? Give feedback.
-
I'm not sure I fully understand the implications of the options. So, I'll just present the current For rules_haskell we have a Gazelle extension called gazelle_cabal (Cabal is a Haskell package manager). It goes through a project that may contain multiple Cabal files (Cabal package descriptions). For each Cabal file, it generates Bazel targets corresponding to the components of this package (a package may have multiple library, binary, test components). It resolves dependencies between Cabal packages within the project, and assumes that third-party packages are provided in an external workspace called The What would an alternative approach without We currently don't have a direct line between the Cabal files and the WORKSPACE/MODULE file. So, unless we change that, we would require some intermediate tool that collects all third party dependencies and writes them into WORKSPACE/MODULE. |
Beta Was this translation helpful? Give feedback.
-
Overview
With the introduction of Bazel modules (bzlmod), executing
update-repos
for Go and some other languages is no longer necessary. However, some language implementations do have a use forupdate-repos
(e.g., rules_swift_package_manager) even when bzlmod is enabled. The question to the community is what should become ofupdate-repos
in Gazelle?Developer Experience
This section briefly introduces the developer experience/ergonomics of using a bzlmod-enabled repository with and without
update-repos
. It is not a critique of the implementations. It is meant to describe the developer experience and howupdate-repos
plays into that experience.Go Implementation (without
update-repos
)The current Go implementation moved much of the logic in
update-repos
into thego_deps
extension. The result is that a client needs to do the following to add Go-Gazelle support (see this doc for more details):Initial Setup
Assumption: The
go.mod
file already exists.bazel_dep
declarations forrules_go
andgazelle
to theirMODULE.bazel
file.gazelle(name = "update_build_files")
and agazelle:prefix
directive to theBUILD.bazel
at the workspace's root.mod tidy
usingbazel run @rules_go//go -- mod tidy -v
.bazel run //:update_build_files
.bazel build //...
). Build fails.Assuming that external dependencies are listed in
go.mod
, there should be a build error and a warning about missing declarations in theMODULE.bazel
file. The warning looks like the following:buildozer
command.bazel build //...
. Build succeeds.NOTE: An
update-repos
command was not defined or executed against the repository.Add an External Dependency
To add an external dependency, you do the following:
bazel run @rules_go//go get golang.org/x/text@v0.3.2
.mod tidy
usingbazel run @rules_go//go -- mod tidy -v
.bazel run //:update_build_files
.bazel build //...
). It will fail and provide abuildozer
command.buildozer
command.rules_swift_package_manager
Implementation (withupdate-repos
)The
rules_swift_package_manager
implementation splits the logic for external dependency management between theupdate-repos
implementation and theswift_deps
extension.For details on the use of
rules_swift_package_manager
, please see this doc.Initial Setup
Assumption: The
Package.swift
file already exists.bazel_dep
declarations forrules_swift
,rules_swift_package_manager
andgazelle
to theirMODULE.bazel
file.gazelle(name = "update_build_files")
andgazelle(name = "swift_update_pkgs", command = "update-repos")
to theBUILD.bazel
at the workspace's root. (In actuality,rules_swift_package_manager
provides a macro that defines two flavors ofupdate-repos
targets.)update-repos
command:bazel run //:swift_update_pkgs
.bazel run //:update_build_files
.bazel build //...
.At this point, the developer's build should be green. The reason that this can happen is that the
update-repos
implementation performs a number of steps behind the scenes:swift_deps_index.json
.MODULE.bazel
file with the appropriate extension code (e.g.use_extension
,use_repo
).Add an External Dependency
Package.swift
file with the dependency.update-repos
:bazel run //:swift_update_pkgs
.bazel run //:update_build_files
.bazel build //...
.Comparison of with/without
update-repos
Both types of implementation achieve success for the developer!
Without
update-repos
buildozer
).With
update-repos
update-repos
:build
,bulldozer
,build
update-repos
:update-repos
,build
swift_deps_index.json
Summary
While some languages have moved away from using
update-repos
relying on Bazel's suggestedbuildozer
command, I believe there is real value in languages that provide the extra code generation inupdate-repos
. I propose the following:update-repos
in Gazelle.MODULE.bazel
file easier.What are your thoughts?
Beta Was this translation helpful? Give feedback.
All reactions