From b1f9123311e0579d6b4c01f375611e0c0086a5d6 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 21 Mar 2017 14:56:13 +0000 Subject: [PATCH] React to dependency management plugin rather than always applying it Previously, the Spring Boot plugin would automatically apply the dependency management plugin and import the spring-boot-dependencies bom. This made it very difficult to use Spring Boot's plugin without also using its dependency management. It also made it difficult to see where the dependency management was coming from. This commit updates the Spring Boot plugin so that it no longer automatically applies the dependency management plugin. Instead, the plugin now reacts to the dependency management plugin being applied by importing the spring-boot-dependencies bom. Users that do not wish to use Spring Boot's dependency management capabilities can now do so by not applying the dependency management plugin. Closes gh-3164 --- .../DependencyManagementPluginFeatures.java | 10 ++-- .../DependencyManagementIntegrationTests.java | 52 +++++++++++++++++++ .../boot/gradle/testkit/GradleBuild.java | 44 +++++++++++++--- ...ependencyManagementIntegrationTests.gradle | 41 +++++++++++++++ 4 files changed, 138 insertions(+), 9 deletions(-) create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/dependencymanagement/DependencyManagementIntegrationTests.java create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/dependencymanagement/DependencyManagementIntegrationTests.gradle diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/dependencymanagement/DependencyManagementPluginFeatures.java b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/dependencymanagement/DependencyManagementPluginFeatures.java index 763bad251a..16f0c7c6f2 100644 --- a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/dependencymanagement/DependencyManagementPluginFeatures.java +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/dependencymanagement/DependencyManagementPluginFeatures.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-2017 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. @@ -36,12 +36,16 @@ public class DependencyManagementPluginFeatures implements PluginFeatures { private static final String SPRING_BOOT_VERSION = DependencyManagementPluginFeatures.class .getPackage().getImplementationVersion(); - private static final String SPRING_BOOT_BOM = "org.springframework.boot:spring-boot-starter-parent:" + private static final String SPRING_BOOT_BOM = "org.springframework.boot:spring-boot-dependencies:" + SPRING_BOOT_VERSION; @Override public void apply(Project project) { - project.getPlugins().apply(DependencyManagementPlugin.class); + project.getPlugins().withType(DependencyManagementPlugin.class, + (plugin) -> configureDependencyManagement(project)); + } + + private void configureDependencyManagement(Project project) { DependencyManagementExtension dependencyManagement = project.getExtensions() .findByType(DependencyManagementExtension.class); dependencyManagement.imports(new Action() { diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/dependencymanagement/DependencyManagementIntegrationTests.java b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/dependencymanagement/DependencyManagementIntegrationTests.java new file mode 100644 index 0000000000..f03a4dcf4b --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/dependencymanagement/DependencyManagementIntegrationTests.java @@ -0,0 +1,52 @@ +/* + * Copyright 2012-2017 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.dependencymanagement; + +import org.gradle.testkit.runner.TaskOutcome; +import org.junit.Rule; +import org.junit.Test; + +import org.springframework.boot.gradle.testkit.GradleBuild; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for the plugin's dependency management features. + * + * @author Andy Wilkinson + */ +public class DependencyManagementIntegrationTests { + + @Rule + public GradleBuild gradleBuild = new GradleBuild(); + + @Test + public void noDependencyManagementIsAppliedByDefault() { + assertThat(this.gradleBuild.build("doesNotHaveDependencyManagement") + .task(":doesNotHaveDependencyManagement").getOutcome()) + .isEqualTo(TaskOutcome.SUCCESS); + } + + @Test + public void bomIsImportedWhenDependencyManagementPluginIsApplied() { + assertThat(this.gradleBuild + .build("hasDependencyManagement", "-PapplyDependencyManagementPlugin") + .task(":hasDependencyManagement").getOutcome()) + .isEqualTo(TaskOutcome.SUCCESS); + } + +} diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/GradleBuild.java b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/GradleBuild.java index 4bde3bea62..d3bae7f497 100644 --- a/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/GradleBuild.java +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/GradleBuild.java @@ -17,6 +17,7 @@ package org.springframework.boot.gradle.testkit; import java.io.File; +import java.io.FileReader; import java.io.IOException; import java.net.URL; import java.nio.file.Files; @@ -25,6 +26,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathFactory; + import io.spring.gradle.dependencymanagement.DependencyManagementPlugin; import org.gradle.testkit.runner.BuildResult; import org.gradle.testkit.runner.GradleRunner; @@ -32,6 +37,7 @@ import org.junit.rules.TemporaryFolder; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; +import org.xml.sax.InputSource; import org.springframework.boot.loader.tools.LaunchScript; @@ -80,12 +86,18 @@ public class GradleBuild implements TestRule { } private String pluginClasspath() { - return new File("build/classes/main").getAbsolutePath() + "," - + new File("build/resources/main").getAbsolutePath() + "," - + LaunchScript.class.getProtectionDomain().getCodeSource().getLocation() - .getPath() - + "," + DependencyManagementPlugin.class.getProtectionDomain() - .getCodeSource().getLocation().getPath(); + return absolutePath("bin") + "," + absolutePath("build/classes/main") + "," + + absolutePath("build/resources/main") + "," + + pathOfJarContaining(LaunchScript.class) + "," + + pathOfJarContaining(DependencyManagementPlugin.class); + } + + private String absolutePath(String path) { + return new File(path).getAbsolutePath(); + } + + private String pathOfJarContaining(Class type) { + return type.getProtectionDomain().getCodeSource().getLocation().getPath(); } public GradleBuild script(String script) { @@ -102,6 +114,7 @@ public class GradleBuild implements TestRule { .withProjectDir(this.projectDir).forwardOutput(); List allArguments = new ArrayList(); allArguments.add("-PpluginClasspath=" + pluginClasspath()); + allArguments.add("-PbootVersion=" + getBootVersion()); allArguments.addAll(Arrays.asList(arguments)); return gradleRunner.withArguments(allArguments).build(); } @@ -110,4 +123,23 @@ public class GradleBuild implements TestRule { } } + public static String getBootVersion() { + return evaluateExpression( + "/*[local-name()='project']/*[local-name()='parent']/*[local-name()='version']" + + "/text()"); + } + + private static String evaluateExpression(String expression) { + try { + XPathFactory xPathFactory = XPathFactory.newInstance(); + XPath xpath = xPathFactory.newXPath(); + XPathExpression expr = xpath.compile(expression); + String version = expr.evaluate(new InputSource(new FileReader("pom.xml"))); + return version; + } + catch (Exception ex) { + throw new IllegalStateException("Failed to evaluate expression", ex); + } + } + } diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/dependencymanagement/DependencyManagementIntegrationTests.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/dependencymanagement/DependencyManagementIntegrationTests.gradle new file mode 100644 index 0000000000..12dca02ea4 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/dependencymanagement/DependencyManagementIntegrationTests.gradle @@ -0,0 +1,41 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +apply plugin: 'java' +apply plugin: 'org.springframework.boot' + +if (project.hasProperty('applyDependencyManagementPlugin')) { + apply plugin: 'io.spring.dependency-management' + dependencyManagement { + resolutionStrategy { + eachDependency { + if (it.requested.group == 'org.springframework.boot') { + it.useVersion project.bootVersion + } + } + } + } +} + +repositories { + mavenLocal() +} + +task doesNotHaveDependencyManagement { + doLast { + if (project.extensions.findByName('dependencyManagement') != null) { + throw new GradleException('Found dependency management extension') + } + } +} + +task hasDependencyManagement { + doLast { + if (!dependencyManagement.managedVersions) { + throw new GradleException('No managed versions have been configured') + } + } +}