1# Buildifier warnings
2
3Warning categories supported by buildifier's linter:
4
5 * [`attr-applicable_licenses`](#attr-applicable_licenses)
6 * [`attr-cfg`](#attr-cfg)
7 * [`attr-license`](#attr-license)
8 * [`attr-licenses`](#attr-licenses)
9 * [`attr-non-empty`](#attr-non-empty)
10 * [`attr-output-default`](#attr-output-default)
11 * [`attr-package-metadata`](#attr-package-metadata)
12 * [`attr-single-file`](#attr-single-file)
13 * [`build-args-kwargs`](#build-args-kwargs)
14 * [`bzl-visibility`](#bzl-visibility)
15 * [`confusing-name`](#confusing-name)
16 * [`constant-glob`](#constant-glob)
17 * [`ctx-actions`](#ctx-actions)
18 * [`ctx-args`](#ctx-args)
19 * [`deprecated-function`](#deprecated-function)
20 * [`depset-items`](#depset-items)
21 * [`depset-iteration`](#depset-iteration)
22 * [`depset-union`](#depset-union)
23 * [`dict-concatenation`](#dict-concatenation)
24 * [`dict-method-named-arg`](#dict-method-named-arg)
25 * [`duplicated-name`](#duplicated-name)
26 * [`filetype`](#filetype)
27 * [`function-docstring`](#function-docstring)
28 * [`function-docstring-args`](#function-docstring-args)
29 * [`function-docstring-header`](#function-docstring-header)
30 * [`function-docstring-return`](#function-docstring-return)
31 * [`git-repository`](#git-repository)
32 * [`http-archive`](#http-archive)
33 * [`integer-division`](#integer-division)
34 * [`keyword-positional-params`](#keyword-positional-params)
35 * [`list-append`](#list-append)
36 * [`load`](#load)
37 * [`load-on-top`](#load-on-top)
38 * [`module-docstring`](#module-docstring)
39 * [`name-conventions`](#name-conventions)
40 * [`native-android`](#native-android)
41 * [`native-build`](#native-build)
42 * [`native-cc`](#native-cc)
43 * [`native-java`](#native-java)
44 * [`native-package`](#native-package)
45 * [`native-proto`](#native-proto)
46 * [`native-py`](#native-py)
47 * [`no-effect`](#no-effect)
48 * [`out-of-order-load`](#out-of-order-load)
49 * [`output-group`](#output-group)
50 * [`overly-nested-depset`](#overly-nested-depset)
51 * [`package-name`](#package-name)
52 * [`package-on-top`](#package-on-top)
53 * [`positional-args`](#positional-args)
54 * [`print`](#print)
55 * [`provider-params`](#provider-params)
56 * [`redefined-variable`](#redefined-variable)
57 * [`repository-name`](#repository-name)
58 * [`return-value`](#return-value)
59 * [`rule-impl-return`](#rule-impl-return)
60 * [`same-origin-load`](#same-origin-load)
61 * [`skylark-comment`](#skylark-comment)
62 * [`skylark-docstring`](#skylark-docstring)
63 * [`string-iteration`](#string-iteration)
64 * [`uninitialized`](#uninitialized)
65 * [`unnamed-macro`](#unnamed-macro)
66 * [`unreachable`](#unreachable)
67 * [`unsorted-dict-items`](#unsorted-dict-items)
68 * [`unused-variable`](#unused-variable)
69
70### <a name="suppress"></a>How to disable warnings
71
72All warnings can be disabled / suppressed / ignored by adding a special comment `# buildifier: disable=<category_name>` to
73the expression that causes the warning. Historically comments with `buildozer` instead of
74`buildifier` are also supported, they are equivalent.
75
76#### Examples
77
78```python
79# buildifier: disable=no-effect
80"""
81A multiline comment as a string literal.
82
83Docstrings don't trigger the warning if they are first statements of a file or a function.
84"""
85
86if debug:
87 print("Debug information:", foo) # buildifier: disable=print
88```
89
90--------------------------------------------------------------------------------
91
92## <a name="attr-applicable_licenses"></a>Do not use `applicable_licenses` as an attribute name.
93
94 * Category name: `attr-applicable_licenses`
95 * Automatic fix: no
96 * [Suppress the warning](#suppress): `# buildifier: disable=attr-applicable_licenses`
97
98Using `applicable_licenses` as an attribute name may cause unexpected behavior. Its use may be prohibited in future Bazel releases.
99
100--------------------------------------------------------------------------------
101
102## <a name="attr-cfg"></a>`cfg = "data"` for attr definitions has no effect
103
104 * Category name: `attr-cfg`
105 * Flag in Bazel: [`--incompatible_disallow_data_transition`](https://github.com/bazelbuild/bazel/issues/6153)
106 * Automatic fix: yes
107 * [Suppress the warning](#suppress): `# buildifier: disable=attr-cfg`
108
109The [Configuration](https://docs.bazel.build/versions/master/skylark/rules.html#configurations)
110`cfg = "data"` is deprecated and has no effect. Consider removing it.
111The [Configuration](https://docs.bazel.build/versions/master/skylark/rules.html#configurations)
112`cfg = "host"` is deprecated. Consider replacing it with `cfg = "exec"`.
113
114--------------------------------------------------------------------------------
115
116## <a name="attr-license"></a>`attr.license()` is deprecated and shouldn't be used
117
118 * Category name: `attr-license`
119 * Flag in Bazel: `--incompatible_no_attr_license`
120 * Automatic fix: no
121 * [Suppress the warning](#suppress): `# buildifier: disable=attr-license`
122
123The `attr.license()` method is almost never used and being deprecated.
124
125--------------------------------------------------------------------------------
126
127## <a name="attr-licenses"></a>Do not use `licenses` as an attribute name.
128
129 * Category name: `attr-licenses`
130 * Automatic fix: no
131 * [Suppress the warning](#suppress): `# buildifier: disable=attr-licenses`
132
133Using licenses as an attribute name may cause unexpected behavior.
134
135--------------------------------------------------------------------------------
136
137## <a name="attr-non-empty"></a>`non_empty` attribute for attr definitions is deprecated
138
139 * Category name: `attr-non-empty`
140 * Flag in Bazel: `--incompatible_disable_deprecated_attr_params`
141 * Automatic fix: yes
142 * [Suppress the warning](#suppress): `# buildifier: disable=attr-non-empty`
143
144The `non_empty` [attribute](https://docs.bazel.build/versions/master/skylark/lib/attr.html)
145for attr definitions is deprecated, please use `allow_empty` with an opposite value instead.
146
147--------------------------------------------------------------------------------
148
149## <a name="attr-output-default"></a>The `default` parameter for `attr.output()`is deprecated
150
151 * Category name: `attr-output-default`
152 * Flag in Bazel: [`--incompatible_no_output_attr_default`](https://github.com/bazelbuild/bazel/issues/7950)
153 * Automatic fix: no
154 * [Suppress the warning](#suppress): `# buildifier: disable=attr-output-default`
155
156The `default` parameter of `attr.output()` is bug-prone, as two targets of the same rule would be
157unable to exist in the same package under default behavior. Use Starlark macros to specify defaults
158for these attributes instead.
159
160--------------------------------------------------------------------------------
161
162## <a name="attr-package-metadata"></a>Do not use `package_metadata` as an attribute name.
163
164 * Category name: `attr-package-metadata`
165 * Automatic fix: no
166 * Not supported by the latest version of Buildifier
167 * [Suppress the warning](#suppress): `# buildifier: disable=attr-package-metadata`
168
169Using `package_metadata` as an attribute name may cause unexpected behavior. Its use may be prohibited in future Bazel releases.
170
171--------------------------------------------------------------------------------
172
173## <a name="attr-single-file"></a>`single_file` is deprecated
174
175 * Category name: `attr-single-file`
176 * Flag in Bazel: `--incompatible_disable_deprecated_attr_params`
177 * Automatic fix: yes
178 * [Suppress the warning](#suppress): `# buildifier: disable=attr-single-file`
179
180The `single_file` [attribute](https://docs.bazel.build/versions/master/skylark/lib/attr.html)
181is deprecated, please use `allow_single_file` instead.
182
183--------------------------------------------------------------------------------
184
185## <a name="build-args-kwargs"></a>`*args` and `**kwargs` are not allowed in BUILD files
186
187 * Category name: `build-args-kwargs`
188 * Flag in Bazel: `--incompatible_no_kwargs_in_build_files`
189 * Automatic fix: no
190 * [Suppress the warning](#suppress): `# buildifier: disable=build-args-kwargs`
191
192Having `*args` or `**kwargs` makes BUILD files hard to read and manipulate. The list of
193arguments should be explicit.
194
195--------------------------------------------------------------------------------
196
197## <a name="bzl-visibility"></a>Module shouldn't be used directly
198
199 * Category name: `bzl-visibility`
200 * Automatic fix: no
201 * [Suppress the warning](#suppress): `# buildifier: disable=bzl-visibility`
202
203If a directory `foo` contains a subdirectory `internal` or `private`, only files located under `foo`
204can access it.
205
206For example, `dir/rules_mockascript/private/foo.bzl` can be loaded from
207`dir/rules_mockascript/private/bar.bzl` or `dir/rules_mockascript/sub/public.bzl`,
208but not from `dir/other_rule/file.bzl`.
209
210--------------------------------------------------------------------------------
211
212## <a name="confusing-name"></a>Never use `l`, `I`, or `O` as names
213
214 * Category name: `confusing-name`
215 * Automatic fix: no
216 * [Suppress the warning](#suppress): `# buildifier: disable=confusing-name`
217
218The names `l`, `I`, or `O` can be easily confused with `I`, `l`, or `0` correspondingly.
219
220--------------------------------------------------------------------------------
221
222## <a name="constant-glob"></a>Glob pattern has no wildcard ('*')
223
224 * Category name: `constant-glob`
225 * Automatic fix: no
226 * [Suppress the warning](#suppress): `# buildifier: disable=constant-glob`
227
228[Glob function](https://docs.bazel.build/versions/master/be/functions.html#glob)
229is used to get a list of files from the depot. The patterns (the first argument)
230typically include a wildcard (* character). A pattern without a wildcard is
231often useless and sometimes harmful.
232
233To fix the warning, move the string out of the glob:
234
235```diff
236- glob(["*.cc", "test.cpp"])
237+ glob(["*.cc"]) + ["test.cpp"]
238```
239
240**There’s one important difference**: before the change, Bazel would silently
241ignore test.cpp if file is missing; after the change, Bazel will throw an error
242if file is missing.
243
244If `test.cpp` doesn’t exist, the fix becomes:
245
246```diff
247- glob(["*.cc", "test.cpp"])
248+ glob(["*.cc"])
249```
250
251which improves maintenance and readability.
252
253If no pattern has a wildcard, just remove the glob. It will also improve build
254performance (glob can be relatively slow):
255
256```diff
257- glob(["test.cpp"])
258+ ["test.cpp"]
259```
260
261--------------------------------------------------------------------------------
262
263## <a name="ctx-actions"></a>`ctx.{action_name}` is deprecated
264
265 * Category name: `ctx-actions`
266 * Flag in Bazel: [`--incompatible_new_actions_api`](https://github.com/bazelbuild/bazel/issues/5825)
267 * Automatic fix: yes
268 * [Suppress the warning](#suppress): `# buildifier: disable=ctx-actions`
269
270The following [actions](https://docs.bazel.build/versions/master/skylark/lib/actions.html)
271are deprecated, please use the new API:
272
273 * [`ctx.new_file`](https://docs.bazel.build/versions/master/skylark/lib/ctx.html#new_file) → [`ctx.actions.declare_file`](https://docs.bazel.build/versions/master/skylark/lib/actions.html#declare_file)
274 * `ctx.experimental_new_directory` → [`ctx.actions.declare_directory`](https://docs.bazel.build/versions/master/skylark/lib/actions.html#declare_directory)
275 * [`ctx.file_action`](https://docs.bazel.build/versions/master/skylark/lib/ctx.html#file_action) → [`ctx.actions.write`](https://docs.bazel.build/versions/master/skylark/lib/actions.html#write)
276 * [`ctx.action(command = "...")`](https://docs.bazel.build/versions/master/skylark/lib/ctx.html#action) → [`ctx.actions.run_shell`](https://docs.bazel.build/versions/master/skylark/lib/actions.html#run_shell)
277 * [`ctx.action(executable = "...")`](https://docs.bazel.build/versions/master/skylark/lib/ctx.html#action) → [`ctx.actions.run`](https://docs.bazel.build/versions/master/skylark/lib/actions.html#run)
278 * [`ctx.empty_action`](https://docs.bazel.build/versions/master/skylark/lib/ctx.html#empty_action) → [`ctx.actions.do_nothing`](https://docs.bazel.build/versions/master/skylark/lib/actions.html#do_nothing)
279 * [`ctx.template_action`](https://docs.bazel.build/versions/master/skylark/lib/ctx.html#template_action) → [`ctx.actions.expand_template`](https://docs.bazel.build/versions/master/skylark/lib/actions.html#expand_template)
280
281--------------------------------------------------------------------------------
282
283## <a name="ctx-args"></a>`ctx.actions.args().add()` for multiple arguments is deprecated
284
285 * Category name: `ctx-args`
286 * Flag in Bazel: [`--incompatible_disallow_old_style_args_add`](https://github.com/bazelbuild/bazel/issues/5822)
287 * Automatic fix: yes
288 * [Suppress the warning](#suppress): `# buildifier: disable=ctx-args`
289
290It's deprecated to use the [`add`](https://docs.bazel.build/versions/master/skylark/lib/Args.html#add)
291method of `ctx.actions.args()` to add a list (or a depset) of variables. Please use either
292[`add_all`](https://docs.bazel.build/versions/master/skylark/lib/Args.html#add_all) or
293[`add_joined`](https://docs.bazel.build/versions/master/skylark/lib/Args.html#add_joined),
294depending on the desired behavior.
295
296--------------------------------------------------------------------------------
297
298## <a name="deprecated-function"></a>The function is deprecated
299
300 * Category name: `deprecated-function`
301 * Automatic fix: no
302 * [Suppress the warning](#suppress): `# buildifier: disable=deprecated-function`
303
304The function defined in another .bzl file has a docstring stating that it's deprecated, i.e. it
305contains a `Deprecated:` section. The convention for function docstrings is described by
306the [`function-docstring`](#function-docstring) warning.
307
308--------------------------------------------------------------------------------
309
310## <a name="depset-items"></a>Depset's "items" parameter is deprecated
311
312 * Category name: `depset-items`
313 * Flag in Bazel: [`--incompatible_disable_depset_items`](https://github.com/bazelbuild/bazel/issues/9017)
314 * Automatic fix: no
315 * [Suppress the warning](#suppress): `# buildifier: disable=depset-items`
316
317The `items` parameter for [`depset`](https://docs.bazel.build/versions/master/skylark/lib/globals.html#depset)
318is deprecated. In its old form it's either a list of direct elements to be
319added (use the `direct` or unnamed first parameter instead) or a depset that
320becomes a transitive element of the new depset (use the `transitive` parameter
321instead).
322
323--------------------------------------------------------------------------------
324
325## <a name="depset-iteration"></a>Depset iteration is deprecated
326
327 * Category name: `depset-iteration`
328 * Flag in Bazel: [`--incompatible_depset_is_not_iterable`](https://github.com/bazelbuild/bazel/issues/5816)
329 * Automatic fix: yes
330 * [Suppress the warning](#suppress): `# buildifier: disable=depset-iteration`
331
332Depsets are complex structures, iterations over them and lookups require flattening them to
333a list which may be a heavy operation. To make it more obvious it's now required to call
334the `.to_list()` method on them in order to be able to iterate their items:
335
336```python
337deps = depset()
338[x.path for x in deps] # deprecated
339[x.path for x in deps.to_list()] # recommended
340```
341
342--------------------------------------------------------------------------------
343
344## <a name="depset-union"></a>Depsets should be joined using the depset constructor
345
346 * Category name: `depset-union`
347 * Flag in Bazel: [`--incompatible_depset_union`](https://github.com/bazelbuild/bazel/issues/5817)
348 * Automatic fix: no
349 * [Suppress the warning](#suppress): `# buildifier: disable=depset-union`
350
351The following ways to merge two depsets are deprecated:
352
353```python
354depset1 + depset2
355depset1 | depset2
356depset1.union(depset2)
357```
358
359Please use the [depset](https://docs.bazel.build/versions/master/skylark/lib/depset.html) constructor
360instead:
361
362```python
363depset(transitive = [depset1, depset2])
364```
365
366When fixing this issue, make sure you
367[understand depsets](https://docs.bazel.build/versions/master/skylark/depsets.html)
368and try to
369[reduce the number of calls to depset](https://docs.bazel.build/versions/master/skylark/performance.html#reduce-the-number-of-calls-to-depset).
370
371--------------------------------------------------------------------------------
372
373## <a name="dict-concatenation"></a>Dictionary concatenation is deprecated
374
375 * Category name: `dict-concatenation`
376 * Flag in Bazel: [`--incompatible_disallow_dict_plus`](https://github.com/bazelbuild/bazel/issues/6461)
377 * Automatic fix: no
378 * [Suppress the warning](#suppress): `# buildifier: disable=dict-concatenation`
379
380The `+` operator to concatenate dicts is deprecated. The operator used to create a new dict and
381copy the data to it. There are several ways to avoid it, for example, instead of `d = d1 + d2 + d3`
382you can use one of the following:
383
384 * Use [Skylib](https://github.com/bazelbuild/bazel-skylib):
385
386```python
387load("@bazel_skylib//lib:dicts.bzl", "dicts")
388
389d = dicts.add(d1, d2, d3)
390```
391
392 * The same if you don't want to use Skylib:
393
394```python
395d = dict(d1.items() + d2.items() + d3.items())
396```
397
398 * The same in several steps:
399
400```python
401d = dict(d1) # If you don't want `d1` to be mutated
402d.update(d2)
403d.update(d3)
404```
405
406--------------------------------------------------------------------------------
407
408## <a name="dict-method-named-arg"></a>Dict methods do not have a named argument `default`
409
410 * Category name: `dict-method-named-arg`
411 * Automatic fix: no
412 * [Suppress the warning](#suppress): `# buildifier: disable=dict-method-named-arg`
413
414Dict methods `get`, `pop` and `setdefault` do not accept a named argument
415called `default`. Due to a bug, Bazel currently accepts that named argument.
416It is better to use a positional argument instead:
417
418```diff
419- mydict.get(5, default = 0)
420+ mydict.get(5, 0)
421```
422
423--------------------------------------------------------------------------------
424
425## <a name="duplicated-name"></a>A rule with name `foo` was already found on line
426
427 * Category name: `duplicated-name`
428 * Automatic fix: no
429 * [Suppress the warning](#suppress): `# buildifier: disable=duplicated-name`
430
431Each label in Bazel has a unique name, and Bazel doesn’t allow two rules to have
432the same name. With macros, this may be accepted by Bazel (if each macro
433generates different rules):
434
435```python
436my_first_macro(name = "foo")
437my_other_macro(name = "foo")
438```
439
440Although the build may work, this code can be very confusing. It can confuse
441users reading a BUILD file (if they look for the rule “foo”, they may read see
442only one of the macros). It will also confuse tools that edit BUILD files.
443
444To fix the issue just change the name attribute of one rule/macro.
445
446--------------------------------------------------------------------------------
447
448## <a name="filetype"></a>The `FileType` function is deprecated
449
450 * Category name: `filetype`
451 * Flag in Bazel: [`--incompatible_disallow_filetype`](https://github.com/bazelbuild/bazel/issues/5831)
452 * Automatic fix: no
453 * [Suppress the warning](#suppress): `# buildifier: disable=filetype`
454
455The function `FileType` is deprecated. Instead of using it as an argument to the
456[`rule` function](https://docs.bazel.build/versions/master/skylark/lib/globals.html#rule)
457just use a list of strings.
458
459--------------------------------------------------------------------------------
460
461## <a name="function-docstring"></a><a name="function-docstring-header"></a><a name="function-docstring-args"></a><a name="function-docstring-return"></a>Function docstring
462
463 * Category names:
464 * `function-docstring`
465 * `function-docstring-header`
466 * `function-docstring-args`
467 * `function-docstring-return`
468 * Automatic fix: no
469 * [Suppress the warning](#suppress): `# buildifier: disable=function-docstring`, `# buildifier: disable=function-docstring-header`, `# buildifier: disable=function-docstring-args`, `# buildifier: disable=function-docstring-return`
470
471Public functions should have docstrings describing functions and their signatures.
472A docstring is a string literal (not a comment) which should be the first statement
473of a function (it may follow comment lines). Function docstrings are expected to be
474formatted in the following way:
475
476```python
477"""One-line summary: must be followed and may be preceded by a blank line.
478
479Optional additional description like this.
480
481If it's a function docstring and the function has more than one argument, the docstring has
482to document these parameters as follows:
483
484Args:
485 parameter1: description of the first parameter. Each parameter line
486 should be indented by one, preferably two, spaces (as here).
487 parameter2: description of the second
488 parameter that spans two lines. Each additional line should have a
489 hanging indentation of at least one, preferably two, additional spaces (as here).
490 another_parameter (unused, mutable): a parameter may be followed
491 by additional attributes in parentheses
492
493Returns:
494 Description of the return value.
495 Should be indented by at least one, preferably two spaces (as here)
496 Can span multiple lines.
497
498Deprecated:
499 Optional, description of why the function is deprecated and what should be used instead.
500"""
501```
502
503Docstrings are required for all public functions with at least 5 statements. If a docstring exists
504it should start with a one-line summary line followed by an empty line. If a docstring is required
505or it describes some arguments, it should describe all of them. If a docstring is required and
506the function returns a value, it should be described.
507
508--------------------------------------------------------------------------------
509
510## <a name="git-repository"></a>Function `git_repository` is not global anymore
511
512 * Category name: `git-repository`
513 * Flag in Bazel: [`--incompatible_remove_native_git_repository`](https://github.com/bazelbuild/bazel/issues/6569)
514 * Automatic fix: yes
515 * [Suppress the warning](#suppress): `# buildifier: disable=git-repository`
516
517Native `git_repository` and `new_git_repository` functions are removed.
518Please use the Starlark version instead:
519
520```python
521load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
522```
523
524--------------------------------------------------------------------------------
525
526## <a name="http-archive"></a>Function `http_archive` is not global anymore
527
528 * Category name: `http-archive`
529 * Flag in Bazel: [`--incompatible_remove_native_http_archive`](https://github.com/bazelbuild/bazel/issues/6570)
530 * Automatic fix: yes
531 * [Suppress the warning](#suppress): `# buildifier: disable=http-archive`
532
533Native `http_archive` function is removed.
534Please use the Starlark version instead:
535
536```python
537load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
538```
539
540--------------------------------------------------------------------------------
541
542## <a name="integer-division"></a>The `/` operator for integer division is deprecated
543
544 * Category name: `integer-division`
545 * Flag in Bazel: [`--incompatible_disallow_slash_operator`](https://github.com/bazelbuild/bazel/issues/5823)
546 * Automatic fix: yes
547 * [Suppress the warning](#suppress): `# buildifier: disable=integer-division`
548
549The `/` operator is deprecated in favor of `//`, please use the latter for
550integer division:
551
552```python
553a = b // c
554d //= e
555```
556
557--------------------------------------------------------------------------------
558
559## <a name="keyword-positional-params"></a>Keyword parameter should be positional
560
561 * Category name: `keyword-positional-params`
562 * Automatic fix: yes
563 * [Suppress the warning](#suppress): `# buildifier: disable=keyword-positional-params`
564
565Some parameters for builtin functions in Starlark are keyword for legacy reasons;
566their names are not meaningful (e.g. `x`). Making them positional-only will improve
567the readability.
568
569--------------------------------------------------------------------------------
570
571## <a name="list-append"></a>Prefer using `.append()` to adding a single element list
572
573 * Category name: `list-append`
574 * Automatic fix: yes
575 * [Suppress the warning](#suppress): `# buildifier: disable=list-append`
576
577Transforming `x += [expr]` to `x.append(expr)` avoids a list allocation.
578
579--------------------------------------------------------------------------------
580
581## <a name="load"></a>Loaded symbol is unused
582
583 * Category name: `load`
584 * Automatic fix: yes
585 * [Suppress the warning](#suppress): `# buildifier: disable=load`
586
587### Background
588
589[load](https://docs.bazel.build/versions/master/skylark/concepts.html#loading-an-extension)
590is used to import definitions in a BUILD file. If the definition is not used in
591the file, the load can be safely removed. If a symbol is loaded two times, you
592will get a warning on the second occurrence.
593
594### How to fix it
595
596Delete the line. When load is used to import multiple symbols, you can remove
597the unused symbols from the list. To fix your BUILD files automatically, try
598this command:
599
600```bash
601$ buildozer 'fix unusedLoads' path/to/BUILD
602```
603
604If you want to keep the load, you can disable the warning by adding a comment
605`# @unused`.
606
607--------------------------------------------------------------------------------
608
609## <a name="load-on-top"></a>Load statements should be at the top of the file
610
611 * Category name: `load-on-top`
612 * Flag in Bazel: [`--incompatible_bzl_disallow_load_after_statement`](https://github.com/bazelbuild/bazel/issues/5815)
613 * Automatic fix: yes
614 * Not supported by the latest version of Buildifier
615 * [Suppress the warning](#suppress): `# buildifier: disable=load-on-top`
616
617Obsolete; the warning has been implemented in the formatter and the fix is now automatically applied to all files except `WORKSPACE` files (unless suppressed).
618
619Load statements should be first statements (with the exception of `WORKSPACE` files),
620they can follow only comments and docstrings.
621
622--------------------------------------------------------------------------------
623
624## <a name="module-docstring"></a>The file has no module docstring
625
626 * Category name: `module-docstring`
627 * Automatic fix: no
628 * [Suppress the warning](#suppress): `# buildifier: disable=module-docstring`
629
630`.bzl` files should have docstrings on top of them. A docstring is a string literal
631(not a comment) which should be the first statement of the file (it may follow
632comment lines). For example:
633
634```python
635"""
636This module contains build rules for my project.
637"""
638
639...
640```
641
642--------------------------------------------------------------------------------
643
644## <a name="name-conventions"></a>Name conventions
645
646 * Category name: `name-conventions`
647 * Automatic fix: no
648 * [Suppress the warning](#suppress): `# buildifier: disable=name-conventions`
649
650By convention, all variables should be lower_snake_case, constant should be
651UPPER_SNAKE_CASE, and providers should be UpperCamelCase ending with `Info`.
652
653--------------------------------------------------------------------------------
654
655## <a name="native-android"></a>All Android build rules should be loaded from Starlark
656
657 * Category name: `native-android`
658 * Flag in Bazel: [`--incompatible_disable_native_android_rules`](https://github.com/bazelbuild/bazel/issues/8391)
659 * Automatic fix: yes
660 * [Disabled by default](buildifier/README.md#linter)
661 * [Suppress the warning](#suppress): `# buildifier: disable=native-android`
662
663The Android build rules should be loaded from Starlark.
664
665Update: the plans for disabling native rules
666[have been postponed](https://groups.google.com/g/bazel-discuss/c/XNvpWcge4AE/m/aJ-aQzszAwAJ),
667at the moment it's not required to load Starlark rules.
668
669--------------------------------------------------------------------------------
670
671## <a name="native-build"></a>The `native` module shouldn't be used in BUILD files
672
673 * Category name: `native-build`
674 * Automatic fix: yes
675 * [Suppress the warning](#suppress): `# buildifier: disable=native-build`
676
677There's no need in using `native.` in BUILD files, its members are available
678as global symbols there.
679
680--------------------------------------------------------------------------------
681
682## <a name="native-cc"></a>All C++ build rules should be loaded from Starlark
683
684 * Category name: `native-cc`
685 * Flag in Bazel: [`--incompatible_load_cc_rules_from_bzl`](https://github.com/bazelbuild/bazel/issues/8743)
686 * Automatic fix: yes
687 * [Disabled by default](buildifier/README.md#linter)
688 * [Suppress the warning](#suppress): `# buildifier: disable=native-cc`
689
690The CC build rules should be loaded from Starlark.
691
692Update: the plans for disabling native rules
693[have been postponed](https://groups.google.com/g/bazel-discuss/c/XNvpWcge4AE/m/aJ-aQzszAwAJ),
694at the moment it's not required to load Starlark rules.
695
696--------------------------------------------------------------------------------
697
698## <a name="native-java"></a>All Java build rules should be loaded from Starlark
699
700 * Category name: `native-java`
701 * Flag in Bazel: [`--incompatible_load_java_rules_from_bzl`](https://github.com/bazelbuild/bazel/issues/8746)
702 * Automatic fix: yes
703 * [Disabled by default](buildifier/README.md#linter)
704 * [Suppress the warning](#suppress): `# buildifier: disable=native-java`
705
706The Java build rules should be loaded from Starlark.
707
708Update: the plans for disabling native rules
709[have been postponed](https://groups.google.com/g/bazel-discuss/c/XNvpWcge4AE/m/aJ-aQzszAwAJ),
710at the moment it's not required to load Starlark rules.
711
712--------------------------------------------------------------------------------
713
714## <a name="native-package"></a>`native.package()` shouldn't be used in .bzl files
715
716 * Category name: `native-package`
717 * Automatic fix: no
718 * [Suppress the warning](#suppress): `# buildifier: disable=native-package`
719
720It's discouraged and will be disallowed to use `native.package()` in .bzl files.
721It can silently modify the semantics of a BUILD file and makes it hard to maintain.
722
723--------------------------------------------------------------------------------
724
725## <a name="native-proto"></a>All Proto build rules and symbols should be loaded from Starlark
726
727 * Category name: `native-proto`
728 * Flag in Bazel: [`--incompatible_load_proto_rules_from_bzl`](https://github.com/bazelbuild/bazel/issues/8922)
729 * Automatic fix: yes
730 * [Disabled by default](buildifier/README.md#linter)
731 * [Suppress the warning](#suppress): `# buildifier: disable=native-proto`
732
733The Proto build rules should be loaded from Starlark.
734
735Update: the plans for disabling native rules
736[have been postponed](https://groups.google.com/g/bazel-discuss/c/XNvpWcge4AE/m/aJ-aQzszAwAJ),
737at the moment it's not required to load Starlark rules.
738
739--------------------------------------------------------------------------------
740
741## <a name="native-py"></a>All Python build rules should be loaded from Starlark
742
743 * Category name: `native-py`
744 * Flag in Bazel: [`--incompatible_load_python_rules_from_bzl`](https://github.com/bazelbuild/bazel/issues/9006)
745 * Automatic fix: yes
746 * [Disabled by default](buildifier/README.md#linter)
747 * [Suppress the warning](#suppress): `# buildifier: disable=native-py`
748
749The Python build rules should be loaded from Starlark.
750
751Update: the plans for disabling native rules
752[have been postponed](https://groups.google.com/g/bazel-discuss/c/XNvpWcge4AE/m/aJ-aQzszAwAJ),
753at the moment it's not required to load Starlark rules.
754
755--------------------------------------------------------------------------------
756
757## <a name="no-effect"></a>Expression result is not used
758
759 * Category name: `no-effect`
760 * Automatic fix: no
761 * [Suppress the warning](#suppress): `# buildifier: disable=no-effect`
762
763The statement has no effect. Consider removing it or storing its result in a variable.
764
765--------------------------------------------------------------------------------
766
767## <a name="out-of-order-load"></a>Load statements should be ordered by their labels
768
769 * Category name: `out-of-order-load`
770 * Automatic fix: yes
771 * Not supported by the latest version of Buildifier
772 * [Suppress the warning](#suppress): `# buildifier: disable=out-of-order-load`
773
774Obsolete; the warning has been implemented in the formatter and the fix is now automatically applied to all files (unless suppressed).
775
776Load statements should be ordered by their first argument - extension file label.
777This makes it easier to developers to locate loads of interest and reduces chances
778for conflicts when performing large-scale automated refactoring.
779
780When applying automated fixes, it's highly recommended to also use
781[`load-on-top`](#load-on-top) fixes, since otherwise the relative order
782of a symbol load and its usage can change resulting in runtime error.
783
784--------------------------------------------------------------------------------
785
786## <a name="output-group"></a>`ctx.attr.dep.output_group` is deprecated
787
788 * Category name: `output-group`
789 * Flag in Bazel: [`--incompatible_no_target_output_group`](https://github.com/bazelbuild/bazel/issues/7949)
790 * Automatic fix: yes
791 * [Suppress the warning](#suppress): `# buildifier: disable=output-group`
792
793The `output_group` field of a target is deprecated in favor of the
794[`OutputGroupInfo` provider](https://docs.bazel.build/versions/master/skylark/lib/OutputGroupInfo.html).
795
796--------------------------------------------------------------------------------
797
798## <a name="overly-nested-depset"></a>The depset is potentially overly nested
799
800 * Category name: `overly-nested-depset`
801 * Automatic fix: no
802 * [Suppress the warning](#suppress): `# buildifier: disable=overly-nested-depset`
803
804If a depset is iteratively chained in a for loop, e.g. the following pattern is used:
805
806```python
807for ...:
808 x = depset(..., transitive = [..., x, ...])
809```
810
811this can result in an overly nested depset with a long chain of transitive elements. Such patterns
812can lead to performance problems, consider refactoring the code to create a flat list of transitive
813elements and call the depset constructor just once:
814
815```python
816transitive = []
817
818for ...:
819 transitive += ...
820
821x = depset(..., transitive = transitive)
822```
823
824Or in simple cases you can use list comprehensions instead:
825
826```python
827x = depset(..., transitive = [y.deps for y in ...])
828```
829
830For more information, read Bazel documentation about
831[depsets](https://docs.bazel.build/versions/master/skylark/depsets.html)
832and
833[reducing the number of calls to depset](https://docs.bazel.build/versions/master/skylark/performance.html#reduce-the-number-of-calls-to-depset).
834
835--------------------------------------------------------------------------------
836
837## <a name="package-name"></a>Global variable `PACKAGE_NAME` is deprecated
838
839 * Category name: `package-name`
840 * Flag in Bazel: [`--incompatible_package_name_is_a_function`](https://github.com/bazelbuild/bazel/issues/5827)
841 * Automatic fix: yes
842 * [Suppress the warning](#suppress): `# buildifier: disable=package-name`
843
844The global variable `PACKAGE_NAME` is deprecated, please use
845[`native.package_name()`](https://docs.bazel.build/versions/master/skylark/lib/native.html#package_name)
846instead.
847
848--------------------------------------------------------------------------------
849
850## <a name="package-on-top"></a>Package declaration should be at the top of the file
851
852 * Category name: `package-on-top`
853 * Automatic fix: no
854 * [Suppress the warning](#suppress): `# buildifier: disable=package-on-top`
855
856Here is a typical structure of a BUILD file:
857
858 * `load()` statements
859 * `package()`
860 * calls to rules, macros
861
862Instantiating a rule and setting the package defaults later can be very
863confusing, and has been a source of bugs (tools and humans sometimes believe
864package applies to everything in a BUILD file). This might become an error in
865the future.
866
867### What can be used before package()?
868
869The linter allows the following to be before `package()`:
870
871 * comments
872 * `load()`
873 * variable declarations
874 * `package_group()`
875 * `licenses()`
876
877--------------------------------------------------------------------------------
878
879## <a name="positional-args"></a>Keyword arguments should be used over positional arguments
880
881 * Category name: `positional-args`
882 * Automatic fix: no
883 * [Suppress the warning](#suppress): `# buildifier: disable=positional-args`
884
885All top level calls (except for some built-ins) should use keyword args over
886positional arguments. Positional arguments can cause subtle errors if the order
887is switched or if an argument is removed. Keyword args also greatly improve
888readability.
889
890```diff
891- my_macro("foo", "bar")
892+ my_macro(name = "foo", env = "bar")
893```
894
895The linter allows the following functions to be called with positional arguments:
896
897 * `load()`
898 * `vardef()`
899 * `export_files()`
900 * `licenses()`
901 * `print()`
902
903--------------------------------------------------------------------------------
904
905## <a name="print"></a>`print()` is a debug function and shouldn't be submitted
906
907 * Category name: `print`
908 * Automatic fix: no
909 * [Suppress the warning](#suppress): `# buildifier: disable=print`
910
911Using the `print()` function for warnings is discouraged: they are often spammy and
912non actionable, the people who see the warning are usually not the people who can
913fix the code to make the warning disappear, and the actual maintainers of the code
914may never see the warning.
915
916--------------------------------------------------------------------------------
917
918## <a name="provider-params"></a>Calls to `provider` should specify a list of fields and a documentation
919
920 * Category name: `provider-params`
921 * Automatic fix: no
922 * [Suppress the warning](#suppress): `# buildifier: disable=provider-params`
923
924Calls to `provider` should specify a documentation string and a list of fields:
925
926```python
927ServerAddressInfo = provider(
928 "The address of an HTTP server. Fields are host (string) and port (int).",
929 fields = ["host", "port"]
930)
931```
932
933Fields should also be documented when needed:
934
935```python
936ServerAddressInfo = provider(
937 "The address of an HTTP server.",
938 fields = {
939 "host": "string, e.g. 'example.com'",
940 "port": "int, a TCP port number",
941 }
942)
943```
944
945Note that specifying a list of fields is a breaking change. It is an error if a
946call to the provider uses undeclared fields. If you cannot declare the list of
947fields, you may explicitly set it to None (and explain why in a comment).
948
949```python
950AllInfo = provider("This provider accepts any field.", fields = None)
951
952NoneInfo = provider("This provider cannot have fields.", fields = [])
953```
954
955See the [documentation for providers](https://docs.bazel.build/versions/master/skylark/lib/globals.html#provider).
956
957--------------------------------------------------------------------------------
958
959## <a name="redefined-variable"></a>Variable has already been defined
960
961 * Category name: `redefined-variable`
962 * Automatic fix: no
963 * [Suppress the warning](#suppress): `# buildifier: disable=redefined-variable`
964
965### Background
966
967In .bzl files, redefining a global variable is already forbidden. This helps
968both humans and tools reason about the code. For consistency, we want to bring
969this restriction also to BUILD files.
970
971### How to fix it
972
973Rename one of the variables.
974
975Note that the content of lists and dictionaries can still be modified. We will
976forbid reassignment, but not every side-effect.
977
978--------------------------------------------------------------------------------
979
980## <a name="repository-name"></a>Global variable `REPOSITORY_NAME` is deprecated
981
982 * Category name: `repository-name`
983 * Flag in Bazel: [`--incompatible_package_name_is_a_function`](https://github.com/bazelbuild/bazel/issues/5827)
984 * Automatic fix: yes
985 * [Suppress the warning](#suppress): `# buildifier: disable=repository-name`
986
987The global variable `REPOSITORY_NAME` is deprecated, please use
988[`native.repository_name()`](https://docs.bazel.build/versions/master/skylark/lib/native.html#repository_name)
989instead.
990
991--------------------------------------------------------------------------------
992
993## <a name="return-value"></a>Some but not all execution paths of a function return a value
994
995 * Category name: `return-value`
996 * Automatic fix: no
997 * [Suppress the warning](#suppress): `# buildifier: disable=return-value`
998
999Some but not all execution paths of a function return a value. Either there's
1000an explicit empty `return` statement, or an implicit return in the end of a
1001function. If it is intentional, make it explicit using `return None`. If you
1002know certain parts of the code cannot be reached, add the statement
1003`fail("unreachable")` to them.
1004
1005--------------------------------------------------------------------------------
1006
1007## <a name="rule-impl-return"></a>Avoid using the legacy provider syntax
1008
1009 * Category name: `rule-impl-return`
1010 * Automatic fix: no
1011 * [Suppress the warning](#suppress): `# buildifier: disable=rule-impl-return`
1012
1013Returning structs from rule implementation functions is
1014[deprecated](https://docs.bazel.build/versions/master/skylark/rules.html#migrating-from-legacy-providers),
1015consider using
1016[providers](https://docs.bazel.build/versions/master/skylark/rules.html#providers)
1017or lists of providers instead.
1018
1019--------------------------------------------------------------------------------
1020
1021## <a name="same-origin-load"></a>Same label is used for multiple loads
1022
1023 * Category name: `same-origin-load`
1024 * Automatic fix: yes
1025 * Not supported by the latest version of Buildifier
1026 * [Suppress the warning](#suppress): `# buildifier: disable=same-origin-load`
1027
1028Obsolete; the warning has been implemented in the formatter and the fix is now automatically applied to all files except `WORKSPACE` files (unless suppressed).
1029
1030### Background
1031
1032[load](https://docs.bazel.build/versions/master/skylark/concepts.html#loading-an-extension)
1033is used to import definitions in a BUILD file. If the same label is used for loading
1034symbols more the ones, all such loads can be merged into a single one.
1035
1036### How to fix it
1037
1038Merge all loads into a single one. For example,
1039
1040```python
1041load(":f.bzl", "s1")
1042load(":f.bzl", "s2")
1043```
1044
1045can be written more compactly as
1046
1047```python
1048load(":f.bzl", "s1", "s2")
1049```
1050
1051--------------------------------------------------------------------------------
1052
1053## <a name="skylark-comment"></a><a name="skylark-docstring"></a>"Skylark" is an outdated name of the language, please use "starlark" instead
1054
1055 * Category names:
1056 * `skylark-comment`
1057 * `skylark-docstring`
1058 * Automatic fix: yes
1059 * [Suppress the warning](#suppress): `# buildifier: disable=skylark-comment`, `# buildifier: disable=skylark-docstring`
1060
1061The configuration language for Bazel is called "Starlark" now, the name "Skylark" is
1062outdated and shouldn't be used.
1063
1064--------------------------------------------------------------------------------
1065
1066## <a name="string-iteration"></a>String iteration is deprecated
1067
1068 * Category name: `string-iteration`
1069 * Flag in Bazel: [`--incompatible_string_is_not_iterable`](https://github.com/bazelbuild/bazel/issues/5830)
1070 * Automatic fix: no
1071 * [Suppress the warning](#suppress): `# buildifier: disable=string-iteration`
1072
1073Iteration over strings often leads to confusion with iteration over a sequence of strings,
1074therefore strings won't be recognized as sequences of 1-element strings (like in Python).
1075Use string indexing and `len` instead:
1076
1077```python
1078my_string = "hello world"
1079for i in range(len(my_string)):
1080 char = my_string[i]
1081 # do something with char
1082```
1083
1084--------------------------------------------------------------------------------
1085
1086## <a name="uninitialized"></a>Variable may not have been initialized
1087
1088 * Category name: `uninitialized`
1089 * Automatic fix: no
1090 * [Suppress the warning](#suppress): `# buildifier: disable=uninitialized`
1091
1092The local value can be not initialized at the time of execution. It may happen if it's
1093initialized in one of the if-else clauses but not in all of them, or in a for-loop which
1094can potentially be empty.
1095
1096--------------------------------------------------------------------------------
1097
1098## <a name="unnamed-macro"></a>The macro should have a keyword argument called "name"
1099
1100 * Category name: `unnamed-macro`
1101 * Automatic fix: no
1102 * [Suppress the warning](#suppress): `# buildifier: disable=unnamed-macro`
1103
1104By convention all macro functions should have a keyword argument called `name`
1105(even if they don't use it). This is important for tooling and automation.
1106
1107A macro is a function that calls a rule (either directly or indirectly by calling other
1108macros).
1109
1110If this function is a helper function that's not supposed to be used outside of its file,
1111please make it private (rename it so that the name starts with `_`), this will
1112prevent loading the function from BUILD files and suppress the warning.
1113
1114--------------------------------------------------------------------------------
1115
1116## <a name="unreachable"></a>The statement is unreachable
1117
1118 * Category name: `unreachable`
1119 * Automatic fix: no
1120 * [Suppress the warning](#suppress): `# buildifier: disable=unreachable`
1121
1122The statement is unreachable because it follows a `return`, `break`, `continue`,
1123or `fail()` statement.
1124
1125--------------------------------------------------------------------------------
1126
1127## <a name="unsorted-dict-items"></a>Dictionary items should be ordered by their keys
1128
1129 * Category name: `unsorted-dict-items`
1130 * Automatic fix: yes
1131 * [Disabled by default](buildifier/README.md#linter)
1132 * [Suppress the warning](#suppress): `# buildifier: disable=unsorted-dict-items`
1133
1134Dictionary items should be sorted lexicographically by their keys. This makes
1135it easier to find the item of interest and reduces chances of conflicts when
1136performing large-scale automated refactoring.
1137
1138The order is affected by `NamePriority` dictionary passed using `-tables` or
1139`-add_tables` flags.
1140
1141If you want to preserve the original dictionary items order, you can disable
1142the warning by adding a comment `# @unsorted-dict-items` to the dictionary
1143expression or any of its enclosing expressions (binary, if etc). For example,
1144
1145```python
1146# @unsorted-dict-items
1147d = {
1148 "b": "bvalue",
1149 "a": "avalue",
1150}
1151```
1152
1153will not be reported as an issue because the assignment operation that uses
1154the dictionary with unsorted items has a comment disabling this warning.
1155
1156--------------------------------------------------------------------------------
1157
1158## <a name="unused-variable"></a>Variable is unused
1159
1160 * Category name: `unused-variable`
1161 * Automatic fix: no
1162 * [Suppress the warning](#suppress): `# buildifier: disable=unused-variable`
1163
1164This happens when a variable or function is set but not used in the file, e.g.
1165
1166```python
1167x = [1, 2]
1168```
1169
1170The line can often be safely removed.
1171
1172If you want to keep the variable, you can disable the warning by adding a
1173comment `# @unused`.
1174
1175```python
1176x = [1, 2] # @unused
1177
1178# @unused
1179def f(
1180 x,
1181 y, # @unused
1182):
1183 pass
1184```
1185
1186If an unused variable is used for partially unpacking tuples, just prefix
1187its name with an underscore to suppress the warning:
1188
1189```python
1190x, _y = foo()
1191for _, (a, _b) in iterable:
1192 print(a + x)
1193```
1194
1195The same applies for function arguments that are not used by design:
1196
1197```python
1198def foo(a, _b, *_args):
1199 return bar(a)
1200```
1201
1202If a tuple is unpacked not in a for-loop and all variables are unused,
1203it'll still trigger a warning, even if all variables are underscored:
1204
1205```python
1206_a, _b = pair
1207_unused = 3
1208```
View as plain text