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 ```