Skip to content

Commit 244b61c

Browse files
committed
Assign dependency scope based on regex filters
Add new filter variables that can be used to categorize a dependency as 'runtime'. If not specified or not matched, a 'development' scope is assumed.
1 parent 727cc5a commit 244b61c

File tree

8 files changed

+95
-23
lines changed

8 files changed

+95
-23
lines changed

plugin/src/main/kotlin/org/gradle/dependencygraph/extractor/DependencyExtractor.kt

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import org.gradle.api.internal.artifacts.configurations.ResolveConfigurationDepe
99
import org.gradle.api.logging.Logging
1010
import org.gradle.dependencygraph.DependencyGraphRenderer
1111
import org.gradle.dependencygraph.model.*
12+
import org.gradle.dependencygraph.model.DependencyScope.RUNTIME
13+
import org.gradle.dependencygraph.model.DependencyScope.DEVELOPMENT
1214
import org.gradle.dependencygraph.util.*
1315
import org.gradle.initialization.EvaluateSettingsBuildOperationType
1416
import org.gradle.initialization.LoadProjectsBuildOperationType
@@ -21,6 +23,9 @@ import java.util.*
2123

2224
const val PARAM_INCLUDE_PROJECTS = "DEPENDENCY_GRAPH_INCLUDE_PROJECTS"
2325
const val PARAM_INCLUDE_CONFIGURATIONS = "DEPENDENCY_GRAPH_INCLUDE_CONFIGURATIONS"
26+
const val PARAM_RUNTIME_PROJECTS = "DEPENDENCY_GRAPH_RUNTIME_PROJECTS"
27+
const val PARAM_RUNTIME_CONFIGURATIONS = "DEPENDENCY_GRAPH_RUNTIME_CONFIGURATIONS"
28+
2429

2530
const val PARAM_REPORT_DIR = "DEPENDENCY_GRAPH_REPORT_DIR"
2631

@@ -42,13 +47,20 @@ abstract class DependencyExtractor :
4247

4348
// Properties are lazily initialized so that System Properties are initialized by the time
4449
// the values are used. This is required due to a bug in older Gradle versions. (https://github.com/gradle/gradle/issues/6825)
45-
private val configurationFilter by lazy {
50+
private val includeFilter by lazy {
4651
ResolvedConfigurationFilter(
4752
pluginParameters.loadOptional(PARAM_INCLUDE_PROJECTS),
4853
pluginParameters.loadOptional(PARAM_INCLUDE_CONFIGURATIONS)
4954
)
5055
}
5156

57+
private val runtimeFilter by lazy {
58+
ResolvedConfigurationFilter(
59+
pluginParameters.loadOptional(PARAM_RUNTIME_PROJECTS),
60+
pluginParameters.loadOptional(PARAM_RUNTIME_CONFIGURATIONS)
61+
)
62+
}
63+
5264
private val dependencyGraphReportDir by lazy {
5365
pluginParameters.loadOptional(PARAM_REPORT_DIR)
5466
}
@@ -157,15 +169,18 @@ abstract class DependencyExtractor :
157169
// It is possible to do better. By tracking the current build operation context, we can assign more precisely.
158170
// See the Gradle Enterprise Build Scan Plugin: `ConfigurationResolutionCapturer_5_0`
159171
val rootPath = projectIdentityPath ?: details.buildPath
172+
val configurationName = details.configurationName
160173

161-
if (!configurationFilter.include(rootPath, details.configurationName)) {
162-
LOGGER.debug("Ignoring resolved configuration: $rootPath - ${details.configurationName}")
174+
if (!includeFilter.include(rootPath, configurationName)) {
175+
LOGGER.debug("Ignoring resolved configuration: $rootPath - $configurationName")
163176
return
164177
}
165178

179+
val scope = if (runtimeFilter.include(rootPath, configurationName)) RUNTIME else DEVELOPMENT
180+
166181
val rootId = if (projectIdentityPath == null) "build $rootPath" else componentId(rootComponent)
167182
val rootOrigin = DependencyOrigin(rootId, rootPath)
168-
val resolvedConfiguration = ResolvedConfiguration(rootOrigin, details.configurationName)
183+
val resolvedConfiguration = ResolvedConfiguration(rootOrigin, configurationName, scope)
169184

170185
for (dependencyComponent in getResolvedDependencies(rootComponent)) {
171186
val directDep = createComponentNode(

plugin/src/main/kotlin/org/gradle/dependencygraph/extractor/ResolvedConfigurationFilter.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
package org.gradle.dependencygraph.extractor
22

33
class ResolvedConfigurationFilter(projectFilter: String?, configurationFilter: String?) {
4-
private val projectRegex = projectFilter?.toRegex()
5-
private val configurationRegex = configurationFilter?.toRegex()
4+
private val projectFilter = projectFilter?.toRegex()
5+
private val configurationFilter = configurationFilter?.toRegex()
66

77
fun include(projectPath: String, configurationName: String): Boolean {
8-
if (projectRegex != null && !projectRegex.matches(projectPath)) {
8+
if (projectFilter != null && !projectFilter.matches(projectPath)) {
99
return false
1010
}
11-
if (configurationRegex != null && !configurationRegex.matches(configurationName)) {
11+
if (configurationFilter != null && !configurationFilter.matches(configurationName)) {
1212
return false
1313
}
1414
return true
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.gradle.dependencygraph.model
2+
3+
/**
4+
* Represents the scope of a resolved dependency.
5+
* At this point, the scopes are limited to those exposed in the GitHub DependencySubmission API.
6+
* Later development may extend this to a richer set of scopes.
7+
*/
8+
enum class DependencyScope {
9+
DEVELOPMENT, RUNTIME;
10+
11+
companion object {
12+
fun getEffectiveScope(scopes: List<DependencyScope>): DependencyScope {
13+
if (scopes.contains(RUNTIME)) return RUNTIME
14+
return DEVELOPMENT
15+
}
16+
}
17+
}

plugin/src/main/kotlin/org/gradle/dependencygraph/model/ResolvedConfiguration.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package org.gradle.dependencygraph.model
33
data class ResolvedConfiguration(
44
val rootOrigin: DependencyOrigin,
55
val configurationName: String,
6+
val scope: DependencyScope,
67
val allDependencies: MutableList<ResolvedDependency> = mutableListOf()
78
) {
89
fun addDependency(component: ResolvedDependency) {

plugin/src/main/kotlin/org/gradle/dependencygraph/simple/SimpleDependencyGraphRenderer.kt

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package org.gradle.dependencygraph.simple
33
import org.gradle.dependencygraph.DependencyGraphRenderer
44
import org.gradle.dependencygraph.model.BuildLayout
55
import org.gradle.dependencygraph.model.ResolvedConfiguration
6+
import org.gradle.dependencygraph.model.DependencyScope
67
import org.gradle.dependencygraph.util.JacksonJsonSerializer
78
import org.gradle.dependencygraph.util.PluginParameters
89
import java.io.File
@@ -40,21 +41,24 @@ class SimpleDependencyGraphRenderer : DependencyGraphRenderer {
4041
resolvedConfigurations: List<ResolvedConfiguration>
4142
) {
4243
val outputFile = File(outputDirectory, "dependency-scopes.json")
43-
val dependencyList: MutableMap<String, MutableSet<SimpleDependencyOrigin>> = mutableMapOf()
44+
val dependencyList: MutableMap<String, MutableSet<SimpleDependencyResolution>> = mutableMapOf()
4445
for (config in resolvedConfigurations) {
4546
for (dependency in config.allDependencies) {
46-
val dependencyOrigins = dependencyList.getOrPut(dependency.id) { mutableSetOf() }
47-
dependencyOrigins.add(
48-
SimpleDependencyOrigin(
47+
if (dependency.isProject) continue
48+
49+
val dependencyScopes = dependencyList.getOrPut(dependency.id) { mutableSetOf() }
50+
dependencyScopes.add(
51+
SimpleDependencyResolution(
4952
config.rootOrigin.path,
50-
config.configurationName
53+
config.configurationName,
54+
config.scope
5155
)
5256
)
5357
}
5458
}
5559

56-
val simpleDependencies = dependencyList.map { (id, origins) ->
57-
SimpleDependency(id, origins.toList())
60+
val simpleDependencies = dependencyList.map { (id, resolutions) ->
61+
SimpleDependency(id, DependencyScope.getEffectiveScope(resolutions.map {it.scope}), resolutions.toList())
5862
}
5963
val jsonContent = JacksonJsonSerializer.serializeToJson(simpleDependencies)
6064
outputFile.writeText(jsonContent)
@@ -67,7 +71,7 @@ class SimpleDependencyGraphRenderer : DependencyGraphRenderer {
6771
val outputFile = File(outputDirectory, "dependency-list.txt")
6872
val dependencyList = resolvedConfigurations.flatMap { config ->
6973
config.allDependencies.map {
70-
"${it.coordinates.group}:${it.coordinates.module}:${it.coordinates.version} ---- ${config.rootOrigin.id} ${config.rootOrigin.path} ${config.configurationName}"
74+
"${it.coordinates.group}:${it.coordinates.module}:${it.coordinates.version}"
7175
}
7276
}.distinct().sorted()
7377

@@ -78,7 +82,8 @@ class SimpleDependencyGraphRenderer : DependencyGraphRenderer {
7882

7983
data class SimpleDependency(
8084
val dependency: String,
81-
val resolvedBy: List<SimpleDependencyOrigin>
85+
val effectiveScope: DependencyScope,
86+
val resolvedBy: List<SimpleDependencyResolution>
8287
)
8388

84-
data class SimpleDependencyOrigin(val path: String, val configuration: String)
89+
data class SimpleDependencyResolution(val path: String, val configuration: String, val scope: DependencyScope)

plugin/src/main/kotlin/org/gradle/github/dependencygraph/GitHubRepositorySnapshotBuilder.kt

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package org.gradle.github.dependencygraph
33
import org.gradle.dependencygraph.model.ResolvedDependency
44
import org.gradle.dependencygraph.model.ResolvedConfiguration
55
import org.gradle.dependencygraph.model.BuildLayout
6+
import org.gradle.dependencygraph.model.DependencyScope
67
import org.gradle.github.dependencygraph.model.*
78

89
class GitHubRepositorySnapshotBuilder(
@@ -21,12 +22,12 @@ class GitHubRepositorySnapshotBuilder(
2122
fun buildManifest(manifestName: String, resolvedConfigurations: List<ResolvedConfiguration>, buildLayout: BuildLayout): GitHubManifest {
2223
val dependencyCollector = DependencyCollector()
2324

24-
for (resolutionRoot in resolvedConfigurations) {
25-
for (dependency in resolutionRoot.allDependencies) {
25+
for (configuration in resolvedConfigurations) {
26+
for (dependency in configuration.allDependencies) {
2627
// Ignore project dependencies (transitive deps of projects will be reported with project)
2728
if (dependency.isProject) continue
2829

29-
dependencyCollector.addResolved(dependency)
30+
dependencyCollector.addResolved(dependency, determineGitHubScope(configuration))
3031
}
3132
}
3233

@@ -37,6 +38,13 @@ class GitHubRepositorySnapshotBuilder(
3738
)
3839
}
3940

41+
private fun determineGitHubScope(configuration: ResolvedConfiguration): GitHubDependency.Scope {
42+
return when(configuration.scope) {
43+
DependencyScope.DEVELOPMENT -> GitHubDependency.Scope.development
44+
DependencyScope.RUNTIME -> GitHubDependency.Scope.runtime
45+
}
46+
}
47+
4048
/**
4149
* Manifest file is the root build settings file if it exists, or the root build file if not.
4250
*/
@@ -67,11 +75,12 @@ class GitHubRepositorySnapshotBuilder(
6775
/**
6876
* Merge each resolved component with the same ID into a single GitHubDependency.
6977
*/
70-
fun addResolved(component: ResolvedDependency) {
78+
fun addResolved(component: ResolvedDependency, scope: GitHubDependency.Scope) {
7179
val dep = dependencyBuilders.getOrPut(component.id) {
7280
GitHubDependencyBuilder(component.packageUrl())
7381
}
7482
dep.addRelationship(relationship(component))
83+
dep.addScope(scope)
7584
dep.addDependencies(component.dependencies)
7685
}
7786

@@ -89,6 +98,7 @@ class GitHubRepositorySnapshotBuilder(
8998

9099
private class GitHubDependencyBuilder(val package_url: String) {
91100
var relationship: GitHubDependency.Relationship = GitHubDependency.Relationship.indirect
101+
var scope: GitHubDependency.Scope = GitHubDependency.Scope.development
92102
val dependencies = mutableListOf<String>()
93103

94104
fun addRelationship(newRelationship: GitHubDependency.Relationship) {
@@ -98,6 +108,12 @@ class GitHubRepositorySnapshotBuilder(
98108
}
99109
}
100110

111+
fun addScope(newScope: GitHubDependency.Scope) {
112+
if (scope == GitHubDependency.Scope.development) {
113+
scope = newScope
114+
}
115+
}
116+
101117
fun addDependencies(newDependencies: List<String>) {
102118
// Add any dependencies that are not in the existing set
103119
for (newDependency in newDependencies.subtract(dependencies.toSet())) {
@@ -106,7 +122,7 @@ class GitHubRepositorySnapshotBuilder(
106122
}
107123

108124
fun build(): GitHubDependency {
109-
return GitHubDependency(package_url, relationship, dependencies)
125+
return GitHubDependency(package_url, relationship, scope, dependencies)
110126
}
111127
}
112128
}

plugin/src/main/kotlin/org/gradle/github/dependencygraph/model/GitHubDependency.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@ package org.gradle.github.dependencygraph.model
33
data class GitHubDependency(
44
val package_url: String,
55
val relationship: Relationship,
6+
val scope: Scope,
67
val dependencies: List<String>
78
) {
89
enum class Relationship {
910
indirect, direct
1011
}
12+
enum class Scope {
13+
runtime, development
14+
}
1115
}

plugin/src/test/groovy/org/gradle/github/dependencygraph/internal/ResolvedConfigurationTest.groovy

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,18 @@ class ResolvedConfigurationTest extends Specification {
9595
!filter.include(":proj-a:proj-b:", "")
9696
!filter.include("parent-proj:proj-a", "")
9797
}
98+
99+
def "filters on excluded project path"() {
100+
when:
101+
def filter = new ResolvedConfigurationFilter(/^:(?!buildSrc).*/, null)
102+
103+
then:
104+
filter.include(":proj-a", "")
105+
filter.include(":proj-a:proj-b", "")
106+
filter.include(":proj-a:buildSrc", "")
107+
108+
!filter.include(":buildSrc", "")
109+
!filter.include(":buildSrc:", "")
110+
!filter.include(":buildSrc:proj-b:", "")
111+
}
98112
}

0 commit comments

Comments
 (0)