diff --git a/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/ModuleDependencyExcludeResolveIntegrationTest.groovy b/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/ModuleDependencyExcludeResolveIntegrationTest.groovy index 923899b5e3d4..825254668448 100644 --- a/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/ModuleDependencyExcludeResolveIntegrationTest.groovy +++ b/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/ModuleDependencyExcludeResolveIntegrationTest.groovy @@ -542,4 +542,73 @@ task check(type: Sync) { } } } + + + /** + * In the project, dependency `c` will be rewritten to dependency `b`. + * If we exclude dependency b, both the direct request dependency `b` + * and the dependency rewritten from `c` will be excluded + * with their transitive dependencies. + * + * Dependency graph: + * a -> b, c, f, g + * b -> d + * c -> e + * + * Exclude is applied to configuration conf + */ + def "ensure renamed dependencies are exclude correctly"() { + given: + buildFile << """ +configurations { + conf { + exclude group: 'b', module: 'b' + resolutionStrategy { + dependencySubstitution { + all { + if (it.requested instanceof ModuleComponentSelector) { + if (it.requested.group == 'c' && it.requested.module == 'c') { + it.useTarget group: 'b', name: 'b', version: '1.0' + } + } + } + } + } + } +} +""" + + def expectResolved = ['a', 'f', 'g'] + repository { + 'a:a:1.0' { + dependsOn 'b:b:1.0' + dependsOn 'c:c:1.0' + dependsOn 'f:f:1.0' + dependsOn 'g:g:1.0' + } + 'b:b:1.0' { + dependsOn 'd:d:1.0' + } + 'c:c:1.0' { + dependsOn 'e:e:1.0' + } + 'd:d:1.0'() + 'e:e:1.0'() + 'f:f:1.0'() + 'g:g:1.0'() + } + + repositoryInteractions { + expectResolved.each { + "${it}:${it}:1.0" { expectResolve() } + } + } + + when: + succeedsDependencyResolution() + + then: + def resolvedJars = expectResolved.collect { it + '-1.0.jar'} + assertResolvedFiles(resolvedJars) + } } diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/ivyservice/resolveengine/graph/builder/NodeState.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/ivyservice/resolveengine/graph/builder/NodeState.java index e27b3f3b4de9..a0bb4309568c 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/ivyservice/resolveengine/graph/builder/NodeState.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/ivyservice/resolveengine/graph/builder/NodeState.java @@ -432,7 +432,6 @@ private void visitDependencies(ExcludeSpec resolutionFilter, Collection cacheFilteredDependencyStates(ExcludeSpec spec, Li } List tmp = Lists.newArrayListWithCapacity(from.size()); for (DependencyState dependencyState : from) { + if (isExcluded(spec, dependencyState)) { + continue; + } + dependencyState = maybeSubstitute(dependencyState, resolveState.getDependencySubstitutionApplicator()); + if (!isExcluded(spec, dependencyState)) { tmp.add(dependencyState); }