Skip to content

Commit acf16dd

Browse files
authored
Fix false positive in one-liner-rule (#1534)
Also, enable the rule! We almost always did this anyway. Finally, update tests to not mock config for error level, as that's no longer needed. Fixes #1527 Signed-off-by: Anders Eknert <anders@styra.com>
1 parent 23303ae commit acf16dd

10 files changed

Lines changed: 42 additions & 53 deletions

File tree

.regal/config.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ rules:
1919
- cfg
2020
- metadata
2121
- rule
22+
one-liner-rule:
23+
level: error
2224
style:
2325
line-length:
2426
level: error

bundle/regal/ast/ast_test.rego

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,7 @@ test_function_calls if {
9393
{"assign", "f"} == {call.name | some call in calls}
9494
}
9595

96-
test_implicit_boolean_assignment if {
97-
ast.implicit_boolean_assignment(ast.with_rego_v1(`a.b if true`).rules[0])
98-
}
96+
test_implicit_boolean_assignment if ast.implicit_boolean_assignment(ast.with_rego_v1(`a.b if true`).rules[0])
9997

10098
test_ref_to_string if {
10199
ast.ref_to_string([{"type": "var", "value": "data"}]) == `data`

bundle/regal/config/exclusion_test.rego

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,7 @@ test_excluded_file_with_ignore if {
7676
with config.merged_config as object.union(rules_config_error, rules_config_ignore_delta)
7777
}
7878

79-
test_ignored_globally if {
80-
config.ignored_globally("p.rego") with config.merged_config as config_ignore
81-
}
79+
test_ignored_globally if config.ignored_globally("p.rego") with config.merged_config as config_ignore
8280

8381
test_excluded_file_cli_flag if {
8482
config.ignored_globally("p.rego") with data.eval.params as params({"ignore_files": ["p.rego"]})

bundle/regal/lsp/codelens/codelens.rego

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,7 @@ _eval_lenses contains {
3333
},
3434
}
3535

36-
_eval_lenses contains _rule_lens(input.regal.file.name, rule, "regal.eval", "Evaluate") if {
37-
some rule in ast.rules
38-
}
36+
_eval_lenses contains _rule_lens(input.regal.file.name, rule, "regal.eval", "Evaluate") if some rule in ast.rules
3937

4038
_debug_lenses contains {
4139
"range": location.to_range(result.location(input["package"]).location),

bundle/regal/lsp/completion/providers/packagename/packagename_test.rego

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -137,16 +137,7 @@ test_package_name_completion_on_typing_multiple_suggestions_when_invoked if {
137137

138138
test_build_suggestions if {
139139
provider._suggestions("foo.bar.baz", "foo") == ["foo.bar.baz"]
140-
141140
provider._suggestions("foo.bar.baz", "bar") == ["bar.baz"]
142-
143141
provider._suggestions("foo.bar.baz", "ba") == ["bar.baz", "baz"]
144-
}
145-
146-
test_build_suggestions_invoked if {
147-
provider._suggestions("foo.bar.baz", "") == [
148-
"foo.bar.baz",
149-
"bar.baz",
150-
"baz",
151-
]
142+
provider._suggestions("foo.bar.baz", "") == ["foo.bar.baz", "bar.baz", "baz"]
152143
}

bundle/regal/lsp/completion/ref_names.rego

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,4 @@ ref_names contains name if {
2323
# if they have imported data.foo as bar, then bar should be suggested.
2424
# this also has the benefit of skipping future.* and rego.v1 as
2525
# imported_identifiers will only match data.* and input.*
26-
ref_names contains name if {
27-
some name in ast.imported_identifiers
28-
}
26+
ref_names contains name if some name in ast.imported_identifiers

bundle/regal/main/main.rego

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,23 @@ import data.regal.util
1414

1515
# METADATA
1616
# description: set of all notices returned from linter rules
17-
lint.notices := _notices if {
18-
"lint" in input.regal.operations
19-
}
17+
lint.notices := _notices if "lint" in input.regal.operations
2018

2119
# METADATA
2220
# description: map of all ignore directives encountered when linting
23-
lint.ignore_directives[input.regal.file.name] := ast.ignore_directives if {
24-
"lint" in input.regal.operations
25-
}
21+
lint.ignore_directives[input.regal.file.name] := ast.ignore_directives if "lint" in input.regal.operations
2622

2723
# METADATA
2824
# description: all violations from non-aggregate rules
29-
lint.violations := report if {
30-
"lint" in input.regal.operations
31-
}
25+
lint.violations := report if "lint" in input.regal.operations
3226

3327
# METADATA
3428
# description: map of all aggregated data from aggregate rules, keyed by category/title
35-
lint.aggregates := aggregate if {
36-
"collect" in input.regal.operations
37-
}
29+
lint.aggregates := aggregate if "collect" in input.regal.operations
3830

3931
# METADATA
4032
# description: all violations from aggregate rules
41-
lint.aggregate.violations := aggregate_report if {
42-
"aggregate" in input.regal.operations
43-
}
33+
lint.aggregate.violations := aggregate_report if "aggregate" in input.regal.operations
4434

4535
_file_name_relative_to_root(filename, "/") := trim_prefix(filename, "/")
4636
_file_name_relative_to_root(filename, root) := trim_prefix(filename, concat("", [root, "/"])) if root != "/"

bundle/regal/rules/custom/one-liner-rule/one_liner_rule.rego

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ import data.regal.util
1414
notices contains result.notice(rego.metadata.chain()) if not capabilities.has_if
1515

1616
report contains violation if {
17-
max_line_length := object.get(config.rules, ["custom", "one-liner-rule", "max-line-length"], 120)
18-
1917
some rule in input.rules
2018

2119
# Bail out of rules with else for now. It is possible that they can be made
@@ -35,22 +33,25 @@ report contains violation if {
3533
line := trim_space(s)
3634
]
3735

38-
# Technically, the `if` could be on another line, but who would do that?
3936
regex.match(`\s+if`, lines[0])
4037
_rule_body_brackets(lines)
4138

4239
# ideally we'd take style preference into account but for now assume tab == 4 spaces
4340
# then just add the sum of the line counts minus the removed '{' character
4441
# redundant parens added by `opa fmt` :/
45-
((4 + count(lines[0])) + count(lines[1])) - 1 < max_line_length
42+
((4 + count(lines[0])) + count(lines[1])) - 1 < _max_line_length
4643

4744
not _comment_in_body(rule_location.row, object.get(input, "comments", []), lines)
4845

4946
violation := result.fail(rego.metadata.chain(), result.location(rule.head))
5047
}
5148

49+
default _max_line_length := 120
50+
51+
_max_line_length := config.rules.custom["one-liner-rule"]["max-line-length"]
52+
5253
# K&R style
53-
_rule_body_brackets(lines) if endswith(lines[0], "{")
54+
_rule_body_brackets(lines) if regex.match(`.*if\s*{$`, lines[0])
5455

5556
# Allman style
5657
_rule_body_brackets(lines) if {

bundle/regal/rules/custom/one-liner-rule/one_liner_rule_test.rego

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ test_fail_could_be_one_liner if {
1212
input.yes
1313
}
1414
`)
15-
r := rule.report with input as module with config.rules as {"custom": {"one-liner-rule": {"level": "error"}}}
15+
r := rule.report with input as module
1616

1717
r == expected_with_location({
1818
"col": 2,
@@ -32,7 +32,7 @@ test_fail_could_be_one_liner_all_keywords if {
3232
input.yes
3333
}
3434
`)
35-
r := rule.report with input as module with config.rules as {"custom": {"one-liner-rule": {"level": "error"}}}
35+
r := rule.report with input as module
3636

3737
r == expected_with_location({
3838
"col": 2,
@@ -54,8 +54,8 @@ test_fail_could_be_one_liner_allman_style if {
5454
input.yes
5555
}
5656
`)
57+
r := rule.report with input as module
5758

58-
r := rule.report with input as module with config.rules as {"custom": {"one-liner-rule": {"level": "error"}}}
5959
r == expected_with_location({
6060
"col": 2,
6161
"row": 5,
@@ -73,8 +73,8 @@ test_success_too_long_for_a_one_liner if {
7373
some_really_long_rule_name_in_fact_53_characters_long == another_long_rule_but_only_45_characters_long
7474
}
7575
`)
76+
r := rule.report with input as module
7677

77-
r := rule.report with input as module with config.rules as {"custom": {"one-liner-rule": {"level": "error"}}}
7878
r == set()
7979
}
8080

@@ -84,8 +84,7 @@ test_success_too_long_for_a_one_liner_configured_line_length if {
8484
some_really_long_rule_name_in_fact_53_characters_long
8585
}
8686
`)
87-
r := rule.report with input as module
88-
with config.rules as {"custom": {"one-liner-rule": {"level": "error", "max-line-length": 50}}}
87+
r := rule.report with input as module with config.rules as {"custom": {"one-liner-rule": {"max-line-length": 50}}}
8988

9089
r == set()
9190
}
@@ -97,7 +96,7 @@ test_success_no_one_liner_comment_in_rule_body if {
9796
1 == 1
9897
}
9998
`)
100-
r := rule.report with input as module with config.rules as {"custom": {"one-liner-rule": {"level": "error"}}}
99+
r := rule.report with input as module
101100

102101
r == set()
103102
}
@@ -108,7 +107,7 @@ test_success_no_one_liner_comment_in_rule_body_same_line if {
108107
1 == 1 # Surely one equals one
109108
}
110109
`)
111-
r := rule.report with input as module with config.rules as {"custom": {"one-liner-rule": {"level": "error"}}}
110+
r := rule.report with input as module
112111

113112
r == set()
114113
}
@@ -120,7 +119,7 @@ test_success_no_one_liner_comment_in_rule_body_line_below if {
120119
# Surely one equals one
121120
}
122121
`)
123-
r := rule.report with input as module with config.rules as {"custom": {"one-liner-rule": {"level": "error"}}}
122+
r := rule.report with input as module
124123

125124
r == set()
126125
}
@@ -131,14 +130,13 @@ test_success_does_not_use_if_v0 if {
131130
1 == 1
132131
}
133132
`)
134-
r := rule.report with input as module with config.rules as {"custom": {"one-liner-rule": {"level": "error"}}}
133+
r := rule.report with input as module
135134

136135
r == set()
137136
}
138137

139138
test_success_already_a_one_liner if {
140139
r := rule.report with input as ast.with_rego_v1(`allow if 1 == 1`)
141-
with config.rules as {"custom": {"one-liner-rule": {"level": "error"}}}
142140

143141
r == set()
144142
}
@@ -155,6 +153,20 @@ test_has_notice_if_unmet_capability if {
155153
}}
156154
}
157155

156+
# verify fix for https://github.com/StyraInc/regal/issues/1527
157+
test_fail_single_expression_spanning_multiple_lines_already_a_one_liner if {
158+
module := ast.policy(`
159+
160+
foo := bar if baz in {
161+
"foo",
162+
"bar",
163+
}
164+
`)
165+
r := rule.report with input as module
166+
167+
r == set()
168+
}
169+
158170
expected := {
159171
"category": "custom",
160172
"description": "Rule body could be made a one-liner",

bundle/regal/util/util_test.rego

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import data.regal.util
44

55
test_find_duplicates if {
66
util.find_duplicates([1, 1, 2, 3, 3, 3]) == {{0, 1}, {3, 4, 5}}
7+
util.find_duplicates([1, 2, 3]) == set()
78
}
89

910
test_json_pretty if {

0 commit comments

Comments
 (0)