github.com/cheshirekow/buildtools@v0.0.0-20200224190056-5d637702fe81/WARNINGS.md (about)

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