Rules_go: Build Gazelle with the same version of Gazelle as the workspace

Created on 21 Jun 2017  路  7Comments  路  Source: bazelbuild/rules_go

The current workflow for running Gazelle is:

$ go get github.com/bazelbuild/rules_go/go/tools/gazelle
$ gazelle

There are a couple problems with this. First, it requires the user to have a working Go SDK installed, which is otherwise not needed. Second, the version of Gazelle won't match the version of the rules being used.

In workspaces that use Gazelle, it should be possible to run the command using bazel run //:gazelle. When Gazelle creates the BUILD file at the repository root, it could add an alias to itself here.

enhancement gazelle

Most helpful comment

With updated rules you can now add

load("@io_bazel_rules_go//go:def.bzl", "gazelle")
gazelle(name=gazelle)

to your build file. You can also add options if you need. Then use

bazel run //:gazelle

All 7 comments

I currently have a ./scripts/gazelle.sh that uses a copy of bazel-run.sh, some $PWD work, and a buildtools dep in my WORKSPACE to do this. It'd be really handy to have some of that handled for me, instead!

With updated rules you can now add

load("@io_bazel_rules_go//go:def.bzl", "gazelle")
gazelle(name=gazelle)

to your build file. You can also add options if you need. Then use

bazel run //:gazelle

@ianthehat have to quote the name, as in gazelle(name="gazelle"). Then it works :)

Resurrecting this old issue.

bazel run //:gazelle has been in place for a while, and it's been working well (though I think the core Bazel team would not be happy if they knew how it works).

This won't work in the future because Gazelle will need to run Bazel in order to manage external repositories, and it can't do that while the Bazel parent process holds the lock.

I've been tinkering with a PR to change the wrapper script generated by the gazelle rule. It would detect when it's run by Bazel, then tell the user to copy it into their workspace and run it again. When run in the workspace, it would build and run gazelle with some hard-coded arguments.

I'm not happy with that approach for a few reasons, and I don't intend to submit the PR.

  • It's hard to write a portable script because bash probably won't work on Windows. Maybe we could generate .bash or .bat depending on the host OS. Devs would probably want to check this in, so a multi-platform team would have trouble. And it's one more generated file to manage.
  • Once copied to the workspace, the wrapper script can be out of date. It's less likely to be out of date than Gazelle, and it's easy to detect when it needs to be refreshed, but still... that's the problem we're trying to avoid in the first place.
  • The wrapper script doesn't provide that much convenience. It's essentially bazel-run.sh with some hard-coded arguments.

I'd like to propose some changes to replace the gazelle rule. There are two separate problems we're solving here, and I think they should have separate solutions.

  1. We want to store parameters for Gazelle somewhere so it can be invoked consistently and conveniently.
  2. We want to avoid version skew between the Go rules and the running version of Gazelle.

For (1), we can have Gazelle support new directives in build files. For example, # gazelle:prefix, # gazelle:build_tags. This could give us some additional flexibility, since directives could be per-subtree instead of for the whole problems.

(2) is the harder problem, but once we stabilize the Go rules API, version skew won't be that big of an issue. We could manage this using an explicit versioning scheme. The Gazelle binary would be stamped with a version number, and the Go rules would embed a current version number. Additionally, the rules could store a minimum Gazelle version, and Gazelle could be stamped with a minimum rules version. When Gazelle runs, it could determine whether it is too old or too new, then tell the user to rebuild and reinstall if needed.

A major advantage of this approach is that go get -u would again be a reasonable way to update Gazelle. Of course, bazel build, bazel-run.sh, and custom scripts would still work, too.

@ianthehat WDYT?

I agree that we shoud be able to get to the point where no command line arguments are needed, and directives in the BUILD files are enough.
This would mean that

bazel run @io_bazel_rules_go//:gazelle

would work, and if we move gazelle to it's own repository, and load it under the name gazelle then

bazel run @gazelle

would be all you need.
.
I disagree that running gazelle from outside Bazel is the right answer, I think this is a general problem that affects far to many use cases for run, and Bazel as a whole needs a fix for running things without the lock, and if we had that then the above command is as correct and succinct as you can reasonably get

I've emailed bazel-discuss asking if there's a good way to do this. Let's see if they have any ideas. I suspect this will require a change in Bazel that they won't be willing to make.

Closing old Gazelle issues. This one is mostly obsolete.

The gazelle rule (now in @bazel_gazelle//:def.bzl) will continue to be the main way to run Gazelle. It produces a script that may be copied into the workspace and run outside of "bazel run". It doesn't seem like the behavior of "bazel run" will change any time soon.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ohx3ya picture ohx3ya  路  3Comments

prestonvanloon picture prestonvanloon  路  3Comments

dlorenc picture dlorenc  路  7Comments

jarreds picture jarreds  路  7Comments

Globegitter picture Globegitter  路  5Comments