Skip to content

Commit

Permalink
Merge pull request #231 from chali/PathAwareDiff
Browse files Browse the repository at this point in the history
Improve dependency cycle detection, it was too aggresive. Properly add all messages for the same cause
  • Loading branch information
chali authored Dec 8, 2021
2 parents fb4342f + 652a786 commit 091d5a7
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,20 +52,19 @@ class PathAwareDiffReportGenerator : DiffReportGenerator {
val pathQueue: Queue<DependencyPathElement> = LinkedList()
val root = DependencyPathElement(project.configurations.getByName(configurationName).incoming.resolutionResult.root, null, null)
pathQueue.add(root)
val visited = mutableSetOf<ResolvedComponentResult>()
val visited = mutableSetOf<ResolvedDependencyResult>()
while (!pathQueue.isEmpty()) {
val forExploration = pathQueue.poll()
visited.add(forExploration.selected)
forExploration.selected.dependencies.filterIsInstance<ResolvedDependencyResult>()
.sortedBy { it.selected.moduleVersion.toString() }
.forEach {
//attach new element to the tree
val newElement = DependencyPathElement(it.selected, it.requested, differencesByDependency[it.selected.moduleName()])
if (! visited.contains(it.selected) && ! terminateExploration(newElement)) {
if (! visited.contains(it) && ! terminateExploration(newElement)) {
forExploration.addChild(newElement)
pathQueue.add(newElement)
}

visited.add(it)
}
}
return AnnotatedDependencyTree(root)
Expand Down Expand Up @@ -218,7 +217,10 @@ class PathAwareDiffReportGenerator : DiffReportGenerator {
}

fun collectSelectionReasons(): Map<String, Any> {
return selected.selectionReason.descriptions.associate { it.cause.toString() to it.description }.toSortedMap()
return selected.selectionReason.descriptions.groupBy { it.cause.toString() }
.mapValues {
it.value.filter { it.description.isNotEmpty() }.joinToString("; ")
}.toSortedMap()
}

override fun equals(other: Any?): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,117 @@ class PathAwareDependencyDiffSpec extends IntegrationTestKitSpec {
consumer2.children[0].change.previousVersion == "1.0.0"
}

def 'diff lock with paths with alignment and constraint to have multiple descriptions of the same cause'() {
File rulesJsonFile = new File(projectDir, "${moduleName}.json")
rulesJsonFile << '''\
{
"deny": [], "reject": [], "substitute": [], "replace": [],
"align": [
{
"name": "testNebula",
"group": "test.example.alignment",
"reason": "Align test.example.alignment dependencies",
"author": "Example Person <[email protected]>",
"date": "2016-03-17T20:21:20.368Z"
}
]
}
'''.stripIndent()

new File("${projectDir}/gradle.properties").text = "systemProp.nebula.features.pathAwareDependencyDiff=true"
def dependenciesLock = new File(projectDir, 'dependencies.lock')
dependenciesLock << LockGenerator.duplicateIntoConfigsWhenUsingImplementationConfigurationOnly('''\
"test.example:consumer-of-aligned-dependency1": {
"locked": "1.0.0"
},
"test.example:consumer-of-aligned-dependency2": {
"locked": "1.0.0"
},
"test.example.alignment:consumer1-library": {
"locked": "1.0.0",
"transitive": [
"test.example:consumer-of-aligned-dependency1"
]
},
"test.example.alignment:consumer2-library": {
"locked": "1.0.0",
"transitive": [
"test.example:consumer-of-aligned-dependency2"
]
},
"test.example.alignment:core-library": {
"locked": "1.0.0",
"transitive": [
"test.example.alignment:consumer1-library"
]
},
"test.example.alignment:core2-library": {
"locked": "1.0.0",
"transitive": [
"test.example.alignment:consumer2-library"
]
}
'''.stripIndent())
buildFile << """\
plugins {
id 'nebula.dependency-lock'
id "nebula.resolution-rules" version "9.0.0"
}
apply plugin: 'java'
repositories {
maven { url '${repoDir.absolutePath}' }
}
dependencyLock {
includeTransitives = true
}
dependencies {
constraints {
implementation 'test.example.alignment:consumer1-library:2.0.0'
}
resolutionRules files('$rulesJsonFile')
implementation 'test.example:consumer-of-aligned-dependency1:2.0.0'
implementation 'test.example:consumer-of-aligned-dependency2:2.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.find { it.configurations.contains("compileClasspath")}
def directDependencies = allConfigurations["differentPaths"]
def alignedConsumer1 = directDependencies.find { it.dependency == "test.example:consumer-of-aligned-dependency1"}
alignedConsumer1.version == "2.0.0"
alignedConsumer1.change.description == "requested"
alignedConsumer1.change.type == "UPDATED"
alignedConsumer1.change.previousVersion == "1.0.0"
def consumer1 = alignedConsumer1.children.find { it.dependency == "test.example.alignment:consumer1-library"}
consumer1.requestedVersion == "1.0.0"
consumer1.version == "2.0.0"
consumer1.selectionReasons["CONSTRAINT"] == "belongs to platform aligned-platform:diff-lock-with-paths-with-alignment-and-constraint-to-have-multiple-descriptions-of-the-same-cause-0-for-test.example.alignment:2.0.0; constraint"
consumer1.change.type == "UPDATED"
consumer1.change.previousVersion == "1.0.0"
def alignedConsumer2 = directDependencies.find { it.dependency == "test.example:consumer-of-aligned-dependency2"}
alignedConsumer2.version == "2.0.0"
alignedConsumer2.change.description == "requested"
alignedConsumer2.change.type == "UPDATED"
alignedConsumer2.change.previousVersion == "1.0.0"
def consumer2 = alignedConsumer2.children.find { it.dependency == "test.example.alignment:consumer2-library"}
consumer2.version == "2.0.0"
consumer2.change.description == "requested; belongs to platform aligned-platform:diff-lock-with-paths-with-alignment-and-constraint-to-have-multiple-descriptions-of-the-same-cause-0-for-test.example.alignment:2.0.0"
consumer2.change.type == "UPDATED"
consumer2.change.previousVersion == "1.0.0"
consumer2.children[0].dependency == "test.example.alignment:core2-library"
consumer2.children[0].version == "2.0.0"
consumer2.children[0].change.description == "requested; belongs to platform aligned-platform:diff-lock-with-paths-with-alignment-and-constraint-to-have-multiple-descriptions-of-the-same-cause-0-for-test.example.alignment:2.0.0"
consumer2.children[0].change.type == "UPDATED"
consumer2.children[0].change.previousVersion == "1.0.0"
}

def 'diff lock with paths with constrained dependency'() {
new File("${projectDir}/gradle.properties").text = "systemProp.nebula.features.pathAwareDependencyDiff=true"
def dependenciesLock = new File(projectDir, 'dependencies.lock')
Expand Down

0 comments on commit 091d5a7

Please sign in to comment.