Skip to content

Commit 7f228ee

Browse files
committed
Add a buildifier warning to enforce rule load location
1 parent a9c248f commit 7f228ee

File tree

12 files changed

+132
-6
lines changed

12 files changed

+132
-6
lines changed

WARNINGS.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ Warning categories supported by buildifier's linter:
7474
* [`repository-name`](#repository-name)
7575
* [`return-value`](#return-value)
7676
* [`rule-impl-return`](#rule-impl-return)
77+
* [`rule-load-location`](#rule-load-location)
7778
* [`same-origin-load`](#same-origin-load)
7879
* [`skylark-comment`](#skylark-comment)
7980
* [`skylark-docstring`](#skylark-docstring)
@@ -1210,6 +1211,26 @@ consider using
12101211
[providers](https://docs.bazel.build/versions/main/skylark/rules.html#providers)
12111212
or lists of providers instead.
12121213

1214+
--------------------------------------------------------------------------------
1215+
1216+
## <a name="rule-load-location"></a>Rule must be loaded from a specific location
1217+
1218+
* Category name: `rule-load-location`
1219+
* Automatic fix: no
1220+
* [Suppress the warning](#suppress): `# buildifier: disable=rule-load-location`
1221+
1222+
Warns when a rule is loaded from a location other than the expected one.
1223+
Expected locations are specified in the tables file:
1224+
1225+
```json
1226+
{
1227+
"RuleLoadLocation": {
1228+
"genrule": "//:genrule.bzl"
1229+
}
1230+
}
1231+
```
1232+
1233+
12131234
--------------------------------------------------------------------------------
12141235

12151236
## <a name="same-origin-load"></a>Same label is used for multiple loads

buildifier/config/config_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ func ExampleExample() {
112112
// "repository-name",
113113
// "return-value",
114114
// "rule-impl-return",
115+
// "rule-load-location",
115116
// "skylark-comment",
116117
// "skylark-docstring",
117118
// "string-iteration",
@@ -310,6 +311,7 @@ func TestValidate(t *testing.T) {
310311
"repository-name",
311312
"return-value",
312313
"rule-impl-return",
314+
"rule-load-location",
313315
"skylark-comment",
314316
"skylark-docstring",
315317
"string-iteration",
@@ -389,6 +391,7 @@ func TestValidate(t *testing.T) {
389391
"repository-name",
390392
"return-value",
391393
"rule-impl-return",
394+
"rule-load-location",
392395
"skylark-comment",
393396
"skylark-docstring",
394397
"string-iteration",
@@ -467,7 +470,7 @@ func TestValidate(t *testing.T) {
467470
"repository-name",
468471
"return-value",
469472
"rule-impl-return",
470-
473+
"rule-load-location",
471474
"skylark-comment",
472475
"skylark-docstring",
473476
"string-iteration",

buildifier/integration_test.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ cat > golden/.buildifier.example.json <<EOF
317317
"repository-name",
318318
"return-value",
319319
"rule-impl-return",
320+
"rule-load-location",
320321
"skylark-comment",
321322
"skylark-docstring",
322323
"string-iteration",

tables/jsonparser.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ type Definitions struct {
3131
NamePriority map[string]int
3232
StripLabelLeadingSlashes bool
3333
ShortenAbsoluteLabelsToRelative bool
34+
RuleLoadLocation map[string]string
3435
}
3536

3637
// ParseJSONDefinitions reads and parses JSON table definitions from file.
@@ -55,9 +56,9 @@ func ParseAndUpdateJSONDefinitions(file string, merge bool) error {
5556
}
5657

5758
if merge {
58-
MergeTables(definitions.IsLabelArg, definitions.LabelDenylist, definitions.IsListArg, definitions.IsSortableListArg, definitions.SortableDenylist, definitions.SortableAllowlist, definitions.NamePriority, definitions.StripLabelLeadingSlashes, definitions.ShortenAbsoluteLabelsToRelative)
59+
MergeTables(definitions.IsLabelArg, definitions.LabelDenylist, definitions.IsListArg, definitions.IsSortableListArg, definitions.SortableDenylist, definitions.SortableAllowlist, definitions.NamePriority, definitions.StripLabelLeadingSlashes, definitions.ShortenAbsoluteLabelsToRelative, definitions.RuleLoadLocation)
5960
} else {
60-
OverrideTables(definitions.IsLabelArg, definitions.LabelDenylist, definitions.IsListArg, definitions.IsSortableListArg, definitions.SortableDenylist, definitions.SortableAllowlist, definitions.NamePriority, definitions.StripLabelLeadingSlashes, definitions.ShortenAbsoluteLabelsToRelative)
61+
OverrideTables(definitions.IsLabelArg, definitions.LabelDenylist, definitions.IsListArg, definitions.IsSortableListArg, definitions.SortableDenylist, definitions.SortableAllowlist, definitions.NamePriority, definitions.StripLabelLeadingSlashes, definitions.ShortenAbsoluteLabelsToRelative, definitions.RuleLoadLocation)
6162
}
6263
return nil
6364
}

tables/jsonparser_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ func TestParseJSONDefinitions(t *testing.T) {
3737
SortableAllowlist: map[string]bool{},
3838
NamePriority: map[string]int{"name": -1},
3939
StripLabelLeadingSlashes: true,
40+
RuleLoadLocation: map[string]string{"genrule": "//:genrule.bzl"},
4041
}
4142
if !reflect.DeepEqual(expected, definitions) {
4243
t.Errorf("ParseJSONDefinitions(simple_tables.json) = %v; want %v", definitions, expected)

tables/tables.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,8 +271,11 @@ var IsModuleOverride = map[string]bool{
271271
"single_version_override": true,
272272
}
273273

274+
// RuleLoadLocation contains custom locations for loading rules.
275+
var RuleLoadLocation = map[string]string{}
276+
274277
// OverrideTables allows a user of the build package to override the special-case rules. The user-provided tables replace the built-in tables.
275-
func OverrideTables(labelArg, denylist, listArg, sortableListArg, sortDenylist, sortAllowlist map[string]bool, namePriority map[string]int, stripLabelLeadingSlashes, shortenAbsoluteLabelsToRelative bool) {
278+
func OverrideTables(labelArg, denylist, listArg, sortableListArg, sortDenylist, sortAllowlist map[string]bool, namePriority map[string]int, stripLabelLeadingSlashes, shortenAbsoluteLabelsToRelative bool, ruleLoadLocation map[string]string) {
276279
IsLabelArg = labelArg
277280
LabelDenylist = denylist
278281
IsListArg = listArg
@@ -282,10 +285,11 @@ func OverrideTables(labelArg, denylist, listArg, sortableListArg, sortDenylist,
282285
NamePriority = namePriority
283286
StripLabelLeadingSlashes = stripLabelLeadingSlashes
284287
ShortenAbsoluteLabelsToRelative = shortenAbsoluteLabelsToRelative
288+
RuleLoadLocation = ruleLoadLocation
285289
}
286290

287291
// MergeTables allows a user of the build package to override the special-case rules. The user-provided tables are merged into the built-in tables.
288-
func MergeTables(labelArg, denylist, listArg, sortableListArg, sortDenylist, sortAllowlist map[string]bool, namePriority map[string]int, stripLabelLeadingSlashes, shortenAbsoluteLabelsToRelative bool) {
292+
func MergeTables(labelArg, denylist, listArg, sortableListArg, sortDenylist, sortAllowlist map[string]bool, namePriority map[string]int, stripLabelLeadingSlashes, shortenAbsoluteLabelsToRelative bool, ruleLoadLocation map[string]string) {
289293
for k, v := range labelArg {
290294
IsLabelArg[k] = v
291295
}
@@ -309,4 +313,7 @@ func MergeTables(labelArg, denylist, listArg, sortableListArg, sortDenylist, sor
309313
}
310314
StripLabelLeadingSlashes = stripLabelLeadingSlashes || StripLabelLeadingSlashes
311315
ShortenAbsoluteLabelsToRelative = shortenAbsoluteLabelsToRelative || ShortenAbsoluteLabelsToRelative
316+
for k, v := range ruleLoadLocation {
317+
RuleLoadLocation[k] = v
318+
}
312319
}

tables/testdata/simple_tables.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,8 @@
1919
"NamePriority": {
2020
"name": -1
2121
},
22-
"StripLabelLeadingSlashes": true
22+
"StripLabelLeadingSlashes": true,
23+
"RuleLoadLocation": {
24+
"genrule": "//:genrule.bzl"
25+
}
2326
}

warn/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ go_library(
1313
"warn_cosmetic.go",
1414
"warn_deprecated.go",
1515
"warn_docstring.go",
16+
"warn_load.go",
1617
"warn_macro.go",
1718
"warn_naming.go",
1819
"warn_operation.go",
@@ -41,6 +42,7 @@ go_test(
4142
"warn_cosmetic_test.go",
4243
"warn_deprecated_test.go",
4344
"warn_docstring_test.go",
45+
"warn_load_test.go",
4446
"warn_macro_test.go",
4547
"warn_naming_test.go",
4648
"warn_operation_test.go",

warn/docs/warnings.textproto

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,21 @@ warnings: {
897897
"or lists of providers instead."
898898
}
899899

900+
warnings: {
901+
name: "rule-load-location"
902+
header: "Rule must be loaded from a specific location"
903+
description:
904+
"Warns when a rule is loaded from a location other than the expected one.\n"
905+
"Expected locations are specified in the tables file:\n\n"
906+
"```json\n"
907+
"{\n"
908+
" \"RuleLoadLocation\": {\n"
909+
" \"genrule\": \"//:genrule.bzl\"\n"
910+
" }\n"
911+
"}\n"
912+
"```\n"
913+
}
914+
900915
warnings: {
901916
name: "same-origin-load"
902917
header: "Same label is used for multiple loads"

warn/warn.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ var FileWarningMap = map[string]func(f *build.File) []*LinterFinding{
184184
"redefined-variable": redefinedVariableWarning,
185185
"repository-name": repositoryNameWarning,
186186
"rule-impl-return": ruleImplReturnWarning,
187+
"rule-load-location": ruleLoadLocationWarning,
187188
"return-value": missingReturnValueWarning,
188189
"skylark-comment": skylarkCommentWarning,
189190
"skylark-docstring": skylarkDocstringWarning,

0 commit comments

Comments
 (0)