@@ -149,3 +149,86 @@ gazelle(
149
149
150
150
That's it, now you can finally run ` bazel run //:gazelle ` anytime
151
151
you edit Python code, and it should update your ` BUILD ` files correctly.
152
+
153
+
154
+ ## Target Types and How They're Generated
155
+
156
+ ### Libraries
157
+
158
+ Python source files are those ending in ` .py ` that are not matched as a test
159
+ file via the ` # gazelle:python_test_file_pattern ` directive. By default,
160
+ python source files are all ` *.py ` files except for ` *_test.py ` and
161
+ ` test_*.py ` .
162
+
163
+ First, we look for the nearest ancestor ` BUILD(.bazel) ` file starting from
164
+ the folder containing the Python source file.
165
+
166
+ + In ` package ` generation mode, if there is no {bzl: obj }` py_library ` in this
167
+ ` BUILD(.bazel) ` file, one is created using the package name as the target's
168
+ name. This makes it the default target in the package. Next, all source
169
+ files are collected into the ` srcs ` of the {bzl: obj }` py_library ` .
170
+ + In ` project ` generation mode, all source files in subdirectories (that don't
171
+ have ` BUILD(.bazel) ` files) are also collected.
172
+ + In ` file ` generation mode, each python source file is given its own target.
173
+
174
+ Finally, the ` import ` statements in the source files are parsed and
175
+ dependencies are added to the ` deps ` attribute of the target.
176
+
177
+
178
+ ### Tests
179
+
180
+ A {bzl: obj }` py_test ` target is added to the ` BUILD(.bazel) ` file when gazelle
181
+ encounters a file named ` __test__.py ` or when files matching the
182
+ ` # gazelle:python_test_file_pattern ` directive are found.
183
+
184
+ For example, if we had a folder that is a package named "foo" we could have a
185
+ Python file named ` foo_test.py ` and gazelle would create a {bzl: obj }` py_test `
186
+ block for the file.
187
+
188
+ The following is an example of a {bzl: obj }` py_test ` target that gazelle would
189
+ add when it encounters a file named ` __test__.py ` .
190
+
191
+ ``` starlark
192
+ py_test(
193
+ name = " build_file_generation_test" ,
194
+ srcs = [" __test__.py" ],
195
+ main = " __test__.py" ,
196
+ deps = [" :build_file_generation" ],
197
+ )
198
+ ```
199
+
200
+ You can control the naming convention for test targets using the
201
+ ` # gazelle:python_test_naming_convention ` directive.
202
+
203
+
204
+ ### Binaries
205
+
206
+ When a ` __main__.py ` file is encountered, this indicates the entry point
207
+ of a Python program. A {bzl: obj }` py_binary ` target will be created, named
208
+ ` [package]_bin ` .
209
+
210
+ When no such entry point exists, Gazelle will look for a line like this in
211
+ the top level in every module:
212
+
213
+ ``` python
214
+ if __name == " __main__" :
215
+ ```
216
+
217
+ Gazelle will create a {bzl: obj }` py_binary ` target for every module with such
218
+ a line, with the target name the same as the module name.
219
+
220
+ If the ` # gazelle:python_generation_mode ` directive is set to ` file ` , then
221
+ instead of one {bzl: obj }` py_binary ` target per module, Gazelle will create
222
+ one {bzl: obj }` py_binary ` target for each file with such a line, and the name
223
+ of the target will match the name of the script.
224
+
225
+ :::{note}
226
+ It's possible for another script to depend on a {bzl: obj }` py_binary ` target
227
+ and import from the {bzl: obj }` py_binary ` 's scripts. This can have possible
228
+ negative effects on Bazel analysis time and runfiles size compared to
229
+ depending on a {bzl: obj }` py_library ` target. The simplest way to avoid these
230
+ negative effects is to extract library code into a separate script without a
231
+ ` main ` line. Gazelle will then create a {bzl: obj }` py_library ` target for
232
+ that library code, and other scripts can depend on that {bzl: obj }` py_library `
233
+ target.
234
+ :::
0 commit comments