Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cmd/autogazelle: bazel wrapper for automatically updating build files (…
- Loading branch information
Showing
278 changed files
with
184,856 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") | ||
|
||
go_library( | ||
name = "go_default_library", | ||
srcs = [ | ||
"autogazelle.go", | ||
"client_unix.go", | ||
"server_unix.go", | ||
], | ||
importpath = "github.com/bazelbuild/bazel-gazelle/cmd/autogazelle", | ||
visibility = ["//visibility:private"], | ||
deps = select({ | ||
"@io_bazel_rules_go//go/platform:darwin": [ | ||
"//vendor/github.com/fsnotify/fsnotify:go_default_library", | ||
], | ||
"@io_bazel_rules_go//go/platform:dragonfly": [ | ||
"//vendor/github.com/fsnotify/fsnotify:go_default_library", | ||
], | ||
"@io_bazel_rules_go//go/platform:freebsd": [ | ||
"//vendor/github.com/fsnotify/fsnotify:go_default_library", | ||
], | ||
"@io_bazel_rules_go//go/platform:linux": [ | ||
"//vendor/github.com/fsnotify/fsnotify:go_default_library", | ||
], | ||
"@io_bazel_rules_go//go/platform:nacl": [ | ||
"//vendor/github.com/fsnotify/fsnotify:go_default_library", | ||
], | ||
"@io_bazel_rules_go//go/platform:netbsd": [ | ||
"//vendor/github.com/fsnotify/fsnotify:go_default_library", | ||
], | ||
"@io_bazel_rules_go//go/platform:openbsd": [ | ||
"//vendor/github.com/fsnotify/fsnotify:go_default_library", | ||
], | ||
"@io_bazel_rules_go//go/platform:solaris": [ | ||
"//vendor/github.com/fsnotify/fsnotify:go_default_library", | ||
], | ||
"//conditions:default": [], | ||
}), | ||
) | ||
|
||
go_binary( | ||
name = "autogazelle", | ||
embed = [":go_default_library"], | ||
visibility = ["//visibility:public"], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
Autogazelle: fast, automatic build file generation | ||
================================================== | ||
|
||
.. _cmd/autogazelle/autogazelle.bash: autogazelle.bash | ||
|
||
Autogazelle is a wrapper program that runs Gazelle as part of each | ||
Bazel command. You can add, delete, or rename source files, add imports, then | ||
just ``bazel build``. Your build files are updated automatically during the | ||
build. | ||
|
||
*Autogazelle is highly experimental and may change significantly in the future. | ||
Use with caution. See* `Limitations`_ *below.* | ||
|
||
Setting up autogazelle | ||
---------------------- | ||
|
||
Before you begin | ||
~~~~~~~~~~~~~~~~ | ||
|
||
Make sure the ``bazel_gazelle`` repository is declared in your ``WORKSPACE``. | ||
It should look the the snippet below, but the versions will likely be different. | ||
It may be possible to used Autogazelle from a vendored ``bazel_gazelle`` | ||
repository, but this is not directly supported yet. | ||
|
||
.. code:: bzl | ||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") | ||
http_archive( | ||
name = "io_bazel_rules_go", | ||
urls = ["https://github.com/bazelbuild/rules_go/releases/download/0.15.4/rules_go-0.15.4.tar.gz"], | ||
sha256 = "7519e9e1c716ae3c05bd2d984a42c3b02e690c5df728dc0a84b23f90c355c5a1", | ||
) | ||
http_archive( | ||
name = "bazel_gazelle", | ||
urls = ["https://github.com/bazelbuild/bazel-gazelle/releases/download/0.14.0/bazel-gazelle-0.14.0.tar.gz"], | ||
sha256 = "c0a5739d12c6d05b6c1ad56f2200cb0b57c5a70e03ebd2f7b87ce88cabf09c7b", | ||
) | ||
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains") | ||
go_rules_dependencies() | ||
go_register_toolchains() | ||
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") | ||
gazelle_dependencies() | ||
Make sure you have a ``gazelle`` rule declared in your root build file. | ||
It should look this this, probably with different options. | ||
|
||
.. code:: bzl | ||
load("@bazel_gazelle//:def.bzl", "gazelle") | ||
# gazelle:prefix github.com/example/project | ||
gazelle(name = "gazelle") | ||
Installing the wrapper | ||
~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
In order to run autogazelle as part of each Bazel command, you'll need to | ||
copy `cmd/autogazelle/autogazelle.bash`_ to ``tools/bazel`` within your | ||
repository. Make sure the script is executable. The ``bazel`` script in | ||
your ``PATH`` will execute this script instead of the real ``bazel`` binary | ||
if it's present and executable. | ||
|
||
Deleting build files | ||
~~~~~~~~~~~~~~~~~~~~ | ||
|
||
If your build files are completely generated by Gazelle, you may want to | ||
delete them from source control, since they can be easily regenerated. | ||
When Gazelle generates new files, it names them ``BUILD.bazel`` by default, | ||
so you can add ``BUILD.bazel`` to your ``.gitignore`` file after deleting | ||
them. | ||
|
||
It's likely that you'll have some build files with manual modifications | ||
you want to keep around. At minimum, you'll need to keep the root build | ||
file since it contains the ``gazelle`` rule. The simplest way to keep these | ||
files is to name the ``BUILD`` instead of ``BUILD.bazel``. Bazel and Gazelle | ||
will both recognize files named ``BUILD``, and Git will not ignore them. | ||
|
||
Another option is to name your files ``BUILD.bazel.in`` or ``BUILD.in``. | ||
Autogazelle will copy these files to ``BUILD.bazel`` or ``BUILD`` when it | ||
starts running before invoking Gazelle. | ||
|
||
How autogazelle works | ||
--------------------- | ||
|
||
Autogazelle has three components: a wrapper script, a client, and a server. | ||
|
||
The *wrapper script* is a bash script installed in ``tools/bazel`` in workspaces | ||
that use autogazelle. The ``bazel`` command installed in your ``PATH`` will look | ||
for an executable file at this location and will execute it instead of the real | ||
bazel. The script builds and runs the *autogazelle client* using ``bazel run`` | ||
before invoking the real bazel binary with the original command-line arguments. | ||
|
||
The *client* is a Go program that attempts to connect to the *server* | ||
over a UNIX domain socket. If the server isn't running, the client will | ||
start it and connect. Once connected, the client will wait for the server | ||
to disconnect before exiting. The client does no other work. | ||
|
||
The *server* is a Go program (actually the same binary as the client, started | ||
with different options) that listens for connections on a UNIX domain socket. | ||
When it accepts a connection, it runs Gazelle using ``bazel run``, then closes | ||
the connection. The socket is just used to make the client wait until Gazelle | ||
completes; no information is exchanged, other than log messages. While the | ||
server is waiting for a connection, it watches the file system for changes that | ||
could affect build files. When the server runs Gazelle, it runs only in | ||
directories that have changed. This makes Gazelle run much faster. The server | ||
exits after being idle for an hour. | ||
|
||
Limitations | ||
----------- | ||
|
||
Dependency resolution | ||
~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
Autogazelle tries to run Gazelle quickly by only updating certain | ||
directories. To support this, it runs Gazelle with the flags ``-r=false`` | ||
(don't recurse through selected directories) and ``-index=false`` (don't | ||
build an index of library targets for dependency resolution). This means | ||
that you'll need to set ``external = "vendored"`` explicitly on your ``gazelle`` | ||
rule if you have a vendor directory, and you'll need to add | ||
``# gazelle:resolve`` directives in your root build files for any imports | ||
that should be resolved to custom names. | ||
|
||
Platform support | ||
~~~~~~~~~~~~~~~~ | ||
|
||
Autogazelle uses UNIX-domain sockets to synchronize the client and server. This | ||
only works on UNIX-like platforms; these sockets are not supported on Windows. | ||
|
||
Autogazelle uses ``github.com/fsnotify/fsnotify`` to watch the file system. This | ||
library works on multiple platforms, but it won't work on file systems that | ||
don't support watches (e.g., NFS and most other network file systems). | ||
|
||
Autogazelle has only been tested on Linux. It is intended to work on macOS, but | ||
this has not been tested yet. | ||
|
||
Credits | ||
------- | ||
|
||
The original idea for running Gazelle automatically was proposed by Matthew | ||
Moore (@mattmoor). The initial plan was to run Gazelle in a repository rule | ||
which regenerate a repository full of build files on each run. | ||
|
||
Erick Fejta (@fejta) prototyped this idea for Kubernetes. You can find the | ||
prototype at https://github.com/kubernetes/test-infra/tree/master/autogo. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#!/bin/bash | ||
|
||
# Copyright 2017 The Bazel Authors. All rights reserved. | ||
|
||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
|
||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
|
||
# autogazelle.bash is a bazel wrapper script that runs gazelle automatically | ||
# before running bazel commands. See autogazelle.go for details. | ||
# | ||
# This script may be installed at tools/bazel in your workspace. It must | ||
# be executable. | ||
|
||
set -euo pipefail | ||
|
||
case "$1" in | ||
build|coverage|cquery|fetch|mobile-install|print_action|query|run|test) | ||
"$BAZEL_REAL" run @bazel_gazelle//cmd/autogazelle -- -gazelle=//:gazelle | ||
echo "done running autogazelle" >&1 | ||
;; | ||
esac | ||
|
||
exec "$BAZEL_REAL" "$@" |
Oops, something went wrong.