Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
load("@bazel_gazelle//:def.bzl", "gazelle")
load("//buildifier:def.bzl", "buildifier")
load("//buildifier:def.bzl", "buildifier", "buildifier_test")

exports_files([
"LICENSE",
"launcher.js",
"WORKSPACE",
])

config_setting(
Expand All @@ -20,6 +21,7 @@ filegroup(
test_suite(
name = "tests",
tests = [
":make_location_lint",
"//api_proto:api.gen.pb.go_checkshtest",
"//build:build_test",
"//build_proto:build.gen.pb.go_checkshtest",
Expand All @@ -45,3 +47,11 @@ gazelle(
buildifier(
name = "buildifier",
)

buildifier_test(
name = "make_location_lint",
lint_mode = "warn",
lint_warnings = ["make-location"],
no_sandbox = True,
workspace = "//:WORKSPACE",
)
31 changes: 31 additions & 0 deletions WARNINGS.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Warning categories supported by buildifier's linter:
* [`list-append`](#list-append)
* [`load`](#load)
* [`load-on-top`](#load-on-top)
* [`make-location`](#make-location)
* [`module-docstring`](#module-docstring)
* [`name-conventions`](#name-conventions)
* [`native-android`](#native-android)
Expand Down Expand Up @@ -748,6 +749,36 @@ they can follow only comments and docstrings.

--------------------------------------------------------------------------------

## <a name="make-location"></a>The `$(location)` make variable is deprecated

* Category name: `make-location`
* Automatic fix: no
* [Suppress the warning](#suppress): `# buildifier: disable=make-location`

The `$(location)` and `$(locations)` make variables are legacy synonyms for
`$(execpath)` and `$(rootpath)` whose behavior depends on the attribute being
expanded. Use `$(execpath ...)` when you need the execution path, or
`$(rootpath ...)` when you need the runfiles path.

Examples that trigger this warning:

```python
genrule(
name = "example",
srcs = [":input"],
outs = ["output"],
cmd = "cp $(location :input) $@",
)
```

Instead, use an explicit make variable:

```python
cmd = "cp $(execpath :input) $@",
```

--------------------------------------------------------------------------------

## <a name="module-docstring"></a>The file has no module docstring

* Category name: `module-docstring`
Expand Down
4 changes: 2 additions & 2 deletions build/build_defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -144,15 +144,15 @@ eof
srcs = [src + "_check.sh"],
deps = ["@bazel_tools//tools/bash/runfiles"],
data = [src, gen],
args = ["$(location " + src + ")", "$(location " + gen + ")"],
args = ["$(rootpath " + src + ")", "$(rootpath " + gen + ")"],
)

# magic copy rule used to update the checked-in version
native.genrule(
name = src + "_copysh",
srcs = [gen],
outs = [src + "copy.sh"],
cmd = "echo 'cp $${BUILD_WORKSPACE_DIRECTORY}/$(location " + gen +
cmd = "echo 'cp $${BUILD_WORKSPACE_DIRECTORY}/$(execpath " + gen +
") $${BUILD_WORKSPACE_DIRECTORY}/" + native.package_name() + "/" + src + "' > $@",
)
sh_binary(
Expand Down
2 changes: 1 addition & 1 deletion buildifier/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ sh_test(
size = "small",
srcs = ["integration_test.sh"],
args = [
"$(location :buildifier)",
"$(rootpath :buildifier)",
],
data = [
":buildifier",
Expand Down
5 changes: 5 additions & 0 deletions buildifier/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ func ExampleExample() {
// "keyword-positional-params",
// "list-append",
// "load",
// "make-location",
// "module-docstring",
// "name-conventions",
// "native-android",
Expand Down Expand Up @@ -298,6 +299,7 @@ func TestValidate(t *testing.T) {
"keyword-positional-params",
"list-append",
"load",
"make-location",
"module-docstring",
"name-conventions",
"native-android",
Expand Down Expand Up @@ -400,6 +402,7 @@ func TestValidate(t *testing.T) {
"keyword-positional-params",
"list-append",
"load",
"make-location",
"module-docstring",
"name-conventions",
"native-android",
Expand Down Expand Up @@ -502,6 +505,7 @@ func TestValidate(t *testing.T) {
"keyword-positional-params",
"list-append",
"load",
"make-location",
"module-docstring",
"name-conventions",
"native-android",
Expand Down Expand Up @@ -604,6 +608,7 @@ func TestValidate(t *testing.T) {
"keyword-positional-params",
"list-append",
"load",
"make-location",
"module-docstring",
"name-conventions",
"native-android",
Expand Down
1 change: 1 addition & 0 deletions buildifier/integration_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ cat > golden/.buildifier.example.json <<EOF
"keyword-positional-params",
"list-append",
"load",
"make-location",
"module-docstring",
"name-conventions",
"native-android",
Expand Down
2 changes: 1 addition & 1 deletion buildozer/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ sh_test(
size = "small",
srcs = ["buildozer_test.sh"],
args = [
"$(location :buildozer)",
"$(rootpath :buildozer)",
],
data = [
"test_common.sh",
Expand Down
24 changes: 24 additions & 0 deletions warn/docs/warnings.textproto
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,30 @@ warnings: {
autofix: true
}

warnings: {
name: "make-location"
header: "The `$(location)` make variable is deprecated"
description:
"The `$(location)` and `$(locations)` make variables are legacy synonyms for\n"
"`$(execpath)` and `$(rootpath)` whose behavior depends on the attribute being\n"
"expanded. Use `$(execpath ...)` when you need the execution path, or\n"
"`$(rootpath ...)` when you need the runfiles path.\n\n"
"Examples that trigger this warning:\n\n"
"```python\n"
"genrule(\n"
" name = \"example\",\n"
" srcs = [\":input\"],\n"
" outs = [\"output\"],\n"
" cmd = \"cp $(location :input) $@\",\n"
")\n"
"```\n\n"
"Instead, use an explicit make variable:\n\n"
"```python\n"
"cmd = \"cp $(execpath :input) $@\",\n"
"```"
autofix: false
}

warnings: {
name: "module-docstring"
header: "The file has no module docstring"
Expand Down
1 change: 1 addition & 0 deletions warn/warn.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ var FileWarningMap = map[string]func(f *build.File) []*LinterFinding{
"keyword-positional-params": keywordPositionalParametersWarning,
"list-append": listAppendWarning,
"load": unusedLoadWarning,
"make-location": makeLocationVariableWarning,
"module-docstring": moduleDocstringWarning,
"name-conventions": nameConventionsWarning,
"native-build": nativeInBuildFilesWarning,
Expand Down
24 changes: 24 additions & 0 deletions warn/warn_bazel.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,15 @@ package warn

import (
"fmt"
"regexp"
"strings"

"github.com/bazelbuild/buildtools/build"
)

// locationMakeVariableRe matches deprecated $(location) and $(locations) make variables.
var locationMakeVariableRe = regexp.MustCompile(`\$\(locations?(?:\s[^)]*)?\)`)

func constantGlobPatternWarning(patterns *build.ListExpr) []*LinterFinding {
findings := []*LinterFinding{}
for _, expr := range patterns.List {
Expand Down Expand Up @@ -256,6 +260,26 @@ func printWarning(f *build.File) []*LinterFinding {
return findings
}

func makeLocationVariableWarning(f *build.File) []*LinterFinding {
if f.Type != build.TypeBuild {
return nil
}

findings := []*LinterFinding{}
build.Walk(f, func(expr build.Expr, stack []build.Expr) {
stringExpr, ok := expr.(*build.StringExpr)
if !ok {
return
}
if locationMakeVariableRe.MatchString(stringExpr.Value) {
findings = append(findings,
makeLinterFinding(stringExpr,
`The "$(location)" and "$(locations)" make variables are deprecated. Use "$(execpath ...)" or "$(rootpath ...)" instead.`))
}
})
return findings
}

func externalPathWarning(f *build.File) []*LinterFinding {
if f.Type == build.TypeDefault {
// Only applicable to Bazel files
Expand Down
38 changes: 38 additions & 0 deletions warn/warn_bazel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,3 +289,41 @@ py_binary(
},
scopeBazel)
}

func TestMakeLocationVariable(t *testing.T) {
checkFindings(t, "make-location", `
genrule(
name = "a",
srcs = [":foo"],
outs = ["out"],
cmd = "cp $(location :foo) $@",
)

genrule(
name = "b",
srcs = [":a", ":b"],
outs = ["out"],
cmd = "cat $(locations :a :b) > $@",
)

genrule(
name = "c",
srcs = [":foo"],
outs = ["out"],
cmd = "cp $$(location :foo) $$@",
)

cc_test(
name = "d",
args = ["--config=$(execpath :cfg)"],
)

load("location", "symbol")
`,
[]string{
`:5: The "$(location)" and "$(locations)" make variables are deprecated. Use "$(execpath ...)" or "$(rootpath ...)" instead.`,
`:12: The "$(location)" and "$(locations)" make variables are deprecated. Use "$(execpath ...)" or "$(rootpath ...)" instead.`,
`:19: The "$(location)" and "$(locations)" make variables are deprecated. Use "$(execpath ...)" or "$(rootpath ...)" instead.`,
},
scopeBuild)
}