github.com/bazelbuild/bazel-gazelle@v0.36.1-0.20240520142334-61b277ba6fed/extend.md (about) 1 <!-- Generated with Stardoc: http://skydoc.bazel.build --> 2 3 Extending Gazelle 4 ================= 5 6 Gazelle started out as a build file generator for Go projects, but it can be 7 extended to support other languages and custom sets of rules. 8 9 To extend Gazelle, you must do three things: 10 11 * Write a [go_library] with a function named `NewLanguage` that provides an 12 implementation of the [Language] interface. This interface provides hooks for 13 generating rules, parsing configuration directives, and resolving imports 14 to Bazel labels. By convention, the library's package name should match 15 the language (for example, `proto` or `bzl`). 16 * Write a [gazelle_binary](#gazelle_binary) rule. Include your library in the `languages` 17 list. 18 * Write a [gazelle] rule that points to your `gazelle_binary`. When you run 19 `bazel run //:gazelle`, your binary will be built and executed instead of 20 the default binary. 21 22 Tests 23 ----- 24 25 To write tests for your gazelle extension, you can use [gazelle_generation_test](#gazelle_generation_test), 26 which will run a gazelle binary of your choosing on a set of test workspaces. 27 28 29 Supported languages 30 ------------------- 31 32 Moved to [/README.rst](/README.rst#supported-languages) 33 34 Example 35 ------- 36 37 Gazelle itself is built using the model described above, so it may serve as 38 an example. 39 40 [//language/proto:go_default_library] and [//language/go:go_default_library] 41 both implement the [Language] 42 interface. There is also [//internal/gazellebinarytest:go_default_library], 43 a stub implementation used for testing. 44 45 `//cmd/gazelle` is a `gazelle_binary` rule that includes both of these 46 libraries through the `DEFAULT_LANGUAGES` list (you may want to use 47 `DEFAULT_LANGUAGES` in your own rule). 48 49 ```starlark 50 load("@bazel_gazelle//:def.bzl", "DEFAULT_LANGUAGES", "gazelle_binary") 51 52 gazelle_binary( 53 name = "gazelle", 54 languages = [ 55 "@rules_python//gazelle", # Use gazelle from rules_python. 56 "@bazel_gazelle//language/go", # Built-in rule from gazelle for Golang. 57 "@bazel_gazelle//language/proto", # Built-in rule from gazelle for Protos. 58 # Any languages that depend on Gazelle's proto plugin must come after it. 59 "@external_repository//language/gazelle", # External languages can be added here. 60 ], 61 visibility = ["//visibility:public"], 62 ) 63 ``` 64 65 This binary can be invoked using a `gazelle` rule like this: 66 67 ```starlark 68 load("@bazel_gazelle//:def.bzl", "gazelle") 69 70 # gazelle:prefix example.com/project 71 gazelle( 72 name = "gazelle", 73 gazelle = "//:my_gazelle_binary", 74 ) 75 ``` 76 77 You can run this with `bazel run //:gazelle`. 78 79 Interacting with protos 80 ----------------------- 81 82 The proto extension ([//language/proto:go_default_library]) gathers metadata 83 from .proto files and generates `proto_library` rules based on that metadata. 84 Extensions that generate language-specific proto rules (e.g., 85 `go_proto_library`) may use this metadata. 86 87 For API reference, see the [proto godoc]. 88 89 To get proto configuration information, call [proto.GetProtoConfig]. This is 90 mainly useful for discovering the current proto mode. 91 92 To get information about `proto_library` rules, examine the `OtherGen` 93 list of rules passed to `language.GenerateRules`. This is a list of rules 94 generated by other language extensions, and it will include `proto_library` 95 rules in each directory, if there were any. For each of these rules, you can 96 call `r.PrivateAttr(proto.PackageKey)` to get a [proto.Package] record. This 97 includes the proto package name, as well as source names, imports, and options. 98 99 [Language]: https://godoc.org/github.com/bazelbuild/bazel-gazelle/language#Language 100 [//internal/gazellebinarytest:go_default_library]: https://github.com/bazelbuild/bazel-gazelle/tree/master/internal/gazellebinarytest 101 [//language/go:go_default_library]: https://github.com/bazelbuild/bazel-gazelle/tree/master/language/go 102 [//language/proto:go_default_library]: https://github.com/bazelbuild/bazel-gazelle/tree/master/language/proto 103 [gazelle]: https://github.com/bazelbuild/bazel-gazelle#bazel-rule 104 [go_binary]: https://github.com/bazelbuild/rules_go/blob/master/go/core.rst#go-binary 105 [go_library]: https://github.com/bazelbuild/rules_go/blob/master/go/core.rst#go-library 106 [proto godoc]: https://godoc.org/github.com/bazelbuild/bazel-gazelle/language/proto 107 [proto.GetProtoConfig]: https://godoc.org/github.com/bazelbuild/bazel-gazelle/language/proto#GetProtoConfig 108 [proto.Package]: https://godoc.org/github.com/bazelbuild/bazel-gazelle/language/proto#Package 109 110 <a id="gazelle_binary"></a> 111 112 ## gazelle_binary 113 114 <pre> 115 gazelle_binary(<a href="#gazelle_binary-name">name</a>, <a href="#gazelle_binary-languages">languages</a>) 116 </pre> 117 118 The `gazelle_binary` rule builds a Go binary that incorporates a list of 119 language extensions. This requires generating a small amount of code that 120 must be compiled into Gazelle's main package, so the normal [go_binary] 121 rule is not used. 122 123 When the binary runs, each language extension is run sequentially. This affects 124 the order that rules appear in generated build files. Metadata may be produced 125 by an earlier extension and consumed by a later extension. For example, the 126 proto extension stores metadata in hidden attributes of generated 127 `proto_library` rules. The Go extension uses this metadata to generate 128 `go_proto_library` rules. 129 130 **ATTRIBUTES** 131 132 133 | Name | Description | Type | Mandatory | Default | 134 | :------------- | :------------- | :------------- | :------------- | :------------- | 135 | <a id="gazelle_binary-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | | 136 | <a id="gazelle_binary-languages"></a>languages | A list of language extensions the Gazelle binary will use.<br><br>Each extension must be a [go_library] or something compatible. Each extension must export a function named `NewLanguage` with no parameters that returns a value assignable to [Language]. | <a href="https://bazel.build/concepts/labels">List of labels</a> | required | | 137 138 139 <a id="gazelle_generation_test"></a> 140 141 ## gazelle_generation_test 142 143 <pre> 144 gazelle_generation_test(<a href="#gazelle_generation_test-name">name</a>, <a href="#gazelle_generation_test-gazelle_binary">gazelle_binary</a>, <a href="#gazelle_generation_test-test_data">test_data</a>, <a href="#gazelle_generation_test-build_in_suffix">build_in_suffix</a>, <a href="#gazelle_generation_test-build_out_suffix">build_out_suffix</a>, 145 <a href="#gazelle_generation_test-gazelle_timeout_seconds">gazelle_timeout_seconds</a>, <a href="#gazelle_generation_test-size">size</a>, <a href="#gazelle_generation_test-kwargs">kwargs</a>) 146 </pre> 147 148 gazelle_generation_test is a macro for testing gazelle against workspaces. 149 150 The generation test expects a file structure like the following: 151 152 ``` 153 |-- <testDataPath> 154 |-- some_test 155 |-- WORKSPACE 156 |-- README.md --> README describing what the test does. 157 |-- arguments.txt --> newline delimited list of arguments to pass in (ignored if empty). 158 |-- expectedStdout.txt --> Expected stdout for this test. 159 |-- expectedStderr.txt --> Expected stderr for this test. 160 |-- expectedExitCode.txt --> Expected exit code for this test. 161 |-- app 162 |-- sourceFile.foo 163 |-- BUILD.in --> BUILD file prior to running gazelle. 164 |-- BUILD.out --> BUILD file expected after running gazelle. 165 ``` 166 167 To update the expected files, run `UPDATE_SNAPSHOTS=true bazel run //path/to:the_test_target`. 168 169 170 **PARAMETERS** 171 172 173 | Name | Description | Default Value | 174 | :------------- | :------------- | :------------- | 175 | <a id="gazelle_generation_test-name"></a>name | The name of the test. | none | 176 | <a id="gazelle_generation_test-gazelle_binary"></a>gazelle_binary | The name of the gazelle binary target. For example, //path/to:my_gazelle. | none | 177 | <a id="gazelle_generation_test-test_data"></a>test_data | A list of target of the test data files you will pass to the test. This can be a https://bazel.build/reference/be/general#filegroup. | none | 178 | <a id="gazelle_generation_test-build_in_suffix"></a>build_in_suffix | The suffix for the input BUILD.bazel files. Defaults to .in. By default, will use files named BUILD.in as the BUILD files before running gazelle. | `".in"` | 179 | <a id="gazelle_generation_test-build_out_suffix"></a>build_out_suffix | The suffix for the expected BUILD.bazel files after running gazelle. Defaults to .out. By default, will use files named check the results of the gazelle run against files named BUILD.out. | `".out"` | 180 | <a id="gazelle_generation_test-gazelle_timeout_seconds"></a>gazelle_timeout_seconds | <p align="center"> - </p> | `2` | 181 | <a id="gazelle_generation_test-size"></a>size | Specifies a test target's "heaviness": how much time/resources it needs to run. | `None` | 182 | <a id="gazelle_generation_test-kwargs"></a>kwargs | Attributes that are passed directly to the test declaration. | none | 183 184