Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,13 @@ archRulesAggregate {
}
```

#### Filtering specific rules
If you would like to only display certain rules or rule classes on the CLI, you can use the following flags.
(Note: these rules must still be on the classpath and not excluded.)
```commandline
./gradlew archRulesConsoleReport --rule-name=deprecated --rule-class=com.netflix.nebula.archrules.nullability
```

## How it works

The Archrules Library plugin produces a separate Jar for the `archRules` sourceset, which is exposed as an alternate variant of the library. It also will automatically generate a `META-INF/services` file which contains a reference for each implementation of `com.netflix.nebula.archrules.core.ArchRulesService` to declare it as a service provider.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package com.netflix.nebula.archrules.gradle
import com.tngtech.archunit.lang.Priority
import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.*
import org.gradle.api.tasks.options.Option
import org.gradle.internal.logging.text.StyledTextOutput
import org.gradle.internal.logging.text.StyledTextOutputFactory
import org.gradle.kotlin.dsl.support.get
Expand Down Expand Up @@ -38,12 +38,31 @@ abstract class PrintConsoleReportTask : DefaultTask() {
@get:Optional
abstract val detailsThreshold: Property<Priority>

private var filteredRules: List<String> = emptyList()
private var filteredRuleClasses: List<String> = emptyList()

@Option(option = "rule-name", description = "Print only results for the specified rule name(s). Can be specified multiple times.")
fun filterByRuleName(rules: List<String>) {
filteredRules = rules
}

@Option(option = "rule-class", description = "Print only results for rule classes matching the specified prefix(es). Can be specified multiple times.")
fun filterByRuleClass(ruleClasses: List<String>) {
filteredRuleClasses = ruleClasses
}

@TaskAction
fun printReport() {
val consoleOutput = services.get<StyledTextOutputFactory>().create("archrules")
val list = dataFiles.files
.filter(File::exists)
.flatMap { ViolationsUtil.readDetails(it) }
.filter {
val noFilters = filteredRules.isEmpty() && filteredRuleClasses.isEmpty()
val matchesRule = filteredRules.contains(it.rule().ruleName())
val matchesClass = filteredRuleClasses.any { prefix -> it.rule().ruleClass().startsWith(prefix) }
noFilters || matchesRule || matchesClass
}
.toList()
val byRule = ViolationsUtil.consolidatedFailures(list)
ViolationsUtil.printSummary(byRule, consoleOutput, summaryForPassingDisabled.get(), logger.isInfoEnabled)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,51 @@ archRules {
assertThat(results).isEmpty()
}

@Test
fun `ruleName level source set includes`() {
val runner = testProject(projectDir) {
setupConsumerProject {
dependencies("""archRules("com.netflix.nebula:archrules-nullability:0.+")""")
}
}

val result = runner.run("archRulesConsoleReport", "--rule-name=no Optional class fields", "--rule-name=deprecated", "--stacktrace")
assertThat(result.task(":checkArchRulesMain")).hasOutcome(TaskOutcome.SUCCESS, TaskOutcome.FROM_CACHE)

assertThat(result.output)
.contains("deprecated")
.contains("no Optional class fields")
.doesNotContain("deprecatedForRemoval")
}

@Test
fun `ruleClass level source set includes`() {
val runner = testProject(projectDir) {
setupConsumerProject {
dependencies("""
archRules("com.netflix.nebula:archrules-nullability:0.+")
archRules("com.netflix.nebula:archrules-joda:0.+")
""")
}
}

val result = runner.run("archRulesConsoleReport", "--rule-class=com.netflix.nebula.archrules.nullability", "--rule-name=jodaRule", "--stacktrace")
assertThat(result.task(":checkArchRulesMain")).hasOutcome(TaskOutcome.SUCCESS, TaskOutcome.FROM_CACHE)

val mainReport = projectDir.resolve("build/reports/archrules/main.data")
val nullabilityRuleNames = readDetails(mainReport)
.filter { it.rule.ruleClass().startsWith("com.netflix.nebula.archrules.nullability") }
.map { it.rule.ruleName() }
.distinct()

assertThat(nullabilityRuleNames).isNotEmpty()
nullabilityRuleNames.forEach { ruleName ->
assertThat(result.output).contains(ruleName)
}
assertThat(result.output).contains("jodaRule")
assertThat(result.output).doesNotContain("com.netflix.nebula.archrules.deprecation")
}

@Test
fun `invalid priority string logs warning and does not override`() {
val runner = testProject(projectDir) {
Expand Down
Loading