Skip to content

Commit 8a09b2b

Browse files
committed
initial runner plugin
fix library plugin to work with project dependencies
1 parent c51811f commit 8a09b2b

File tree

21 files changed

+501
-31
lines changed

21 files changed

+501
-31
lines changed

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ public class LibraryArchRules implements ArchRulesService {
6161
}
6262
```
6363

64+
You will also need to create a file at `src/archRules/resources/META-INF/services/com.netflix.nebula.archrules.core.ArchRulesService` and add the fully qualified name of your rules class to that file.
65+
6466
When authoring rules about the usage of your own library code, it is recommended to colocate your rules library in the
6567
same project as the library code. The ArchRules plugin will publish the rules in a separate Jar, and the Runner plugin
6668
will select that jar for running rules, but these rule classes will not end up in the runtime classpath.
@@ -106,6 +108,32 @@ public class LibraryArchRulesTest {
106108
}
107109
```
108110

111+
## Running Rules
112+
113+
In order to run rules in a project, add the runner plugin:
114+
```kotlin
115+
plugins {
116+
id("com.netflix.nebula.archrules.runner") version ("latest.release")
117+
}
118+
```
119+
120+
This will create a task for running rules against each source set, eg. `checkArchRulesMain` for the Main source set.
121+
These tasks will run as dependencies of the `check` task.
122+
123+
If you want to run rules on all source sets, add the rule library as a dependency to the `archRules` configuration:
124+
```kotlin
125+
dependencies {
126+
archRules("your:rules:1.0.0")
127+
}
128+
```
129+
130+
Rules that exist in a library on each sourceSet's classpath will also be used:
131+
```kotlin
132+
dependencies {
133+
implementation("some.library:which-also-has-rules:1.0.0")
134+
}
135+
```
136+
109137
## How it works
110138

111139
The Archrules Library plugin produces a separate Jar for the `archRules` sourceset, which is exposed as an alternate variant of the library.

nebula-archrules-core/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ testing {
1818
}
1919
java {
2020
toolchain {
21-
languageVersion = JavaLanguageVersion.of(11)
21+
languageVersion = JavaLanguageVersion.of(8)
2222
}
2323
}
2424
dependencyLocking {

nebula-archrules-core/src/main/java/com/netflix/nebula/archrules/core/NoClassesMatchedEvent.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public ConditionEvent invert() {
2323

2424
@Override
2525
public List<String> getDescriptionLines() {
26-
return List.of(NO_MATCH_MESSAGE);
26+
return Collections.singletonList(NO_MATCH_MESSAGE);
2727
}
2828

2929
@Override

nebula-archrules-core/src/main/java/com/netflix/nebula/archrules/core/Runner.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public static EvaluationResult check(ArchRule rule, JavaClasses classesToCheck)
1212
return rule.evaluate(classesToCheck);
1313
} catch (AssertionError e) {
1414
// evaluate the rule again with more leniency so we can get the priority
15-
final var result2 = rule.allowEmptyShould(true).evaluate(classesToCheck);
15+
final EvaluationResult result2 = rule.allowEmptyShould(true).evaluate(classesToCheck);
1616
if (result2.hasViolation()) {
1717
return result2;
1818
} else {
@@ -26,12 +26,13 @@ public static EvaluationResult check(ArchRule rule, JavaClasses classesToCheck)
2626
/**
2727
* Check a rule against some classes.
2828
* This can be invoked from the real Gradle plugin or unit tests for rules to ensure the same logic is observed there.
29-
* @param rule the rule to run
29+
*
30+
* @param rule the rule to run
3031
* @param classesToCheck the classes to run the rule against
3132
* @return the result, which contains information about failure
3233
*/
3334
public static EvaluationResult check(ArchRule rule, Class<?>... classesToCheck) {
34-
final var classes = new ClassFileImporter()
35+
final JavaClasses classes = new ClassFileImporter()
3536
.importClasses(classesToCheck);
3637
return check(rule, classes);
3738
}

nebula-archrules-core/src/test/java/com/netflix/nebula/archrules/core/RunnerTest.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.netflix.nebula.archrules.core;
22

33
import com.tngtech.archunit.lang.ArchRule;
4+
import com.tngtech.archunit.lang.EvaluationResult;
45
import com.tngtech.archunit.lang.Priority;
56
import com.tngtech.archunit.lang.syntax.ArchRuleDefinition;
67
import org.junit.jupiter.api.Test;
@@ -11,19 +12,19 @@
1112
public class RunnerTest {
1213
@Test
1314
public void test_pass() {
14-
final var result = Runner.check(noDeprecatedRule, PassingClass.class);
15+
final EvaluationResult result = Runner.check(noDeprecatedRule, PassingClass.class);
1516
assertThat(result.hasViolation()).isFalse();
1617
}
1718

1819
@Test
1920
public void test_fail() {
20-
final var result = Runner.check(noDeprecatedRule, FailingClass.class);
21+
final EvaluationResult result = Runner.check(noDeprecatedRule, FailingClass.class);
2122
assertThat(result.hasViolation()).isTrue();
2223
}
2324

2425
@Test
2526
public void test_fail_and_pass() {
26-
final var result = Runner.check(noDeprecatedRule, PassingClass.class, FailingClass.class);
27+
final EvaluationResult result = Runner.check(noDeprecatedRule, PassingClass.class, FailingClass.class);
2728
assertThat(result.hasViolation()).isTrue();
2829
assertThat(result.getFailureReport().getDetails()).hasSize(1);
2930
}
@@ -51,13 +52,13 @@ static class SmokeTest {
5152

5253
@Test
5354
public void test_smoke_pass() {
54-
final var result = Runner.check(smokeTestRule, SmokeTest.class);
55+
final EvaluationResult result = Runner.check(smokeTestRule, SmokeTest.class);
5556
assertThat(result.hasViolation()).isFalse();
5657
}
5758

5859
@Test
5960
public void test_smoke_fail() {
60-
final var result = Runner.check(smokeTestRule, SmokeTestFail.class);
61+
final EvaluationResult result = Runner.check(smokeTestRule, SmokeTestFail.class);
6162
assertThat(result.hasViolation()).isTrue();
6263
assertThat(result.getFailureReport().getDetails())
6364
.contains(NoClassesMatchedEvent.NO_MATCH_MESSAGE);

nebula-archrules-gradle-plugin/build.gradle.kts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ repositories {
77
mavenCentral()
88
}
99
dependencies {
10+
implementation(project(":nebula-archrules-core"))
1011
testImplementation("net.javacrumbs.json-unit:json-unit-assertj:5.0.0")
1112
testImplementation("org.json:json:20250517")
1213
}
@@ -30,7 +31,7 @@ gradlePlugin {
3031
}
3132
java {
3233
toolchain {
33-
languageVersion = JavaLanguageVersion.of(11)
34+
languageVersion = JavaLanguageVersion.of(17)
3435
}
3536
}
3637
testing {

nebula-archrules-gradle-plugin/gradle.lockfile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
cglib:cglib-nodep:3.2.2=integTestRuntimeClasspath,testRuntimeClasspath
55
com.jayway.jsonpath:json-path:2.9.0=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
66
com.netflix.nebula:nebula-test:11.7.1=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
7+
com.tngtech.archunit:archunit:1.4.1=compileClasspath,integTestCompileClasspath,integTestRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
78
net.bytebuddy:byte-buddy:1.17.7=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
89
net.javacrumbs.json-unit:json-unit-assertj:5.0.0=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
910
net.javacrumbs.json-unit:json-unit-core:5.0.0=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
@@ -44,5 +45,5 @@ org.junit.platform:junit-platform-launcher:1.14.0=integTestCompileClasspath,inte
4445
org.objenesis:objenesis:2.4=integTestRuntimeClasspath,testRuntimeClasspath
4546
org.opentest4j:opentest4j:1.3.0=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
4647
org.ow2.asm:asm:9.3=integTestRuntimeClasspath,testRuntimeClasspath
47-
org.slf4j:slf4j-api:2.0.11=integTestRuntimeClasspath,testRuntimeClasspath
48-
empty=annotationProcessor,integTestAnnotationProcessor,integTestKotlinScriptDefExtensions,kotlinScriptDefExtensions,runtimeClasspath,testAnnotationProcessor,testKotlinScriptDefExtensions
48+
org.slf4j:slf4j-api:2.0.17=compileClasspath,integTestCompileClasspath,integTestRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
49+
empty=annotationProcessor,integTestAnnotationProcessor,integTestKotlinScriptDefExtensions,kotlinScriptDefExtensions,testAnnotationProcessor,testKotlinScriptDefExtensions
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.netflix.nebula.archrules.gradle;
2+
3+
import org.gradle.api.Named;
4+
import org.gradle.api.attributes.Attribute;
5+
import org.jspecify.annotations.NonNull;
6+
7+
public interface ArchRuleAttribute extends Named {
8+
Attribute<@NonNull ArchRuleAttribute> ARCH_RULES_ATTRIBUTE =
9+
Attribute.of("com.netflix.nebula.archrules", ArchRuleAttribute.class);
10+
String ARCH_RULES = "arch-rules";
11+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.netflix.nebula.archrules.gradle;
2+
3+
import com.tngtech.archunit.lang.Priority;
4+
5+
import java.io.Serializable;
6+
7+
public record Rule(String ruleClass, String ruleName, String description, Priority priority) implements Serializable {
8+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.netflix.nebula.archrules.gradle;
2+
3+
import java.io.Serializable;
4+
5+
public record RuleResult(
6+
Rule rule,
7+
String message,
8+
RuleResultStatus status
9+
) implements Serializable {
10+
}

0 commit comments

Comments
 (0)