Skip to content

Commit

Permalink
Don’t allow exclusions to affect extending configurations
Browse files Browse the repository at this point in the history
Previously, when the plugin identified that an artifact was to be
excluded from a configuration, the exclusion was applied to the
configuration. In Gradle, when one configuration extends another
configuration, the extending configuration inherits the exclusions from
the configuration that’s being extended. Even if the extending
configuration had a direct dependency on the artifact it was still
excluded as an exclusion added to a configuration applies to all, both
direct and transitive.

This commit updates the plugin to add exclusions to dependencies rather
than the whole configuration. This prevents the exclusions from being
inherited by extending configurations.

Fixes gh-21
  • Loading branch information
wilkinsona committed Dec 19, 2014
1 parent 820c56b commit 9ccb7fa
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 4 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version=0.4.0.BUILD-SNAPSHOT
version=0.3.1.BUILD-SNAPSHOT
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import io.spring.gradle.dependencymanagement.exclusions.DependencyGraph.Dependen
import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.ModuleDependency
import org.gradle.api.artifacts.ResolvableDependencies
import org.gradle.api.artifacts.ResolveException
import org.gradle.api.artifacts.result.ResolvedDependencyResult
Expand Down Expand Up @@ -83,10 +85,15 @@ class ExclusionConfiguringAction implements Action<ResolvableDependencies> {
}.findAll { it != null }

exclusions.each {
def (group, module) = it.split(':')
log.debug("Excluding $it from $configuration.name configuration")
configuration.exclude(group: group, module: module)
resolvableDependencies.dependencies
.matching { it instanceof ModuleDependency }
.all { ModuleDependency dependency ->
log.debug("Excluding {} from {}", it, "$dependency.group:$dependency.name")
def (group, module) = it.split(':')
((ModuleDependency)dependency).exclude(group: group, module: module)
}
}

}

def collectExclusions(root, dependencyManagementExclusions) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,18 @@

package io.spring.gradle.dependencymanagement.exclusions

import org.slf4j.Logger
import org.slf4j.LoggerFactory

/**
* A set of dependency exclusions
*
* @author Andy Wilkinson
*/
class Exclusions {

private final Logger log = LoggerFactory.getLogger(ExclusionConfiguringAction)

def excludersByExclusion = [:]

def exclusionsByExcluder = [:]
Expand All @@ -37,6 +42,8 @@ class Exclusions {
def exclusions = exclusionsByExcluder[excluder] ?: [] as Set
exclusions << exclusion
exclusionsByExcluder[excluder] = exclusions

log.debug("{} is excluded by {}", exclusion, excluder)
}

void addAll(Exclusions newExclusions) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -676,4 +676,65 @@ public class DependencyManagementPluginSpec extends Specification {
'spring-beans-4.1.2.RELEASE.jar',
'spring-core-4.1.2.RELEASE.jar'])
}

def 'Exclusions are not inherited and do no affect direct dependencies (see gh-21)'() {
given: 'A project with the plugin applied'
project.apply plugin: 'io.spring.dependency-management'
project.apply plugin: 'java'
project.repositories {
maven { url new File("src/test/resources/maven-repo").toURI().toURL().toString() }
}
when: 'It depends on a module that excludes commons-logging in compile and on ' +
'commons-logging in testCompile'
project.dependencies {
compile 'test:direct-exclude:1.0'
testCompile 'commons-logging:commons-logging:1.1.3'
}
then: "commons-logging has been excluded from compile but not testCompile"
def compileFiles = project.configurations.compile.resolve()
compileFiles.size() == 4
compileFiles.collect { it.name }.containsAll(['direct-exclude-1.0.jar',
'spring-tx-4.1.2.RELEASE.jar',
'spring-beans-4.1.2.RELEASE.jar',
'spring-core-4.1.2.RELEASE.jar'])
def testCompileFiles = project.configurations.testCompile.resolve()
testCompileFiles.size() == 5
testCompileFiles.collect { it.name }.containsAll(['direct-exclude-1.0.jar',
'spring-tx-4.1.2.RELEASE.jar',
'spring-beans-4.1.2.RELEASE.jar',
'spring-core-4.1.2.RELEASE.jar',
'commons-logging-1.1.3.jar'])
}
def 'Exclusions are not inherited and do no affect transitive dependencies (see gh-21)'() {
given: 'A project with a compile dependency that pulls in a JUnit exclude'
project.apply plugin: 'io.spring.dependency-management'
project.apply plugin: 'java'
project.dependencyManagement {
imports {
mavenBom 'org.springframework.boot:spring-boot-dependencies:1.2.0.RELEASE'
}
}
project.dependencies {
compile 'org.codehaus.groovy:groovy'
}
when: 'It has a transitive testCompile dependency on JUnit'
project.dependencies {
testCompile 'org.springframework.boot:spring-boot-starter-test'
}
then: "JUnit has not be excluded"
def testCompileFiles = project.configurations.testCompile.resolve()
testCompileFiles.size() == 9
testCompileFiles
.collect { it.name }
.containsAll(['groovy-2.3.8.jar',
'spring-boot-starter-test-1.2.0.RELEASE.jar',
'junit-4.12.jar',
'mockito-core-1.10.8.jar',
'hamcrest-core-1.3.jar',
'hamcrest-library-1.3.jar',
'spring-core-4.1.3.RELEASE.jar',
'spring-test-4.1.3.RELEASE.jar',
'objenesis-2.1.jar'])
}
}

0 comments on commit 9ccb7fa

Please sign in to comment.