From 40ed1ef046329eaa4b1c2ea2ea79d463392cf366 Mon Sep 17 00:00:00 2001 From: Anders Eknert Date: Thu, 9 Nov 2023 09:39:56 +0100 Subject: [PATCH] Allow ignore directive on same line (#450) Also some minor fixes tangentially related to ignore directives. Fixes #447 Signed-off-by: Anders Eknert --- README.md | 14 ++++++++++---- bundle/regal/main.rego | 18 +++++++++++------- bundle/regal/main_test.rego | 11 +++++++++++ bundle/regal/rules/bugs/inconsistent_args.rego | 12 +++--------- bundle/regal/rules/custom/one_liner_rule.rego | 1 - 5 files changed, 35 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 31f358b8..e24d3f2b 100644 --- a/README.md +++ b/README.md @@ -430,21 +430,27 @@ If `--fail-level warning` is supplied, warnings will result in a non-zero exit c ## Inline Ignore Directives -If you'd like to ignore a specific violation, you can add an ignore directive above the line in question: +If you'd like to ignore a specific violation, you can add an ignore directive above the line in question, or +alternatively on the same line to the right of the expression: ```rego package policy # regal ignore:prefer-snake-case camelCase := "yes" + +list_users contains user if { # regal ignore:avoid-get-and-list-prefix + some user in data.db.users + # ... +} ``` The format of an ignore directive is `regal ignore:,...`, where `` is the name of the rule to ignore. Multiple rules may be added to the same ignore directive, separated by commas. -Note that at this point in time, Regal only considers the line following the ignore directive, i.e. it does not ignore -entire blocks of code (like rules, functions or even packages). See [configuration](#configuration) if you want to -ignore certain rules altogether. +Note that at this point in time, Regal only considers the same line or the line following the ignore directive, i.e. it +does not apply to entire blocks of code (like rules, functions or even packages). See [configuration](#configuration) if you want +to ignore certain rules altogether. ## Output Formats diff --git a/bundle/regal/main.rego b/bundle/regal/main.rego index 7b0d7d85..44effe67 100644 --- a/bundle/regal/main.rego +++ b/bundle/regal/main.rego @@ -48,7 +48,7 @@ grouped_notices[category][title] contains notice if { config.for_rule(category, title).level != "ignore" - notice := data.regal.rules[category][title].notices[_] + some notice in data.regal.rules[category][title].notices } # Check bundled rules @@ -61,7 +61,7 @@ report contains violation if { count(object.get(grouped_notices, [category, title], [])) == 0 - violation := data.regal.rules[category][title].report[_] + some violation in data.regal.rules[category][title].report not ignored(violation, ignore_directives) } @@ -86,7 +86,7 @@ aggregate[category_title] contains entry if { config.for_rule(category, title).level != "ignore" not config.excluded_file(category, title, input.regal.file.name) - entry := data.regal.rules[category][title].aggregate[_] + some entry in data.regal.rules[category][title].aggregate category_title := concat("/", [category, title]) } @@ -98,7 +98,7 @@ aggregate[category_title] contains entry if { config.for_rule(category, title).level != "ignore" not config.excluded_file(category, title, input.regal.file.name) - entry := data.custom.regal.rules[category][title].aggregate[_] + some entry in data.custom.regal.rules[category][title].aggregate category_title := concat("/", [category, title]) } @@ -120,7 +120,7 @@ aggregate_report contains violation if { ["aggregates_internal"], ) - violation := data.regal.rules[category][title].aggregate_report[_] with input as input_for_rule + some violation in data.regal.rules[category][title].aggregate_report with input as input_for_rule not ignored(violation, ignore_directives) } @@ -141,8 +141,7 @@ aggregate_report contains violation if { ["aggregates_internal"], ) - # regal ignore:prefer-some-in-iteration - violation := data.custom.regal.rules[category][title].aggregate_report[_] with input as input_for_rule + some violation in data.custom.regal.rules[category][title].aggregate_report with input as input_for_rule not ignored(violation, ignore_directives) } @@ -152,6 +151,11 @@ ignored(violation, directives) if { violation.title in ignored_rules } +ignored(violation, directives) if { + ignored_rules := directives[violation.location.row + 1] + violation.title in ignored_rules +} + ignore_directives[row] := rules if { some comment in input.comments text := trim_space(base64.decode(comment.Text)) diff --git a/bundle/regal/main_test.rego b/bundle/regal/main_test.rego index ba7e9564..edd8146c 100644 --- a/bundle/regal/main_test.rego +++ b/bundle/regal/main_test.rego @@ -71,6 +71,17 @@ test_main_ignore_directive_success if { count(report) == 0 } +test_main_ignore_directive_success_same_line if { + policy := `package p + + camelCase := "yes" # regal ignore:prefer-snake-case + ` + report := main.report with input as regal.parse_module("p.rego", policy) + with config.merged_config as {"rules": {"style": {"prefer-snake-case": {"level": "error"}}}} + + count(report) == 0 +} + test_main_ignore_directive_multiple_success if { policy := `package p diff --git a/bundle/regal/rules/bugs/inconsistent_args.rego b/bundle/regal/rules/bugs/inconsistent_args.rego index 9cb84dce..28c0351e 100644 --- a/bundle/regal/rules/bugs/inconsistent_args.rego +++ b/bundle/regal/rules/bugs/inconsistent_args.rego @@ -16,17 +16,11 @@ report contains violation if { # to have block level scoped ignore directives... function_args_by_name := {name: args_list | some i - - # regal ignore:prefer-some-in-iteration - name := ast.ref_to_string(ast.functions[i].head.ref) + name := ast.ref_to_string(ast.functions[i].head.ref) # regal ignore:prefer-some-in-iteration args_list := [args | some j - - # regal ignore:prefer-some-in-iteration - ast.ref_to_string(ast.functions[j].head.ref) == name - - # regal ignore:prefer-some-in-iteration - args := ast.functions[j].head.args + ast.ref_to_string(ast.functions[j].head.ref) == name # regal ignore:prefer-some-in-iteration + args := ast.functions[j].head.args # regal ignore:prefer-some-in-iteration ] count(args_list) > 1 } diff --git a/bundle/regal/rules/custom/one_liner_rule.rego b/bundle/regal/rules/custom/one_liner_rule.rego index b747b539..fa83dc9f 100644 --- a/bundle/regal/rules/custom/one_liner_rule.rego +++ b/bundle/regal/rules/custom/one_liner_rule.rego @@ -23,7 +23,6 @@ has_if if "if" in config.capabilities.future_keywords has_if if "rego_v1_import" in config.capabilities.features -# regal ignore:rule-length report contains violation if { # No need to traverse rules here if we're not importing `if` ast.imports_keyword(input.imports, "if")