From 68a70f1a6e23cebf15169c33df7ab57474ca57eb Mon Sep 17 00:00:00 2001 From: Martin Chalupa Date: Tue, 23 Nov 2021 13:22:37 -0800 Subject: [PATCH 1/2] Improve message for conflict resolution participats --- .../dependencylock/diff/PathAwareDiffReportGenerator.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/nebula/plugin/dependencylock/diff/PathAwareDiffReportGenerator.kt b/src/main/kotlin/nebula/plugin/dependencylock/diff/PathAwareDiffReportGenerator.kt index a08b9c5..3cae727 100644 --- a/src/main/kotlin/nebula/plugin/dependencylock/diff/PathAwareDiffReportGenerator.kt +++ b/src/main/kotlin/nebula/plugin/dependencylock/diff/PathAwareDiffReportGenerator.kt @@ -175,9 +175,9 @@ class PathAwareDiffReportGenerator : DiffReportGenerator { } if (causesWithDescription.contains(ComponentSelectionCause.CONFLICT_RESOLUTION)) { val message = if (isWinnerOfConflictResolution()) - "this path brought the winner of conflict resolution" + "the parent brought the winner of conflict resolution" else - "this path participates in conflict resolution, but the winner is from a different path" + "the parent brought this participant in conflict resolution, but the winner is from a different path" causesWithDescription[ComponentSelectionCause.CONFLICT_RESOLUTION] = message } From 5000058d0d87cb57e54aeec3cac60bdb6866a40b Mon Sep 17 00:00:00 2001 From: Martin Chalupa Date: Tue, 23 Nov 2021 13:23:25 -0800 Subject: [PATCH 2/2] Include status for dependencies. That will allow us mark snapshots in visualization --- .../diff/PathAwareDiffReportGenerator.kt | 32 ++++--- .../PathAwareDependencyDiffSpec.groovy | 88 ++++++++++++++++++- 2 files changed, 104 insertions(+), 16 deletions(-) diff --git a/src/main/kotlin/nebula/plugin/dependencylock/diff/PathAwareDiffReportGenerator.kt b/src/main/kotlin/nebula/plugin/dependencylock/diff/PathAwareDiffReportGenerator.kt index 3cae727..adc14cd 100644 --- a/src/main/kotlin/nebula/plugin/dependencylock/diff/PathAwareDiffReportGenerator.kt +++ b/src/main/kotlin/nebula/plugin/dependencylock/diff/PathAwareDiffReportGenerator.kt @@ -9,6 +9,8 @@ import org.gradle.api.artifacts.result.ResolvedDependencyResult import org.gradle.api.internal.artifacts.ivyservice.ivyresolve.strategy.DefaultVersionComparator import org.gradle.api.internal.artifacts.ivyservice.ivyresolve.strategy.DefaultVersionSelectorScheme import org.gradle.api.internal.artifacts.ivyservice.ivyresolve.strategy.VersionParser +import org.gradle.api.internal.project.ProjectInternal +import java.lang.RuntimeException import java.util.* class PathAwareDiffReportGenerator : DiffReportGenerator { @@ -119,18 +121,20 @@ class PathAwareDiffReportGenerator : DiffReportGenerator { private fun createDiffTree(parentElement: DependencyPathElement): List> { return parentElement.children.map { dependencyPathElement: DependencyPathElement -> - val result = mutableMapOf( - "dependency" to dependencyPathElement.selected.moduleName(), - if (! dependencyPathElement.alreadyVisited) { - "children" to createDiffTree(dependencyPathElement) - } else { - "repeated" to true - }, - if (dependencyPathElement.isSubmodule()) - "submodule" to true - else - "version" to dependencyPathElement.selected.moduleVersion() - ) + val result: MutableMap = mutableMapOf() + result["dependency"] = dependencyPathElement.selected.moduleName() + if (dependencyPathElement.isSubmodule()) + result["submodule"] = true + else { + result["status"] = dependencyPathElement.extractStatus() + result["version"] = dependencyPathElement.selected.moduleVersion() + } + + if (!dependencyPathElement.alreadyVisited) { + result["children"] = createDiffTree(dependencyPathElement) + } else { + result["repeated"] = true + } if (dependencyPathElement.isChangedInUpdate()) { val diff = dependencyPathElement.dependencyDiff!! val change = mutableMapOf( @@ -198,6 +202,10 @@ class PathAwareDiffReportGenerator : DiffReportGenerator { false } + fun extractStatus(): String { + return this.selected.variants.first().attributes.getAttribute(ProjectInternal.STATUS_ATTRIBUTE) ?: throw RuntimeException("Unknown status") + } + override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false diff --git a/src/test/groovy/nebula/plugin/dependencylock/PathAwareDependencyDiffSpec.groovy b/src/test/groovy/nebula/plugin/dependencylock/PathAwareDependencyDiffSpec.groovy index 0bfed6c..f9c84fa 100644 --- a/src/test/groovy/nebula/plugin/dependencylock/PathAwareDependencyDiffSpec.groovy +++ b/src/test/groovy/nebula/plugin/dependencylock/PathAwareDependencyDiffSpec.groovy @@ -4,7 +4,9 @@ import groovy.json.JsonSlurper import nebula.plugin.dependencylock.util.LockGenerator import nebula.test.IntegrationTestKitSpec import nebula.test.dependencies.DependencyGraph +import nebula.test.dependencies.DependencyGraphBuilder import nebula.test.dependencies.GradleDependencyGenerator +import nebula.test.dependencies.ModuleBuilder import nebula.test.dependencies.maven.Pom import nebula.test.dependencies.maven.ArtifactType import nebula.test.dependencies.repositories.MavenRepo @@ -183,7 +185,7 @@ class PathAwareDependencyDiffSpec extends IntegrationTestKitSpec { def directDependencies = allConfigurations["differentPaths"] def directTransitive = directDependencies.find { it.dependency == "test.example:direct-dependency-updating-transitive"} directTransitive.version == "2.2.0" - directTransitive.change.description == "requested; this path brought the winner of conflict resolution" + directTransitive.change.description == "requested; the parent brought the winner of conflict resolution" directTransitive.change.type == "UPDATED" directTransitive.change.previousVersion == "2.0.0" def ruleUpdateConsumer = directDependencies.find { it.dependency == "test.example:updated-by-rule-dependency-consumer"} @@ -201,12 +203,12 @@ class PathAwareDependencyDiffSpec extends IntegrationTestKitSpec { qux.change.previousVersion == "1.0.0" def foo = qux.children.find { it.dependency == "test.example:foo" } foo.version == "2.0.1" - foo.change.description == "requested; this path brought the winner of conflict resolution" + foo.change.description == "requested; the parent brought the winner of conflict resolution" foo.change.type == "UPDATED" foo.change.previousVersion == "1.0.1" foo.children[0].dependency == "test.example:direct-dependency-updated-transitively" foo.children[0].version == "1.1.0" - foo.children[0].change.description == "requested; this path brought the winner of conflict resolution" + foo.children[0].change.description == "requested; the parent brought the winner of conflict resolution" foo.children[0].change.type == "UPDATED" foo.children[0].change.previousVersion == "1.0.0" def newDependency = qux.children.find { it.dependency == "test.example:new-dependency" } @@ -475,7 +477,7 @@ class PathAwareDependencyDiffSpec extends IntegrationTestKitSpec { alignedConsumer1.change.previousVersion == "1.0.0" def consumer1 = alignedConsumer1.children.find { it.dependency == "test.example.alignment:consumer1-library"} consumer1.version == "2.0.0" - consumer1.change.description == "requested; this path participates in conflict resolution, but the winner is from a different path; belongs to platform aligned-platform:diff-lock-with-paths-with-alignment-without-clear-conflict-resolution-winner-0-for-test.example.alignment:2.0.0" + consumer1.change.description == "requested; the parent brought this participant in conflict resolution, but the winner is from a different path; belongs to platform aligned-platform:diff-lock-with-paths-with-alignment-without-clear-conflict-resolution-winner-0-for-test.example.alignment:2.0.0" consumer1.change.type == "UPDATED" consumer1.change.previousVersion == "1.0.0" consumer1.children[0].dependency == "test.example.alignment:core-library" @@ -947,4 +949,82 @@ class PathAwareDependencyDiffSpec extends IntegrationTestKitSpec { def allConfigurations = lockdiff[0] ! allConfigurations["differentPaths"].isEmpty() } + + def 'diff lock with snapshot dependencies'() { + def myGraph= new DependencyGraphBuilder() + .addModule("test.example:dependency-of-snapshot:2.0.0") + .addModule(new ModuleBuilder("test.example:snapshot-dependency:1.0.0") + .setStatus("integration") + .addDependency("test.example:dependency-of-snapshot:2.0.0") + .build()) + .addModule(new ModuleBuilder("test.example:dependency-of-snapshot:2.0.0").setStatus("release").build()) + .addModule(new ModuleBuilder("test.example:direct-dependency:1.0.0") + .setStatus("release") + .addDependency("test.example:snapshot-dependency:1.0.0") + .build()) + .build() + + def generator = new GradleDependencyGenerator(myGraph) + generator.generateTestIvyRepo() + + new File("${projectDir}/gradle.properties").text = "systemProp.nebula.features.pathAwareDependencyDiff=true" + def dependenciesLock = new File(projectDir, 'dependencies.lock') + dependenciesLock << LockGenerator.duplicateIntoConfigsWhenUsingImplementationConfigurationOnly('''\ + "test.example:dependency-of-snapshot": { + "locked": "1.0.0" + }, + "test.example:snapshot-dependency": { + "locked": "1.0.0", + "transitive": [ + "test.example:dependency-of-snapshot" + ] + }, + "test.example:direct-dependency": { + "locked": "1.0.0", + "transitive": [ + "test.example:snapshot-dependency" + ] + } + '''.stripIndent()) + buildFile << """\ + plugins { + id 'nebula.dependency-lock' + } + + apply plugin: 'java' + repositories { + ${generator.getIvyRepositoryBlock()} + } + + dependencyLock { + includeTransitives = true + } + + dependencies { + implementation 'test.example:direct-dependency:1.0.0' + } + """.stripIndent() + + when: + def result = runTasks('generateLock', 'diffLock') + + then: + def lockdiff = new JsonSlurper().parse(new File(projectDir, 'build/dependency-lock/lockdiff.json')) + def allConfigurations = lockdiff[0] + def directDependencies = allConfigurations["differentPaths"] + def direct = directDependencies[0] + direct.dependency == "test.example:direct-dependency" + direct.status == "release" + direct.version == "1.0.0" + direct.children[0].dependency == "test.example:snapshot-dependency" + direct.children[0].status == "integration" + direct.children[0].version == "1.0.0" + def updatedChild = direct.children[0].children[0] + updatedChild.dependency == "test.example:dependency-of-snapshot" + updatedChild.status == "release" + updatedChild.version == "2.0.0" + updatedChild.change.description == "requested" + updatedChild.change.type == "UPDATED" + updatedChild.change.previousVersion == "1.0.0" + } }