Skip to content

Commit

Permalink
Rule: if-object-literal (#835)
Browse files Browse the repository at this point in the history
This replaces `if-empty-object`, and covers any object literal.

Fixes #822

Signed-off-by: Anders Eknert <[email protected]>
  • Loading branch information
anderseknert committed Jun 13, 2024
1 parent e3e12a9 commit 34fc452
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ The following rules are currently available:
| bugs | [deprecated-builtin](https://docs.styra.com/regal/rules/bugs/deprecated-builtin) | Avoid using deprecated built-in functions |
| bugs | [duplicate-rule](https://docs.styra.com/regal/rules/bugs/duplicate-rule) | Duplicate rule |
| bugs | [if-empty-object](https://docs.styra.com/regal/rules/bugs/if-empty-object) | Empty object following `if` |
| bugs | [if-object-literal](https://docs.styra.com/regal/rules/bugs/if-object-literal) | Object literal following `if` |
| bugs | [impossible-not](https://docs.styra.com/regal/rules/bugs/impossible-not) | Impossible `not` condition |
| bugs | [inconsistent-args](https://docs.styra.com/regal/rules/bugs/inconsistent-args) | Inconsistently named function arguments |
| bugs | [internal-entrypoint](https://docs.styra.com/regal/rules/bugs/internal-entrypoint) | Entrypoint can't be marked internal |
Expand Down
3 changes: 3 additions & 0 deletions bundle/regal/config/provided/data.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ rules:
duplicate-rule:
level: error
if-empty-object:
# deprecated with the introduction of if-object-literal
level: ignore
if-object-literal:
level: error
impossible-not:
level: error
Expand Down
4 changes: 4 additions & 0 deletions bundle/regal/rules/bugs/if_empty_object.rego
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
# description: Empty object following `if`
package regal.rules.bugs["if-empty-object"]

# NOTE: this rule has been deprecated and is no longer enabled by default
# Use the `if-object-literal` rule instead, which checks for any object,
# non-empty or not

import rego.v1

import data.regal.capabilities
Expand Down
24 changes: 24 additions & 0 deletions bundle/regal/rules/bugs/if_object_literal.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# METADATA
# description: Object literal following `if`
package regal.rules.bugs["if-object-literal"]

import rego.v1

import data.regal.capabilities
import data.regal.result

# METADATA
# description: Missing capability for keyword `if`
# custom:
# severity: warning
notices contains result.notice(rego.metadata.chain()) if not capabilities.has_if

report contains violation if {
some rule in input.rules

count(rule.body) == 1

rule.body[0].terms.type == "object"

violation := result.fail(rego.metadata.chain(), result.location(rule))
}
46 changes: 46 additions & 0 deletions bundle/regal/rules/bugs/if_object_literal_test.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package regal.rules.bugs["if-object-literal_test"]

import rego.v1

import data.regal.ast
import data.regal.config

import data.regal.rules.bugs["if-object-literal"] as rule

test_fail_if_empty_object if {
module := ast.with_rego_v1("rule if {}")
r := rule.report with input as module
r == {{
"category": "bugs",
"description": "Object literal following `if`",
"level": "error",
"location": {"col": 1, "file": "policy.rego", "row": 5, "text": "rule if {}"},
"related_resources": [{
"description": "documentation",
"ref": config.docs.resolve_url("$baseUrl/$category/if-object-literal", "bugs"),
}],
"title": "if-object-literal",
}}
}

test_fail_non_empty_object if {
module := ast.with_rego_v1(`rule if {"x": input.x}`)
r := rule.report with input as module
r == {{
"category": "bugs",
"description": "Object literal following `if`",
"level": "error",
"location": {"col": 1, "file": "policy.rego", "row": 5, "text": `rule if {"x": input.x}`},
"related_resources": [{
"description": "documentation",
"ref": config.docs.resolve_url("$baseUrl/$category/if-object-literal", "bugs"),
}],
"title": "if-object-literal",
}}
}

test_success_not_an_object if {
module := ast.with_rego_v1(`rule if { true }`)
r := rule.report with input as module
r == set()
}
4 changes: 4 additions & 0 deletions docs/rules/bugs/if-empty-object.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# if-empty-object

**This rule has been deprecated and replaced by the
[if-object-literal](https://docs.styra.com/regal/rules/bugs/if-object-literal) rule. Documentation kept here only for
the sake of posterity.**

**Summary**: Empty object following `if`

**Category**: Bugs
Expand Down
45 changes: 45 additions & 0 deletions docs/rules/bugs/if-object-literal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# if-object-literal

**Summary**: Object literal following `if`

**Category**: Bugs

**Avoid**
```rego
package policy
import rego.v1
# {} interpreted as object, not a rule body
allow if {}
allow if {
# perhaps meant to be comparison?
# but this too is an object
input.x: 10
}
```

## Rationale

An object literal immediately following an `if` is almost certainly a mistake, and the intention was likely to express
a rule body in its place. This isn't too common, but can happen when either an empty object `{}` is all that follows the
`if`, or an expression in the "body" mistakenly is written as a `key: value` pair.

## Configuration Options

This linter rule provides the following configuration options:

```yaml
rules:
bugs:
if-object-literal:
# one of "error", "warning", "ignore"
level: error
```
## Community
If you think you've found a problem with this rule or its documentation, would like to suggest improvements, new rules,
or just talk about Regal in general, please join us in the `#regal` channel in the Styra Community
[Slack](https://communityinviter.com/apps/styracommunity/signup)!

0 comments on commit 34fc452

Please sign in to comment.