Skip to content

Commit

Permalink
Apply dependency management resolution strategy to all detached configs
Browse files Browse the repository at this point in the history
Support for a dependency management-specific resolution strategy was
added in 8f59648. This resolution strategy is applied to any
configuration that’s created by the plugin for resolving imported boms.
It is not, however, applied to various other configurations that are
used by the plugin. The configurations that are used when apply Maven
exclusions are one example.

The fact that the resolution strategy isn’t applied to all
detached configurations that are created by the plugin has proven to
be problematic. If a user configures the main configurations to
disable caching this will have no effect. The problem is that the
logic for applying Maven exclusions creates a detached configuration
and copies a main configuration’s dependencies into it. When this
detached configuration is resolved, it’s done so with the default
caching rules. When the main configuration that contains the same
dependency is resolved, the custom caching configuration is ignored.
Presumably, this happens because the dependency has already been
resolved once in this build and Gradle doesn’t want different parts of
the build to use different snapshots.

This commit updates the plugin to introduce a new central location,
DependencyManagementConfigurationContainer, for creating detached
configurations. The dependency management resolution strategy is
apply to every configuration that’s created by this configuration
container, thereby ensuring that things like the caching configuration
are applied consistently.

Closes gh-74
  • Loading branch information
wilkinsona committed Feb 11, 2016
1 parent c496031 commit 096e87f
Show file tree
Hide file tree
Showing 11 changed files with 166 additions and 62 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -41,6 +41,8 @@ class DependencyManagement {

private final Configuration targetConfiguration

private final EffectiveModelBuilder effectiveModelBuilder

private boolean resolved

private Map<String, String> versions = [:]
Expand All @@ -57,15 +59,17 @@ class DependencyManagement {

private List<Dependency> importedBoms = [];

def DependencyManagement(Project project, Configuration dependencyManagementConfiguration) {
this(project, null, dependencyManagementConfiguration)
def DependencyManagement(Project project, Configuration dependencyManagementConfiguration,
EffectiveModelBuilder effectiveModelBuilder) {
this(project, null, dependencyManagementConfiguration, effectiveModelBuilder)
}

def DependencyManagement(Project project, Configuration targetConfiguration, Configuration
dependencyManagementConfiguration) {
dependencyManagementConfiguration, EffectiveModelBuilder effectiveModelBuilder) {
this.project = project
this.configuration = dependencyManagementConfiguration
this.targetConfiguration = targetConfiguration
this.effectiveModelBuilder = effectiveModelBuilder
}

void importBom(bomCoordinates) {
Expand Down Expand Up @@ -145,8 +149,6 @@ class DependencyManagement {

log.debug("Preserving existing versions: {}", existingVersions)

def effectiveModelBuilder = new EffectiveModelBuilder(project)

importedBoms.each { configuration.dependencies.add(it) }

Map<String, File> artifacts = configuration.resolvedConfiguration.resolvedArtifacts.collectEntries {
Expand All @@ -155,7 +157,7 @@ class DependencyManagement {
importedBoms.each {
File file = artifacts["${it.group}:${it.name}" as String]
log.debug("Processing '{}'", file)
Model effectiveModel = effectiveModelBuilder.buildModel(file)
Model effectiveModel = this.effectiveModelBuilder.buildModel(file)
if (effectiveModel.dependencyManagement?.dependencies) {
String bomCoordinates = "${effectiveModel.groupId}:${effectiveModel.artifactId}:${effectiveModel.version}"
effectiveModel.dependencyManagement.dependencies.each { dependency ->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.spring.gradle.dependencymanagement

import org.gradle.api.DomainObjectCollection
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.ConfigurationContainer
import org.gradle.api.artifacts.Dependency

/**
* A container for {@link Configuration Configurations} created by the dependency management plugin
* that aren't part of the project's configurations.
*
* @author Andy Wilkinson
*/
class DependencyManagementConfigurationContainer {

private final DomainObjectCollection<Configuration> configurations

private final ConfigurationContainer delegate

DependencyManagementConfigurationContainer(Project project) {
this.delegate = project.configurations
this.configurations = project.container(Configuration)
}

Configuration newConfiguration(Dependency... dependencies) {
Configuration configuration = delegate.detachedConfiguration(dependencies)
configurations.add(configuration)
return configuration
}

void resolutionStrategy(Closure closure) {
this.configurations.all { Configuration configuration ->
configuration.resolutionStrategy closure
}
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,9 +17,11 @@
package io.spring.gradle.dependencymanagement

import io.spring.gradle.dependencymanagement.exclusions.Exclusions
import io.spring.gradle.dependencymanagement.maven.EffectiveModelBuilder
import org.gradle.api.DomainObjectCollection
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.Dependency
import org.slf4j.Logger
import org.slf4j.LoggerFactory

Expand All @@ -32,20 +34,24 @@ class DependencyManagementContainer {

private final Logger log = LoggerFactory.getLogger(DependencyManagementContainer)

private final DomainObjectCollection<Configuration> dependencyManagementConfigurations
private final DependencyManagementConfigurationContainer configurationContainer

protected final DependencyManagement globalDependencyManagement

private final EffectiveModelBuilder effectiveModelBuilder

final Project project

private final Map<Configuration, DependencyManagement> configurationDependencyManagement = [:]

DependencyManagementContainer(Project project) {
DependencyManagementContainer(Project project,
DependencyManagementConfigurationContainer configurationContainer,
EffectiveModelBuilder effectiveModelBuilder) {
this.project = project
this.dependencyManagementConfigurations = this.project.container(Configuration)
Configuration dependencyManagementConfiguration = this.project.configurations.detachedConfiguration()
this.dependencyManagementConfigurations.add(dependencyManagementConfiguration)
this.globalDependencyManagement = new DependencyManagement(this.project, dependencyManagementConfiguration)
this.configurationContainer = configurationContainer
this.globalDependencyManagement = new DependencyManagement(this.project,
configurationContainer.newConfiguration(), effectiveModelBuilder)
this.effectiveModelBuilder = effectiveModelBuilder
}

void addImplicitManagedVersion(configuration, String group, String name, String version) {
Expand All @@ -63,12 +69,6 @@ class DependencyManagementContainer {
dependencyManagementForConfiguration(configuration).importBom(coordinates)
}

void resolutionStrategy(Closure closure) {
this.dependencyManagementConfigurations.all { Configuration configuration ->
configuration.resolutionStrategy closure
}
}

String getManagedVersion(Configuration configuration, String group, String name) {
String version = null
if (configuration) {
Expand Down Expand Up @@ -142,9 +142,9 @@ class DependencyManagementContainer {
else {
DependencyManagement dependencyManagement = configurationDependencyManagement.get(configuration)
if (!dependencyManagement) {
Configuration dependencyManagementConfiguration = this.project.configurations.detachedConfiguration()
this.dependencyManagementConfigurations.add(dependencyManagementConfiguration)
dependencyManagement = new DependencyManagement(project, configuration, dependencyManagementConfiguration)
Configuration dependencyManagementConfiguration = this.configurationContainer.newConfiguration()
dependencyManagement = new DependencyManagement(project, configuration,
dependencyManagementConfiguration, effectiveModelBuilder)
configurationDependencyManagement.put(configuration, dependencyManagement)
}
dependencyManagement
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -27,9 +27,11 @@ import org.gradle.api.artifacts.Configuration
*/
class DependencyManagementExtension {

protected DependencyManagementContainer dependencyManagementContainer
protected final DependencyManagementContainer dependencyManagementContainer

protected Project project
private final Project project

private final DependencyManagementConfigurationContainer configurationContainer

boolean applyMavenExclusions = true

Expand All @@ -38,8 +40,9 @@ class DependencyManagementExtension {
PomCustomizationConfiguration generatedPomCustomization = new PomCustomizationConfiguration()

DependencyManagementExtension(DependencyManagementContainer dependencyManagementContainer,
Project project) {
DependencyManagementConfigurationContainer configurationContainer, Project project) {
this.dependencyManagementContainer = dependencyManagementContainer
this.configurationContainer = configurationContainer
this.project = project
}

Expand All @@ -53,7 +56,7 @@ class DependencyManagementExtension {
}

void resolutionStrategy(Closure closure) {
this.dependencyManagementContainer.resolutionStrategy closure
configurationContainer.resolutionStrategy closure
}

void generatedPomCustomization(Closure closure) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -48,11 +48,18 @@ class DependencyManagementPlugin implements Plugin<Project> {

@Override
void apply(Project project) {
DependencyManagementConfigurationContainer configurationContainer = new
DependencyManagementConfigurationContainer(project)

EffectiveModelBuilder effectiveModelBuilder = new EffectiveModelBuilder(project,
configurationContainer)

DependencyManagementContainer dependencyManagementContainer =
new DependencyManagementContainer(project)
new DependencyManagementContainer(project, configurationContainer, effectiveModelBuilder)

DependencyManagementExtension extension = project.extensions.create("dependencyManagement",
DependencyManagementExtension, dependencyManagementContainer, project)
DependencyManagementExtension, dependencyManagementContainer,
configurationContainer, project)

project.tasks.create("dependencyManagement", DependencyManagementReportTask) { task ->
task.dependencyManagement = dependencyManagementContainer
Expand All @@ -78,7 +85,7 @@ class DependencyManagementPlugin implements Plugin<Project> {
}

ExclusionResolver exclusionResolver = new ExclusionResolver(project.dependencies,
project.configurations, new EffectiveModelBuilder(project))
configurationContainer, effectiveModelBuilder)

project.configurations.all { Configuration c ->
log.info("Applying dependency management to configuration '{}' in project '{}'",
Expand All @@ -89,7 +96,7 @@ class DependencyManagementPlugin implements Plugin<Project> {

c.incoming.beforeResolve(new ExclusionConfiguringAction(
project.extensions.findByType(DependencyManagementExtension),
dependencyManagementContainer, project.configurations, c, exclusionResolver,
dependencyManagementContainer, configurationContainer, c, exclusionResolver,
versionConfiguringAction))

resolutionStrategy.eachDependency(versionConfiguringAction)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,6 +16,7 @@

package io.spring.gradle.dependencymanagement.exclusions

import io.spring.gradle.dependencymanagement.DependencyManagementConfigurationContainer
import io.spring.gradle.dependencymanagement.DependencyManagementContainer
import io.spring.gradle.dependencymanagement.DependencyManagementExtension
import io.spring.gradle.dependencymanagement.VersionConfiguringAction
Expand Down Expand Up @@ -45,7 +46,7 @@ class ExclusionConfiguringAction implements Action<ResolvableDependencies> {

private final DependencyManagementContainer dependencyManagementContainer

private final ConfigurationContainer configurationContainer
private final DependencyManagementConfigurationContainer configurationContainer

private final Configuration configuration

Expand All @@ -55,7 +56,7 @@ class ExclusionConfiguringAction implements Action<ResolvableDependencies> {

ExclusionConfiguringAction(DependencyManagementExtension dependencyManagementExtension,
DependencyManagementContainer dependencyManagementContainer,
ConfigurationContainer configurationContainer, Configuration configuration,
DependencyManagementConfigurationContainer configurationContainer, Configuration configuration,
ExclusionResolver exclusionResolver, VersionConfiguringAction versionConfiguringAction) {
this.dependencyManagementExtension = dependencyManagementExtension
this.dependencyManagementContainer = dependencyManagementContainer
Expand Down Expand Up @@ -90,8 +91,8 @@ class ExclusionConfiguringAction implements Action<ResolvableDependencies> {
}

private Set findExcludedDependencies() {
def configurationCopy = this.configurationContainer.detachedConfiguration(this
.configuration.allDependencies as Dependency[])
def configurationCopy = this.configurationContainer
.newConfiguration(configuration.allDependencies as Dependency[])
configurationCopy.resolutionStrategy.eachDependency(this.versionConfiguringAction)
ResolutionResult resolutionResult = configurationCopy.incoming.resolutionResult
def root = resolutionResult.root
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,9 +16,9 @@

package io.spring.gradle.dependencymanagement.exclusions

import io.spring.gradle.dependencymanagement.DependencyManagementConfigurationContainer
import io.spring.gradle.dependencymanagement.maven.EffectiveModelBuilder
import io.spring.gradle.dependencymanagement.maven.ModelExclusionCollector
import org.gradle.api.artifacts.ConfigurationContainer
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.ResolvedArtifact
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
Expand All @@ -35,14 +35,14 @@ class ExclusionResolver {

private final DependencyHandler dependencyHandler

private final ConfigurationContainer configurationContainer
private final DependencyManagementConfigurationContainer configurationContainer

private final EffectiveModelBuilder effectiveModelBuilder

private final Map<String, Exclusions> exclusionsCache = [:]

ExclusionResolver(DependencyHandler dependencyHandler,
ConfigurationContainer configurationContainer,
DependencyManagementConfigurationContainer configurationContainer,
EffectiveModelBuilder effectiveModelBuilder) {
this.dependencyHandler = dependencyHandler
this.configurationContainer = configurationContainer
Expand All @@ -68,7 +68,7 @@ class ExclusionResolver {
}
}

def configuration = this.configurationContainer.detachedConfiguration(dependencies
def configuration = this.configurationContainer.newConfiguration(dependencies
.toArray(new Dependency[dependencies.size()]))

configuration.resolvedConfiguration.lenientConfiguration
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
/*
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.spring.gradle.dependencymanagement.maven

import io.spring.gradle.dependencymanagement.DependencyManagementConfigurationContainer
import io.spring.gradle.dependencymanagement.org.apache.maven.model.Model
import io.spring.gradle.dependencymanagement.org.apache.maven.model.building.DefaultModelBuilder
import io.spring.gradle.dependencymanagement.org.apache.maven.model.building.DefaultModelBuilderFactory
Expand All @@ -26,12 +43,13 @@ class EffectiveModelBuilder {

private final ModelResolver modelResolver

EffectiveModelBuilder(Project project) {
EffectiveModelBuilder(Project project,
DependencyManagementConfigurationContainer configurationContainer) {
mavenModelBuilder = new DefaultModelBuilderFactory().newInstance()
mavenModelBuilder.modelInterpolator = new ProjectPropertiesModelInterpolator(
project)
mavenModelBuilder.modelValidator = new RelaxedModelValidator();
modelResolver = new PomDependencyModelResolver(project)
modelResolver = new PomDependencyModelResolver(project, configurationContainer)
}

Model buildModel(File pom) {
Expand Down
Loading

0 comments on commit 096e87f

Please sign in to comment.