From 9ccb7fa750e839627b34e6a71294200850111265 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 19 Dec 2014 15:21:16 +0000 Subject: [PATCH] =?UTF-8?q?Don=E2=80=99t=20allow=20exclusions=20to=20affec?= =?UTF-8?q?t=20extending=20configurations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- gradle.properties | 2 +- .../ExclusionConfiguringAction.groovy | 13 +++- .../exclusions/Exclusions.groovy | 7 +++ .../DependencyManagementPluginSpec.groovy | 61 +++++++++++++++++++ 4 files changed, 79 insertions(+), 4 deletions(-) diff --git a/gradle.properties b/gradle.properties index df445c2..8dee759 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -version=0.4.0.BUILD-SNAPSHOT \ No newline at end of file +version=0.3.1.BUILD-SNAPSHOT \ No newline at end of file diff --git a/src/main/groovy/io/spring/gradle/dependencymanagement/exclusions/ExclusionConfiguringAction.groovy b/src/main/groovy/io/spring/gradle/dependencymanagement/exclusions/ExclusionConfiguringAction.groovy index a52fa8d..ee9f605 100644 --- a/src/main/groovy/io/spring/gradle/dependencymanagement/exclusions/ExclusionConfiguringAction.groovy +++ b/src/main/groovy/io/spring/gradle/dependencymanagement/exclusions/ExclusionConfiguringAction.groovy @@ -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 @@ -83,10 +85,15 @@ class ExclusionConfiguringAction implements Action { }.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) { diff --git a/src/main/groovy/io/spring/gradle/dependencymanagement/exclusions/Exclusions.groovy b/src/main/groovy/io/spring/gradle/dependencymanagement/exclusions/Exclusions.groovy index 347cc8d..a1b2bd8 100644 --- a/src/main/groovy/io/spring/gradle/dependencymanagement/exclusions/Exclusions.groovy +++ b/src/main/groovy/io/spring/gradle/dependencymanagement/exclusions/Exclusions.groovy @@ -16,6 +16,9 @@ package io.spring.gradle.dependencymanagement.exclusions +import org.slf4j.Logger +import org.slf4j.LoggerFactory + /** * A set of dependency exclusions * @@ -23,6 +26,8 @@ package io.spring.gradle.dependencymanagement.exclusions */ class Exclusions { + private final Logger log = LoggerFactory.getLogger(ExclusionConfiguringAction) + def excludersByExclusion = [:] def exclusionsByExcluder = [:] @@ -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) { diff --git a/src/test/groovy/io/spring/gradle/dependencymanagement/DependencyManagementPluginSpec.groovy b/src/test/groovy/io/spring/gradle/dependencymanagement/DependencyManagementPluginSpec.groovy index 43a2953..eb409b6 100644 --- a/src/test/groovy/io/spring/gradle/dependencymanagement/DependencyManagementPluginSpec.groovy +++ b/src/test/groovy/io/spring/gradle/dependencymanagement/DependencyManagementPluginSpec.groovy @@ -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']) + } }