github.com/bazelbuild/bazel-gazelle@v0.36.1-0.20240520142334-61b277ba6fed/cmd/autogazelle/README.rst (about) 1 Autogazelle: fast, automatic build file generation 2 ================================================== 3 4 .. _cmd/autogazelle/autogazelle.bash: autogazelle.bash 5 6 Autogazelle is a wrapper program that runs Gazelle as part of each 7 Bazel command. You can add, delete, or rename source files, add imports, then 8 just ``bazel build``. Your build files are updated automatically during the 9 build. 10 11 *Autogazelle is highly experimental and may change significantly in the future. 12 Use with caution. See* `Limitations`_ *below.* 13 14 Setting up autogazelle 15 ---------------------- 16 17 Before you begin 18 ~~~~~~~~~~~~~~~~ 19 20 Make sure the ``bazel_gazelle`` repository is declared in your ``WORKSPACE``. 21 It should look the the snippet below, but the versions will likely be different. 22 It may be possible to used Autogazelle from a vendored ``bazel_gazelle`` 23 repository, but this is not directly supported yet. 24 25 .. code:: bzl 26 27 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 28 29 http_archive( 30 name = "io_bazel_rules_go", 31 integrity = "sha256-fHbWI2so/2laoozzX5XeMXqUcv0fsUrHl8m/aE8Js3w=", 32 urls = [ 33 "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.44.2/rules_go-v0.44.2.zip", 34 "https://github.com/bazelbuild/rules_go/releases/download/v0.44.2/rules_go-v0.44.2.zip", 35 ], 36 ) 37 38 http_archive( 39 name = "bazel_gazelle", 40 integrity = "sha256-MpOL2hbmcABjA1R5Bj2dJMYO2o15/Uc5Vj9Q0zHLMgk=", 41 urls = [ 42 "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.35.0/bazel-gazelle-v0.35.0.tar.gz", 43 "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.35.0/bazel-gazelle-v0.35.0.tar.gz", 44 ], 45 ) 46 47 load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains") 48 go_rules_dependencies() 49 go_register_toolchains() 50 load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") 51 gazelle_dependencies() 52 53 Make sure you have a ``gazelle`` rule declared in your root build file. 54 It should look this this, probably with different options. 55 56 .. code:: bzl 57 58 load("@bazel_gazelle//:def.bzl", "gazelle") 59 60 # gazelle:prefix github.com/example/project 61 gazelle(name = "gazelle") 62 63 Installing the wrapper 64 ~~~~~~~~~~~~~~~~~~~~~~ 65 66 In order to run autogazelle as part of each Bazel command, you'll need to 67 copy `cmd/autogazelle/autogazelle.bash`_ to ``tools/bazel`` within your 68 repository. Make sure the script is executable. The ``bazel`` script in 69 your ``PATH`` will execute this script instead of the real ``bazel`` binary 70 if it's present and executable. 71 72 Deleting build files 73 ~~~~~~~~~~~~~~~~~~~~ 74 75 If your build files are completely generated by Gazelle, you may want to 76 delete them from source control, since they can be easily regenerated. 77 When Gazelle generates new files, it names them ``BUILD.bazel`` by default, 78 so you can add ``BUILD.bazel`` to your ``.gitignore`` file after deleting 79 them. 80 81 It's likely that you'll have some build files with manual modifications 82 you want to keep around. At minimum, you'll need to keep the root build 83 file since it contains the ``gazelle`` rule. The simplest way to keep these 84 files is to name the ``BUILD`` instead of ``BUILD.bazel``. Bazel and Gazelle 85 will both recognize files named ``BUILD``, and Git will not ignore them. 86 87 Another option is to name your files ``BUILD.bazel.in`` or ``BUILD.in``. 88 Autogazelle will copy these files to ``BUILD.bazel`` or ``BUILD`` when it 89 starts running before invoking Gazelle. 90 91 How autogazelle works 92 --------------------- 93 94 Autogazelle has three components: a wrapper script, a client, and a server. 95 96 The *wrapper script* is a bash script installed in ``tools/bazel`` in workspaces 97 that use autogazelle. The ``bazel`` command installed in your ``PATH`` will look 98 for an executable file at this location and will execute it instead of the real 99 bazel. The script builds and runs the *autogazelle client* using ``bazel run`` 100 before invoking the real bazel binary with the original command-line arguments. 101 102 The *client* is a Go program that attempts to connect to the *server* 103 over a UNIX domain socket. If the server isn't running, the client will 104 start it and connect. Once connected, the client will wait for the server 105 to disconnect before exiting. The client does no other work. 106 107 The *server* is a Go program (actually the same binary as the client, started 108 with different options) that listens for connections on a UNIX domain socket. 109 When it accepts a connection, it runs Gazelle using ``bazel run``, then closes 110 the connection. The socket is just used to make the client wait until Gazelle 111 completes; no information is exchanged, other than log messages. While the 112 server is waiting for a connection, it watches the file system for changes that 113 could affect build files. When the server runs Gazelle, it runs only in 114 directories that have changed. This makes Gazelle run much faster. The server 115 exits after being idle for an hour. 116 117 Limitations 118 ----------- 119 120 Dependency resolution 121 ~~~~~~~~~~~~~~~~~~~~~ 122 123 Autogazelle tries to run Gazelle quickly by only updating certain 124 directories. To support this, it runs Gazelle with the flags ``-r=false`` 125 (don't recurse through selected directories) and ``-index=false`` (don't 126 build an index of library targets for dependency resolution). This means 127 that you'll need to set ``external = "vendored"`` explicitly on your ``gazelle`` 128 rule if you have a vendor directory, and you'll need to add 129 ``# gazelle:resolve`` directives in your root build files for any imports 130 that should be resolved to custom names. 131 132 Platform support 133 ~~~~~~~~~~~~~~~~ 134 135 Autogazelle uses UNIX-domain sockets to synchronize the client and server. This 136 only works on UNIX-like platforms; these sockets are not supported on Windows. 137 138 Autogazelle uses ``github.com/fsnotify/fsnotify`` to watch the file system. This 139 library works on multiple platforms, but it won't work on file systems that 140 don't support watches (e.g., NFS and most other network file systems). 141 142 Autogazelle has only been tested on Linux. It is intended to work on macOS, but 143 this has not been tested yet. 144 145 Credits 146 ------- 147 148 The original idea for running Gazelle automatically was proposed by Matthew 149 Moore (@mattmoor). The initial plan was to run Gazelle in a repository rule 150 which regenerate a repository full of build files on each run. 151 152 Erick Fejta (@fejta) prototyped this idea for Kubernetes. You can find the 153 prototype at https://github.com/kubernetes/test-infra/tree/master/autogo.