...

Text file src/github.com/bazelbuild/buildtools/WARNINGS.md

Documentation: github.com/bazelbuild/buildtools

     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