Commit cef7ad77 authored by Phillip Webb's avatar Phillip Webb

Support automatic exclude rules with Gradle

Update the Spring Boot Gradle plugin to automatically apply exclude
rules to dependencies.

See gh-1047
parent addc1f77
...@@ -22,10 +22,13 @@ import org.gradle.api.plugins.ApplicationPlugin ...@@ -22,10 +22,13 @@ import org.gradle.api.plugins.ApplicationPlugin
import org.gradle.api.plugins.BasePlugin import org.gradle.api.plugins.BasePlugin
import org.gradle.api.plugins.JavaPlugin import org.gradle.api.plugins.JavaPlugin
import org.springframework.boot.gradle.agent.AgentPluginFeatures import org.springframework.boot.gradle.agent.AgentPluginFeatures
import org.springframework.boot.gradle.exclude.ExcludePluginFeatures
import org.springframework.boot.gradle.repackage.RepackagePluginFeatures import org.springframework.boot.gradle.repackage.RepackagePluginFeatures
import org.springframework.boot.gradle.resolve.ResolvePluginFeatures import org.springframework.boot.gradle.resolve.ResolvePluginFeatures
import org.springframework.boot.gradle.resolve.SpringBootResolutionStrategy
import org.springframework.boot.gradle.run.RunPluginFeatures import org.springframework.boot.gradle.run.RunPluginFeatures
/** /**
* Gradle 'Spring Boot' {@link Plugin}. * Gradle 'Spring Boot' {@link Plugin}.
* *
...@@ -41,11 +44,13 @@ class SpringBootPlugin implements Plugin<Project> { ...@@ -41,11 +44,13 @@ class SpringBootPlugin implements Plugin<Project> {
project.getPlugins().apply(ApplicationPlugin) project.getPlugins().apply(ApplicationPlugin)
project.getExtensions().create("springBoot", SpringBootPluginExtension) project.getExtensions().create("springBoot", SpringBootPluginExtension)
project.getConfigurations().create(VersionManagedDependencies.CONFIGURATION);
new AgentPluginFeatures().apply(project) new AgentPluginFeatures().apply(project)
new ResolvePluginFeatures().apply(project) new ResolvePluginFeatures().apply(project)
new RepackagePluginFeatures().apply(project) new RepackagePluginFeatures().apply(project)
new RunPluginFeatures().apply(project) new RunPluginFeatures().apply(project)
new ExcludePluginFeatures().apply(project)
useUtf8Encoding(project) useUtf8Encoding(project)
} }
......
...@@ -108,4 +108,9 @@ public class SpringBootPluginExtension { ...@@ -108,4 +108,9 @@ public class SpringBootPluginExtension {
* Flag to indicate that the agent requires -noverify (and the plugin will refuse to start if it is not set) * Flag to indicate that the agent requires -noverify (and the plugin will refuse to start if it is not set)
*/ */
Boolean noverify; Boolean noverify;
/**
* If exclude rules should be applied to dependencies based on the spring-dependencies-bom
*/
boolean applyExcludeRules = true;
} }
/*
* Copyright 2012-2014 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 org.springframework.boot.gradle;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.springframework.boot.dependency.tools.Dependencies;
import org.springframework.boot.dependency.tools.ManagedDependencies;
import org.springframework.boot.dependency.tools.PropertiesFileDependencies;
/**
* Utility to provide access to {@link ManagedDependencies} with support for version
* file overrides.
*
* @author Phillip Webb
*/
public class VersionManagedDependencies {
public static final String CONFIGURATION = "versionManagement";
private Configuration versionManagementConfiguration;
private Collection<Dependencies> versionManagedDependencies;
private ManagedDependencies managedDependencies;
public VersionManagedDependencies(Project project) {
this.versionManagementConfiguration = project.getConfigurations().getByName(
CONFIGURATION);
}
public ManagedDependencies getManagedDependencies() {
if (this.managedDependencies == null) {
this.managedDependencies = ManagedDependencies
.get(getVersionManagedDependencies());
}
return this.managedDependencies;
}
private Collection<Dependencies> getVersionManagedDependencies() {
if (versionManagedDependencies == null) {
Set<File> files = versionManagementConfiguration.resolve();
List<Dependencies> dependencies = new ArrayList<Dependencies>(files.size());
for (File file : files) {
dependencies.add(getPropertiesFileManagedDependencies(file));
}
this.versionManagedDependencies = dependencies;
}
return versionManagedDependencies;
}
private Dependencies getPropertiesFileManagedDependencies(File file) {
if (!file.getName().toLowerCase().endsWith(".properties")) {
throw new IllegalStateException(file + " is not a version property file");
}
try {
return new PropertiesFileDependencies(new FileInputStream(file));
}
catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
}
/*
* Copyright 2012-2014 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 org.springframework.boot.gradle.exclude;
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.internal.artifacts.DefaultExcludeRule;
import org.gradle.api.logging.Logger;
import org.springframework.boot.dependency.tools.Dependency.Exclusion;
import org.springframework.boot.dependency.tools.ManagedDependencies;
import org.springframework.boot.gradle.VersionManagedDependencies;
/**
* {@link Action} to apply exclude rules.
*
* @author Phillip Webb
*/
public class ApplyExcludeRules implements Action<Configuration> {
private final Logger logger;
private final VersionManagedDependencies versionManagedDependencies;
public ApplyExcludeRules(Project project) {
this.logger = project.getLogger();
this.versionManagedDependencies = new VersionManagedDependencies(project);
}
@Override
public void execute(Configuration configuration) {
configuration.getDependencies().all(new Action<Dependency>() {
@Override
public void execute(Dependency dependency) {
applyExcludeRules(dependency);
}
});
}
private void applyExcludeRules(Dependency dependency) {
if (dependency instanceof ModuleDependency) {
applyExcludeRules((ModuleDependency) dependency);
}
}
private void applyExcludeRules(ModuleDependency dependency) {
ManagedDependencies managedDependencies = versionManagedDependencies
.getManagedDependencies();
org.springframework.boot.dependency.tools.Dependency managedDependency = managedDependencies
.find(dependency.getGroup(), dependency.getName());
if (managedDependency != null) {
if (managedDependency.getExclusions().isEmpty()) {
logger.debug("No exclusions rules applied for managed dependency "
+ dependency);
}
for (Exclusion exclusion : managedDependency.getExclusions()) {
addExcludeRule(dependency, exclusion);
}
}
else {
logger.debug("No exclusions rules applied for non-managed dependency "
+ dependency);
}
}
private void addExcludeRule(ModuleDependency dependency, Exclusion exclusion) {
logger.info("Adding managed exclusion rule " + exclusion + " to " + dependency);
DefaultExcludeRule rule = new DefaultExcludeRule(exclusion.getGroupId(),
exclusion.getArtifactId());
dependency.getExcludeRules().add(rule);
}
}
/*
* Copyright 2012-2014 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 org.springframework.boot.gradle.exclude;
import org.gradle.api.Project;
import org.springframework.boot.gradle.PluginFeatures;
import org.springframework.boot.gradle.SpringBootPluginExtension;
/**
* {@link PluginFeatures} to apply exclusion rules.
*
* @author Phillip Webb
*/
public class ExcludePluginFeatures implements PluginFeatures {
@Override
public void apply(Project project) {
SpringBootPluginExtension extension = project.getExtensions().getByType(
SpringBootPluginExtension.class);
if (extension.isApplyExcludeRules()) {
project.getConfigurations().all(new ApplyExcludeRules(project));
}
}
}
...@@ -30,8 +30,6 @@ public class ResolvePluginFeatures implements PluginFeatures { ...@@ -30,8 +30,6 @@ public class ResolvePluginFeatures implements PluginFeatures {
@Override @Override
public void apply(final Project project) { public void apply(final Project project) {
project.getConfigurations().create(
SpringBootResolutionStrategy.VERSION_MANAGEMENT_CONFIGURATION);
project.getConfigurations().all(new Action<Configuration>() { project.getConfigurations().all(new Action<Configuration>() {
@Override @Override
public void execute(Configuration configuration) { public void execute(Configuration configuration) {
......
...@@ -16,23 +16,14 @@ ...@@ -16,23 +16,14 @@
package org.springframework.boot.gradle.resolve; package org.springframework.boot.gradle.resolve;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import org.gradle.api.Action; import org.gradle.api.Action;
import org.gradle.api.Project; import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.DependencyResolveDetails; import org.gradle.api.artifacts.DependencyResolveDetails;
import org.gradle.api.artifacts.ModuleVersionSelector; import org.gradle.api.artifacts.ModuleVersionSelector;
import org.springframework.boot.dependency.tools.Dependencies;
import org.springframework.boot.dependency.tools.Dependency; import org.springframework.boot.dependency.tools.Dependency;
import org.springframework.boot.dependency.tools.ManagedDependencies; import org.springframework.boot.dependency.tools.ManagedDependencies;
import org.springframework.boot.dependency.tools.PropertiesFileDependencies; import org.springframework.boot.gradle.VersionManagedDependencies;
/** /**
* A resolution strategy to resolve missing version numbers using the * A resolution strategy to resolve missing version numbers using the
...@@ -42,12 +33,11 @@ import org.springframework.boot.dependency.tools.PropertiesFileDependencies; ...@@ -42,12 +33,11 @@ import org.springframework.boot.dependency.tools.PropertiesFileDependencies;
*/ */
public class SpringBootResolutionStrategy { public class SpringBootResolutionStrategy {
public static final String VERSION_MANAGEMENT_CONFIGURATION = "versionManagement";
private static final String SPRING_BOOT_GROUP = "org.springframework.boot"; private static final String SPRING_BOOT_GROUP = "org.springframework.boot";
public static void applyToConfiguration(final Project project, Configuration configuration) { public static void applyToConfiguration(final Project project,
if (VERSION_MANAGEMENT_CONFIGURATION.equals(configuration.getName())) { Configuration configuration) {
if (VersionManagedDependencies.CONFIGURATION.equals(configuration.getName())) {
return; return;
} }
VersionResolver versionResolver = new VersionResolver(project); VersionResolver versionResolver = new VersionResolver(project);
...@@ -56,13 +46,10 @@ public class SpringBootResolutionStrategy { ...@@ -56,13 +46,10 @@ public class SpringBootResolutionStrategy {
private static class VersionResolver implements Action<DependencyResolveDetails> { private static class VersionResolver implements Action<DependencyResolveDetails> {
private Configuration versionManagementConfiguration; private final VersionManagedDependencies versionManagedDependencies;
private Collection<Dependencies> versionManagedDependencies;
public VersionResolver(Project project) { public VersionResolver(Project project) {
this.versionManagementConfiguration = project.getConfigurations().getByName( this.versionManagedDependencies = new VersionManagedDependencies(project);
VERSION_MANAGEMENT_CONFIGURATION);
} }
@Override @Override
...@@ -74,41 +61,19 @@ public class SpringBootResolutionStrategy { ...@@ -74,41 +61,19 @@ public class SpringBootResolutionStrategy {
} }
private void resolve(DependencyResolveDetails resolveDetails) { private void resolve(DependencyResolveDetails resolveDetails) {
ManagedDependencies dependencies = ManagedDependencies.get( ManagedDependencies dependencies = this.versionManagedDependencies
getVersionManagedDependencies()); .getManagedDependencies();
ModuleVersionSelector target = resolveDetails.getTarget(); ModuleVersionSelector target = resolveDetails.getTarget();
if (SPRING_BOOT_GROUP.equals(target.getGroup())) { if (SPRING_BOOT_GROUP.equals(target.getGroup())) {
resolveDetails.useVersion(dependencies.getSpringBootVersion()); resolveDetails.useVersion(dependencies.getSpringBootVersion());
return; return;
} }
Dependency dependency = dependencies.find(target.getGroup(), target.getName()); Dependency dependency = dependencies
.find(target.getGroup(), target.getName());
if (dependency != null) { if (dependency != null) {
resolveDetails.useVersion(dependency.getVersion()); resolveDetails.useVersion(dependency.getVersion());
} }
} }
private Collection<Dependencies> getVersionManagedDependencies() {
if (versionManagedDependencies == null) {
Set<File> files = versionManagementConfiguration.resolve();
List<Dependencies> dependencies = new ArrayList<Dependencies>(
files.size());
for (File file : files) {
dependencies.add(getPropertiesFileManagedDependencies(file));
}
this.versionManagedDependencies = dependencies;
}
return versionManagedDependencies;
}
private Dependencies getPropertiesFileManagedDependencies(File file) {
if (!file.getName().toLowerCase().endsWith(".properties")) {
throw new IllegalStateException(file + " is not a version property file");
}
try {
return new PropertiesFileDependencies(new FileInputStream(file));
} catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment