Skip to content

Commit 85b01a5

Browse files
authored
Add ruleClass api for priority override (#52)
1 parent bd5b869 commit 85b01a5

File tree

8 files changed

+72
-25
lines changed

8 files changed

+72
-25
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
.gradle/
2+
.kotlin/
23
build/
34

45
.idea/
56
*.ipr
67
*.iml
78
*.iws
89
out/
9-
.obsidian/
10+
.obsidian/

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,15 +166,20 @@ The default threshold is MEDIUM.
166166

167167
#### Overriding rule priority
168168

169-
You can override the default priority of a rule using the `ruleName` and priority as `LOW`, `MEDIUM`, or `HIGH`:
169+
You can override the default priority of a rule using the `ruleClass` or `ruleName` and `priority` as `LOW`, `MEDIUM`, or `HIGH`:
170170
```kotlin
171171
archRules {
172-
rule("deprecated") {
172+
ruleClass("com.netflix.nebula.archrules.deprecation") {
173173
priority("HIGH")
174174
}
175+
ruleName("deprecated") {
176+
priority("LOW")
177+
}
175178
}
176179
```
177180

181+
The `ruleName` will take precedent over the `ruleClass`.
182+
178183
#### Configuring which code is tested
179184

180185
You can skip running rules on a specific source set:

nebula-archrules-gradle-plugin/src/main/java/com/netflix/nebula/archrules/gradle/RunRulesParams.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,7 @@ public interface RunRulesParams extends WorkParameters {
1414

1515
Property<@NonNull File> getDataOutputFile();
1616

17-
MapProperty<@NonNull String, @NonNull Priority> getPriorityOverrides();
17+
MapProperty<@NonNull String, @NonNull Priority> getPriorityOverridesByName();
18+
19+
MapProperty<@NonNull String, @NonNull Priority> getPriorityOverridesByClass();
1820
}

nebula-archrules-gradle-plugin/src/main/java/com/netflix/nebula/archrules/gradle/RunRulesWorkAction.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,28 @@ public void execute() {
3434
final var classesToCheck = new ClassFileImporter()
3535
.importPaths(getParameters().getClassesToCheck().getFiles().stream().map(File::toPath).toList());
3636
final List<RuleResult> violationList = new ArrayList<>();
37-
final var overrides = getParameters().getPriorityOverrides().getOrElse(Map.of());
37+
final var overridesByName = getParameters().getPriorityOverridesByName().getOrElse(Map.of());
38+
final var overridesByClass = getParameters().getPriorityOverridesByClass().getOrElse(Map.of());
39+
3840
ruleClasses.forEach(ruleClass -> ruleClass.getRules().forEach((id, archRule) -> {
3941
final var result = Runner.check(archRule, classesToCheck);
4042

41-
// check if there is a priority override
43+
// check if there is priority override by class first
4244
var priority = result.getPriority();
43-
if (overrides.containsKey(id)) {
44-
priority = overrides.get(id);
45+
String ruleClassName = ruleClass.getClass().getCanonicalName();
46+
for (Map.Entry<String, Priority> override : overridesByClass.entrySet()) {
47+
String overrideRuleName = override.getKey();
48+
if (ruleClassName.startsWith(overrideRuleName)) {
49+
priority = override.getValue();
50+
break;
51+
}
52+
}
53+
// then check if there is a priority override by name
54+
if (overridesByName.containsKey(id)) {
55+
priority = overridesByName.get(id);
4556
}
4657

47-
final var rule = new Rule(ruleClass.getClass().getCanonicalName(), id, archRule.getDescription(), priority);
58+
final var rule = new Rule(ruleClassName, id, archRule.getDescription(), priority);
4859
if (result.hasViolation()) {
4960
result.getFailureReport().getDetails().forEach(detail -> {
5061
if (detail.equals(NO_MATCH_MESSAGE)) {

nebula-archrules-gradle-plugin/src/main/kotlin/com/netflix/nebula/archrules/gradle/ArchrulesExtension.kt

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ abstract class ArchrulesExtension {
2424
/**
2525
* Allow priority overrides
2626
*/
27-
abstract val priorityOverrides: MapProperty<String, Priority>
27+
abstract val priorityOverridesByRuleName: MapProperty<String, Priority>
28+
abstract val priorityOverridesByRuleClass: MapProperty<String, Priority>
2829

2930
/**
3031
* Add a source set to the list of sourcesets to skip
@@ -49,12 +50,31 @@ abstract class ArchrulesExtension {
4950
consoleDetailsThreshold.set(Priority.valueOf(priority))
5051
}
5152

53+
@Deprecated("use ruleName instead")
5254
fun rule(ruleName: String, action: Action<RuleConfig>) {
5355
val config = RuleConfig()
5456
action.execute(config)
5557

5658
config.priority?.let { priority ->
57-
priorityOverrides.put(ruleName, priority)
59+
priorityOverridesByRuleName.put(ruleName, priority)
60+
}
61+
}
62+
63+
fun ruleName(ruleName: String, action: Action<RuleConfig>) {
64+
val config = RuleConfig()
65+
action.execute(config)
66+
67+
config.priority?.let { priority ->
68+
priorityOverridesByRuleName.put(ruleName, priority)
69+
}
70+
}
71+
72+
fun ruleClass(ruleClass: String, action: Action<RuleConfig>) {
73+
val config = RuleConfig()
74+
action.execute(config)
75+
76+
config.priority?.let { priority ->
77+
priorityOverridesByRuleClass.put(ruleClass, priority)
5878
}
5979
}
6080
}

nebula-archrules-gradle-plugin/src/main/kotlin/com/netflix/nebula/archrules/gradle/ArchrulesRunnerPlugin.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ class ArchrulesRunnerPlugin : Plugin<Project> {
9090
tasks.register<CheckRulesTask>("checkArchRules" + sourceSet.name.capitalized()) {
9191
description = "Checks ArchRules on ${sourceSet.name}"
9292
rulesClasspath.setFrom(sourceSetArchRulesRuntime)
93-
priorityOverrides.set(ext.priorityOverrides)
93+
priorityOverridesByName.set(ext.priorityOverridesByRuleName)
94+
priorityOverridesByClass.set(ext.priorityOverridesByRuleClass)
9495
dataFile.set(archRulesReportDir.map {
9596
it.file(sourceSet.name + ".data").asFile
9697
})
@@ -100,4 +101,4 @@ class ArchrulesRunnerPlugin : Plugin<Project> {
100101
onlyIf { !ext.sourceSetsToSkip.get().contains(sourceSetName) }
101102
}
102103
}
103-
}
104+
}

nebula-archrules-gradle-plugin/src/main/kotlin/com/netflix/nebula/archrules/gradle/CheckRulesTask.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ abstract class CheckRulesTask @Inject constructor(private val workerExecutor: Wo
2727
abstract val dataFile: Property<File>
2828

2929
@get:Input
30-
abstract val priorityOverrides: MapProperty<String, Priority>
30+
abstract val priorityOverridesByName: MapProperty<String, Priority>
31+
32+
@get:Input
33+
abstract val priorityOverridesByClass: MapProperty<String, Priority>
3134

3235
@TaskAction
3336
fun checkRules() {
@@ -37,7 +40,8 @@ abstract class CheckRulesTask @Inject constructor(private val workerExecutor: Wo
3740
workQueue.submit(RunRulesWorkAction::class) {
3841
getClassesToCheck().from(sourcesToCheck)
3942
getDataOutputFile().set(dataFile)
40-
getPriorityOverrides().set(this@CheckRulesTask.priorityOverrides)
43+
getPriorityOverridesByName().set(this@CheckRulesTask.priorityOverridesByName)
44+
getPriorityOverridesByClass().set(this@CheckRulesTask.priorityOverridesByClass)
4145
}
4246
}
4347
}

nebula-archrules-gradle-plugin/src/test/kotlin/com/netflix/nebula/archrules/gradle/ArchrulesRunnerPluginTest.kt

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -466,15 +466,18 @@ archRules {
466466
}
467467

468468
@Test
469-
fun `can override priority of a rule`() {
469+
fun `can override priority of a rule using both rule class and name`() {
470470
val runner = testProject(projectDir) {
471471
setupConsumerProject {
472472
rawBuildScript(
473473
"""
474474
archRules {
475-
rule("deprecated") {
475+
ruleClass("com.netflix.nebula.archrules.deprecation") {
476476
priority("HIGH")
477477
}
478+
ruleName("deprecated") {
479+
priority("MEDIUM")
480+
}
478481
}
479482
"""
480483
)
@@ -490,17 +493,17 @@ archRules {
490493
val mainReport = projectDir.resolve("build/reports/archrules/main.data")
491494
val results = readDetails(mainReport)
492495

493-
// assert deprecated (LOW) is overridden
496+
val deprecatedForRemovalResults = results.filter { it.rule.ruleName.equals("deprecatedForRemoval") }
497+
assertThat(deprecatedForRemovalResults).hasSize(1)
498+
deprecatedForRemovalResults.forEach { result ->
499+
assertThat(result.rule.priority).isEqualTo(Priority.HIGH)
500+
}
501+
494502
val deprecatedResults = results.filter { it.rule.ruleName.equals("deprecated") }
495503
assertThat(deprecatedResults).hasSize(2)
496504
deprecatedResults.forEach { result ->
497-
assertThat(result.rule.priority).isEqualTo(Priority.HIGH)
505+
assertThat(result.rule.priority).isEqualTo(Priority.MEDIUM)
498506
}
499-
500-
// assert deprecatedForRemoval (MEDIUM), which is in the same class but not the same rule, is not overridden
501-
val deprecatedForRemovalResult = results.firstOrNull { it.rule.ruleName.equals("deprecatedForRemoval") }
502-
assertThat(deprecatedForRemovalResult).isNotNull
503-
assertThat(deprecatedForRemovalResult!!.rule.priority).isEqualTo(Priority.MEDIUM)
504507
}
505508

506509
@Test
@@ -510,7 +513,7 @@ archRules {
510513
rawBuildScript(
511514
"""
512515
archRules {
513-
rule("deprecatedForRemoval") {
516+
ruleName("deprecatedForRemoval") {
514517
priority("NONE")
515518
}
516519
}

0 commit comments

Comments
 (0)