Skip to content

Commit cf65658

Browse files
authored
Merge pull request #58 from rubensousa/report_config
Add option to configure report
2 parents c4f6e2c + ac68240 commit cf65658

File tree

17 files changed

+240
-25
lines changed

17 files changed

+240
-25
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,18 @@ projectGuard {
133133
- `./gradlew projectGuardCheck`: Runs the dependency analysis on individual modules and generates a html report under `module/build/reports/projectguard/index.html`.
134134
- `./gradlew projectGuardBaseline`: Creates a `projectguard-baseline.yml` file with all current restrictions. This allows you to start enforcing rules on new code without having to fix all existing issues first.
135135

136+
137+
## Report configuration options
138+
139+
```kotlin
140+
projectGuard {
141+
report {
142+
// Default is false. When true, libraries are displayed in the dependency graph section
143+
showLibrariesInGraph = true
144+
}
145+
}
146+
```
147+
136148
## License
137149

138150
Copyright 2026 Rúben Sousa

projectguard/api/projectguard.api

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public abstract class com/rubensousa/projectguard/plugin/ProjectGuardExtension :
3838
public fun <init> (Lorg/gradle/api/model/ObjectFactory;)V
3939
public fun guard (Ljava/lang/String;Lorg/gradle/api/Action;)V
4040
public fun guardRule (Lorg/gradle/api/Action;)Lcom/rubensousa/projectguard/plugin/GuardRule;
41+
public fun report (Lorg/gradle/api/Action;)V
4142
public fun restrictDependency (Ljava/lang/String;Lorg/gradle/api/Action;)V
4243
public fun restrictDependency (Lorg/gradle/api/provider/Provider;Lorg/gradle/api/Action;)V
4344
public fun restrictDependencyRule (Lorg/gradle/api/Action;)Lcom/rubensousa/projectguard/plugin/RestrictDependencyRule;
@@ -55,6 +56,8 @@ public abstract interface class com/rubensousa/projectguard/plugin/ProjectGuardS
5556
public abstract fun guard (Ljava/lang/String;Lorg/gradle/api/Action;)V
5657
public fun guard (Lorg/gradle/api/internal/catalog/DelegatingProjectDependency;Lorg/gradle/api/Action;)V
5758
public abstract fun guardRule (Lorg/gradle/api/Action;)Lcom/rubensousa/projectguard/plugin/GuardRule;
59+
public fun report (Lgroovy/lang/Closure;)V
60+
public abstract fun report (Lorg/gradle/api/Action;)V
5861
public fun restrictDependency (Ljava/lang/String;Lgroovy/lang/Closure;)V
5962
public abstract fun restrictDependency (Ljava/lang/String;Lorg/gradle/api/Action;)V
6063
public fun restrictDependency (Lorg/gradle/api/internal/catalog/DelegatingProjectDependency;Lorg/gradle/api/Action;)V
@@ -72,6 +75,11 @@ public abstract interface class com/rubensousa/projectguard/plugin/ProjectGuardS
7275
public abstract fun restrictModuleRule (Lorg/gradle/api/Action;)Lcom/rubensousa/projectguard/plugin/RestrictModuleRule;
7376
}
7477

78+
public abstract interface class com/rubensousa/projectguard/plugin/ReportScope {
79+
public abstract fun getShowLibrariesInGraph ()Z
80+
public abstract fun setShowLibrariesInGraph (Z)V
81+
}
82+
7583
public final class com/rubensousa/projectguard/plugin/RestrictDependencyRule {
7684
}
7785

projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/ProjectGuardExtension.kt

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@ import com.rubensousa.projectguard.plugin.internal.GuardSpec
2323
import com.rubensousa.projectguard.plugin.internal.ModuleRestrictionScopeImpl
2424
import com.rubensousa.projectguard.plugin.internal.ModuleRestrictionSpec
2525
import com.rubensousa.projectguard.plugin.internal.ProjectGuardSpec
26+
import com.rubensousa.projectguard.plugin.internal.ReportScopeImpl
27+
import com.rubensousa.projectguard.plugin.internal.ReportSpec
2628
import com.rubensousa.projectguard.plugin.internal.getDependencyPath
2729
import org.gradle.api.Action
2830
import org.gradle.api.artifacts.MinimalExternalModuleDependency
29-
import org.gradle.api.internal.catalog.DelegatingProjectDependency
3031
import org.gradle.api.model.ObjectFactory
3132
import org.gradle.api.provider.Provider
3233
import org.gradle.kotlin.dsl.listProperty
@@ -39,6 +40,7 @@ abstract class ProjectGuardExtension @Inject constructor(
3940
private val guardSpecs = objects.listProperty<GuardSpec>()
4041
private val moduleRestrictionSpecs = objects.listProperty<ModuleRestrictionSpec>()
4142
private val dependencyRestrictionSpecs = objects.listProperty<DependencyRestrictionSpec>()
43+
private var reportSpec = ReportSpec(showLibrariesInGraph = false)
4244

4345
override fun restrictModule(modulePath: String, action: Action<ModuleRestrictionScope>) {
4446
val scope = ModuleRestrictionScopeImpl()
@@ -117,11 +119,20 @@ abstract class ProjectGuardExtension @Inject constructor(
117119
return rule
118120
}
119121

122+
override fun report(action: Action<ReportScope>) {
123+
val scope = ReportScopeImpl()
124+
action.execute(scope)
125+
reportSpec = reportSpec.copy(
126+
showLibrariesInGraph = scope.showLibrariesInGraph
127+
)
128+
}
129+
120130
internal fun getSpec(): ProjectGuardSpec {
121131
return ProjectGuardSpec(
122132
guardSpecs = guardSpecs.get(),
123133
moduleRestrictionSpecs = moduleRestrictionSpecs.get(),
124-
dependencyRestrictionSpecs = dependencyRestrictionSpecs.get()
134+
dependencyRestrictionSpecs = dependencyRestrictionSpecs.get(),
135+
reportSpec = reportSpec
125136
)
126137
}
127138

projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/ProjectGuardPlugin.kt

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class ProjectGuardPlugin : Plugin<Project> {
6161
return
6262
}
6363
val extension = getExtension(rootProject)
64-
val aggregationTasks = createAggregationTasks(rootProject)
64+
val aggregationTasks = createAggregationTasks(rootProject, extension)
6565
val individualModuleTasks = mutableListOf<ModuleTasks>()
6666
rootProject.subprojects.forEach { targetProject ->
6767
val moduleTasks = createModuleTasks(
@@ -166,13 +166,14 @@ class ProjectGuardPlugin : Plugin<Project> {
166166

167167
private fun createAggregationTasks(
168168
rootProject: Project,
169+
extension: ProjectGuardExtension,
169170
): AggregationTasks {
170171
return AggregationTasks(
171172
dependencyDump = createAggregateDependencyDumpTask(rootProject),
172173
restrictionDump = createAggregateRestrictionTask(rootProject),
173174
baselineDump = createBaselineTask(rootProject),
174175
baselineCreate = createBaselineReferenceTask(rootProject),
175-
check = createAggregateCheckTask(rootProject)
176+
check = createAggregateCheckTask(rootProject, extension)
176177
)
177178
}
178179

@@ -233,30 +234,38 @@ class ProjectGuardPlugin : Plugin<Project> {
233234
extension: ProjectGuardExtension,
234235
): ModuleTasks {
235236
return ModuleTasks(
236-
check = createCheckTask(targetProject),
237+
check = createCheckTask(targetProject, extension),
237238
restrictionDump = createModuleRestrictionTask(targetProject, extension),
238239
dependencyDump = createDependencyDumpTask(targetProject)
239240
)
240241
}
241242

242-
private fun createCheckTask(project: Project): TaskProvider<TaskCheck> {
243+
private fun createCheckTask(
244+
project: Project,
245+
extension: ProjectGuardExtension,
246+
): TaskProvider<TaskCheck> {
243247
return project.tasks.register(
244248
"projectGuardCheck",
245249
TaskCheck::class.java
246250
) {
247251
group = "verification"
248252
description = "Verifies if there are any dependency restrictions"
253+
reportSpec.set(extension.getSpec().reportSpec)
249254
outputs.upToDateWhen { false }
250255
}
251256
}
252257

253-
private fun createAggregateCheckTask(project: Project): TaskProvider<TaskCheck> {
258+
private fun createAggregateCheckTask(
259+
project: Project,
260+
extension: ProjectGuardExtension,
261+
): TaskProvider<TaskCheck> {
254262
return project.tasks.register(
255263
"projectGuardAggregateCheck",
256264
TaskCheck::class.java
257265
) {
258266
group = "verification"
259267
description = "Verifies if there are any dependency restrictions"
268+
reportSpec.set(extension.getSpec().reportSpec)
260269
outputs.upToDateWhen { false }
261270
}
262271
}

projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/ProjectGuardScope.kt

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ interface ProjectGuardScope {
7272
*/
7373
fun restrictModule(
7474
moduleDelegation: DelegatingProjectDependency,
75-
action: Action<ModuleRestrictionScope> = Action<ModuleRestrictionScope> { }
75+
action: Action<ModuleRestrictionScope> = Action<ModuleRestrictionScope> { },
7676
) = restrictModule(modulePath = moduleDelegation.path, action = action)
7777

7878
// Just here for groovy support
@@ -122,7 +122,7 @@ interface ProjectGuardScope {
122122
*/
123123
fun guard(
124124
moduleDelegation: DelegatingProjectDependency,
125-
action: Action<GuardScope>
125+
action: Action<GuardScope>,
126126
) = guard(modulePath = moduleDelegation.path, action = action)
127127

128128
/**
@@ -167,7 +167,7 @@ interface ProjectGuardScope {
167167
*/
168168
fun restrictDependency(
169169
dependencyDelegation: DelegatingProjectDependency,
170-
action: Action<DependencyRestrictionScope> = Action<DependencyRestrictionScope> { }
170+
action: Action<DependencyRestrictionScope> = Action<DependencyRestrictionScope> { },
171171
) = restrictDependency(dependencyPath = dependencyDelegation.path, action = action)
172172

173173
/**
@@ -188,16 +188,23 @@ interface ProjectGuardScope {
188188
// Just here for groovy support
189189
fun restrictDependency(
190190
dependencyPath: String,
191-
closure: Closure<DependencyRestrictionScope>
191+
closure: Closure<DependencyRestrictionScope>,
192192
) {
193193
restrictDependency(dependencyPath, ConfigureUtil.configureUsing(closure))
194194
}
195195

196196
// Just here for groovy support
197197
fun restrictDependency(
198198
provider: Provider<MinimalExternalModuleDependency>,
199-
closure: Closure<DependencyRestrictionScope>
199+
closure: Closure<DependencyRestrictionScope>,
200200
) {
201201
restrictDependency(provider, ConfigureUtil.configureUsing(closure))
202202
}
203+
204+
fun report(action: Action<ReportScope>)
205+
206+
fun report(closure: Closure<ReportScope>) {
207+
report(ConfigureUtil.configureUsing(closure))
208+
}
209+
203210
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright 2026 Rúben Sousa
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.rubensousa.projectguard.plugin
18+
19+
interface ReportScope {
20+
var showLibrariesInGraph: Boolean
21+
}

projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/internal/ProjectGuardSpec.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ internal data class ProjectGuardSpec(
2222
val guardSpecs: List<GuardSpec>,
2323
val moduleRestrictionSpecs: List<ModuleRestrictionSpec>,
2424
val dependencyRestrictionSpecs: List<DependencyRestrictionSpec>,
25+
val reportSpec: ReportSpec,
2526
) : Serializable
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright 2026 Rúben Sousa
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.rubensousa.projectguard.plugin.internal
18+
19+
import com.rubensousa.projectguard.plugin.ReportScope
20+
21+
internal class ReportScopeImpl : ReportScope {
22+
23+
override var showLibrariesInGraph: Boolean = false
24+
25+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright 2026 Rúben Sousa
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.rubensousa.projectguard.plugin.internal
18+
19+
import java.io.Serializable
20+
21+
internal data class ReportSpec(
22+
val showLibrariesInGraph: Boolean,
23+
) : Serializable

projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/internal/report/VerificationReportBuilder.kt

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,27 @@
1717
package com.rubensousa.projectguard.plugin.internal.report
1818

1919
import com.rubensousa.projectguard.plugin.internal.DependencyConfiguration
20+
import com.rubensousa.projectguard.plugin.internal.ReportSpec
2021
import com.rubensousa.projectguard.plugin.internal.SuppressionMap
2122

2223
internal class VerificationReportBuilder(
2324
private val suppressionMap: SuppressionMap,
25+
private val reportSpec: ReportSpec,
2426
) {
2527

2628
fun build(
2729
dependencyGraphDump: DependencyGraphDump,
2830
restrictionDump: RestrictionDump,
2931
): VerificationReport {
32+
return VerificationReport(
33+
modules = buildVerificationReports(restrictionDump),
34+
dependencyGraph = buildDependencyGraph(dependencyGraphDump)
35+
)
36+
}
37+
38+
private fun buildVerificationReports(
39+
restrictionDump: RestrictionDump,
40+
): List<VerificationModuleReport> {
3041
val totalFatalMatches = mutableMapOf<String, MutableList<FatalMatch>>()
3142
val totalSuppressedMatches = mutableMapOf<String, MutableList<SuppressedMatch>>()
3243
val reports = mutableSetOf<String>()
@@ -63,30 +74,39 @@ internal class VerificationReportBuilder(
6374
reports.add(moduleReport.module)
6475
}
6576
}
66-
val sortedReports = reports.sortedBy { it }
77+
return reports.sorted()
6778
.map { moduleId ->
6879
VerificationModuleReport(
6980
module = moduleId,
7081
fatal = totalFatalMatches[moduleId]?.sortedBy { it.dependency } ?: emptyList(),
7182
suppressed = totalSuppressedMatches[moduleId]?.sortedBy { it.dependency } ?: emptyList(),
7283
)
7384
}
85+
}
86+
87+
private fun buildDependencyGraph(
88+
dependencyGraphDump: DependencyGraphDump,
89+
): Map<String, List<DependencyReferenceDump>> {
7490
val graph = mutableMapOf<String, MutableSet<DependencyReferenceDump>>()
7591
dependencyGraphDump.modules.forEach { report ->
7692
report.configurations.forEach { configuration ->
7793
// TODO: Until https://github.com/rubensousa/ProjectGuard/issues/3 is clarified,
7894
// filter out test dependencies from the graph reports
7995
val moduleDependencies = graph.getOrPut(report.module) { mutableSetOf() }
8096
if (DependencyConfiguration.isReleaseConfiguration(configuration.id)) {
81-
moduleDependencies.addAll(configuration.dependencies.map { dependency ->
82-
DependencyReferenceDump(dependency.id, dependency.isLibrary)
97+
moduleDependencies.addAll(configuration.dependencies.mapNotNull { dependency ->
98+
if (reportSpec.showLibrariesInGraph || !dependency.isLibrary) {
99+
DependencyReferenceDump(dependency.id, dependency.isLibrary)
100+
} else {
101+
null
102+
}
83103
})
84104
}
85105
}
86106
}
87-
return VerificationReport(sortedReports, graph.mapValues { entry ->
107+
return graph.mapValues { entry ->
88108
entry.value.sortedBy { it.id }
89-
})
109+
}
90110
}
91111

92112
}

0 commit comments

Comments
 (0)