-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This builds upon the design laid out in #282, and on @sesponda's excellent work on that. My approach for testing this was to implement an actual "real world" linter rule from the backlog, and `prefer-package-imports` seemed like a good choice. The rule aggregates package names (or paths) from each input file, along with any import paths. The report rule then checks each import collected against the list of package paths to determine if the import matches a package. If not, the rule will consider that a violation. As is often the case when real world meets the original design, "some" modifications proved to be necessary. The collection of aggregate data is now run alongside the usual linter rule evaluation, as we conveniently may use the same input files for aggregating data. Once that's done, we now send another eval call using only the data aggregated as input. Each aggregate rule is now provided only the data aggregated by _that rule_, so there's no need for policy authors to traverse through all of the aggregates, but one may simply refer to the `input.aggregate` array for the same set of entries as one collected previously. I've also had to add an alternative schema for the input when these rules are evaluated (currently only enforced by `regal test`). Perhaps `anyOf` would be a better option than two separate schemas, but I'll explore that at a later point. Fixes #326 Fixes #343 Signed-off-by: Anders Eknert <anders@styra.com>
- Loading branch information
1 parent
9063cf0
commit 590ce2e
Showing
31 changed files
with
717 additions
and
180 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# METADATA | ||
# description: Prefer importing packages over rules | ||
package regal.rules.imports["prefer-package-imports"] | ||
|
||
import future.keywords.contains | ||
import future.keywords.if | ||
import future.keywords.in | ||
|
||
import data.regal.ast | ||
import data.regal.config | ||
import data.regal.result | ||
|
||
cfg := config.for_rule("imports", "prefer-package-imports") | ||
|
||
aggregate contains entry if { | ||
imports_with_location := [imp | | ||
some _import in input.imports | ||
|
||
_import.path.value[0].value == "data" | ||
count(_import.path.value) > 1 | ||
path := [part.value | some part in array.slice(_import.path.value, 1, count(_import.path.value))] | ||
|
||
imp := object.union(result.location(_import), {"path": path}) | ||
] | ||
|
||
entry := result.aggregate(rego.metadata.chain(), { | ||
"imports": imports_with_location, | ||
"package_path": [part.value | some i, part in input["package"].path; i > 0], | ||
}) | ||
} | ||
|
||
# METADATA | ||
# schemas: | ||
# - input: schema.regal.aggregate | ||
aggregate_report contains violation if { | ||
all_package_paths := {pkg | | ||
some entry in input.aggregate | ||
pkg := entry.aggregate_data.package_path | ||
} | ||
|
||
all_imports := {imp | | ||
some entry in input.aggregate | ||
some imp in entry.aggregate_data.imports | ||
} | ||
|
||
some imp in all_imports | ||
not imp.path in all_package_paths | ||
not imp.path in ignored_import_paths | ||
|
||
violation := result.fail(rego.metadata.chain(), {"location": imp.location}) | ||
} | ||
|
||
ignored_import_paths contains path if { | ||
some item in cfg["ignore-import-paths"] | ||
path := [part | | ||
some i, p in split(item, ".") | ||
part := normalize_part(i, p) | ||
] | ||
} | ||
|
||
normalize_part(0, part) := part if part != "data" | ||
|
||
normalize_part(i, part) := part if i > 0 |
Oops, something went wrong.