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.