From 2668e41dd51b12701ce3da348122b8024d6d776e Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 Jan 2018 11:39:59 +0000 Subject: [PATCH] =?UTF-8?q?Make=20it=20easier=20to=20just=20use=20Boot?= =?UTF-8?q?=E2=80=99s=20dependency=20management=20with=20Gradle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes gh-11059 --- .../main/asciidoc/managing-dependencies.adoc | 42 +++++++++++++++++ .../apply-plugin-snapshot.gradle | 2 +- .../configure-bom.gradle | 35 ++++++++++++++ .../depend-on-plugin-milestone.gradle | 9 ++++ .../depend-on-plugin-release.gradle | 3 ++ .../depend-on-plugin-snapshot.gradle | 9 ++++ .../DependencyManagementPluginAction.java | 46 ++----------------- .../boot/gradle/plugin/SpringBootPlugin.java | 46 ++++++++++++++++++- ...anagingDependenciesDocumentationTests.java | 10 +++- ...yDependencyManagementIntegrationTests.java | 46 +++++++++++++++++++ ...ependencyManagementIntegrationTests.gradle | 25 ++++++++++ 11 files changed, 227 insertions(+), 46 deletions(-) create mode 100644 spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/configure-bom.gradle create mode 100644 spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/depend-on-plugin-milestone.gradle create mode 100644 spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/depend-on-plugin-release.gradle create mode 100644 spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/depend-on-plugin-snapshot.gradle create mode 100644 spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/OnlyDependencyManagementIntegrationTests.java create mode 100644 spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/OnlyDependencyManagementIntegrationTests.gradle diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/managing-dependencies.adoc b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/managing-dependencies.adoc index 7d2a41a08ae..f3f0d2893a7 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/managing-dependencies.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/managing-dependencies.adoc @@ -39,6 +39,48 @@ be done with care. +[[managing-dependencies-using-in-isolation]] +=== Using Spring Boot's dependency management in isolation + +Spring Boot's dependency management can be used in a project without applying Spring +Boot's plugin to that project. The `SpringBootPlugin` class provides a `BOM_COORDINATES` +constant that can be used to import the bom without having to know its group ID, +artifact ID, or version. + +First, configure the project to depend on the Spring Boot plugin but do not apply it: + +ifeval::["{version-type}" == "RELEASE"] +---- +include::../gradle/managing-dependencies/depend-on-plugin-release.gradle[] +---- +endif::[] +ifeval::["{version-type}" == "MILESTONE"] +[source,groovy,indent=0,subs="verbatim,attributes"] +---- +include::../gradle/managing-dependencies/depend-on-plugin-milestone.gradle[] +---- +endif::[] +ifeval::["{version-type}" == "SNAPSHOT"] +[source,groovy,indent=0,subs="verbatim,attributes"] +---- +include::../gradle/managing-dependencies/depend-on-plugin-snapshot.gradle[] +---- +endif::[] + +The Spring Boot plugin's dependency on the dependency management plugin means that you +can use the dependency management plugin without having to declare a dependency on it. +This also means that you will automatically use the same version of the dependency +management plugin as Spring Boot uses. + +Apply the dependency management plugin and then configure it to import Spring Boot's bom: + +[source,groovy,indent=0,subs="verbatim,attributes"] +---- +include::../gradle/managing-dependencies/configure-bom.gradle[tags=configure-bom] +---- + + + [[managing-dependencies-learning-more]] === Learning more diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-snapshot.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-snapshot.gradle index c775fa09252..5872a19b773 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-snapshot.gradle +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/getting-started/apply-plugin-snapshot.gradle @@ -4,7 +4,7 @@ buildscript { } dependencies { - classpath files(pluginClasspath.split(',')) + classpath 'org.springframework.boot:spring-boot-gradle-plugin:{version}' } } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/configure-bom.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/configure-bom.gradle new file mode 100644 index 00000000000..00b62fe807d --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/configure-bom.gradle @@ -0,0 +1,35 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +plugins { + id 'java' +} + +apply plugin: 'io.spring.dependency-management' + +dependencyManagement { + resolutionStrategy { + eachDependency { + if (it.requested.group == 'org.springframework.boot') { + it.useVersion project.bootVersion + } + } + } +} + +repositories { + mavenLocal() +} + +// tag::configure-bom[] +apply plugin: 'io.spring.dependency-management' + +dependencyManagement { + imports { + mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES + } +} +// end::configure-bom[] diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/depend-on-plugin-milestone.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/depend-on-plugin-milestone.gradle new file mode 100644 index 00000000000..9b8007b8dd3 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/depend-on-plugin-milestone.gradle @@ -0,0 +1,9 @@ +buildscript { + repositories { + maven { url 'https://repo.spring.io/libs-milestone' } + } + + dependencies { + classpath 'org.springframework.boot:spring-boot-gradle-plugin:{version}' + } +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/depend-on-plugin-release.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/depend-on-plugin-release.gradle new file mode 100644 index 00000000000..9bde7c2d3fa --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/depend-on-plugin-release.gradle @@ -0,0 +1,3 @@ +plugins { + id 'org.springframework.boot' version '{version}' apply false +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/depend-on-plugin-snapshot.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/depend-on-plugin-snapshot.gradle new file mode 100644 index 00000000000..ab0eb4b2cb4 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/gradle/managing-dependencies/depend-on-plugin-snapshot.gradle @@ -0,0 +1,9 @@ +buildscript { + repositories { + maven { url 'https://repo.spring.io/libs-snapshot' } + } + + dependencies { + classpath 'org.springframework.boot:spring-boot-gradle-plugin:{version}' + } +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/DependencyManagementPluginAction.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/DependencyManagementPluginAction.java index 2e73595d8ea..91f121bda9f 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/DependencyManagementPluginAction.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/DependencyManagementPluginAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -16,14 +16,6 @@ package org.springframework.boot.gradle.plugin; -import java.io.File; -import java.io.IOException; -import java.net.JarURLConnection; -import java.net.URL; -import java.net.URLConnection; -import java.util.jar.Attributes; -import java.util.jar.JarFile; - import io.spring.gradle.dependencymanagement.DependencyManagementPlugin; import io.spring.gradle.dependencymanagement.dsl.DependencyManagementExtension; import org.gradle.api.Action; @@ -38,15 +30,11 @@ import org.gradle.api.Project; */ final class DependencyManagementPluginAction implements PluginApplicationAction { - private static final String SPRING_BOOT_VERSION = determineSpringBootVersion(); - - private static final String SPRING_BOOT_BOM = "org.springframework.boot:spring-boot-dependencies:" - + SPRING_BOOT_VERSION; - @Override public void execute(Project project) { project.getExtensions().findByType(DependencyManagementExtension.class) - .imports((importsHandler) -> importsHandler.mavenBom(SPRING_BOOT_BOM)); + .imports((importsHandler) -> importsHandler + .mavenBom(SpringBootPlugin.BOM_COORDINATES)); } @Override @@ -54,32 +42,4 @@ final class DependencyManagementPluginAction implements PluginApplicationAction return DependencyManagementPlugin.class; } - private static String determineSpringBootVersion() { - String implementationVersion = DependencyManagementPluginAction.class.getPackage() - .getImplementationVersion(); - if (implementationVersion != null) { - return implementationVersion; - } - URL codeSourceLocation = DependencyManagementPluginAction.class - .getProtectionDomain().getCodeSource().getLocation(); - try { - URLConnection connection = codeSourceLocation.openConnection(); - if (connection instanceof JarURLConnection) { - return getImplementationVersion( - ((JarURLConnection) connection).getJarFile()); - } - try (JarFile jarFile = new JarFile(new File(codeSourceLocation.toURI()))) { - return getImplementationVersion(jarFile); - } - } - catch (Exception ex) { - return null; - } - } - - private static String getImplementationVersion(JarFile jarFile) throws IOException { - return jarFile.getManifest().getMainAttributes() - .getValue(Attributes.Name.IMPLEMENTATION_VERSION); - } - } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/SpringBootPlugin.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/SpringBootPlugin.java index bb85d9664a0..ad0dc166245 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/SpringBootPlugin.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/SpringBootPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -16,8 +16,15 @@ package org.springframework.boot.gradle.plugin; +import java.io.File; +import java.io.IOException; +import java.net.JarURLConnection; +import java.net.URL; +import java.net.URLConnection; import java.util.Arrays; import java.util.List; +import java.util.jar.Attributes; +import java.util.jar.JarFile; import org.gradle.api.GradleException; import org.gradle.api.Plugin; @@ -38,6 +45,8 @@ import org.springframework.boot.gradle.tasks.bundling.BootWar; */ public class SpringBootPlugin implements Plugin { + private static final String SPRING_BOOT_VERSION = determineSpringBootVersion(); + /** * The name of the {@link Configuration} that contains Spring Boot archives. * @since 2.0.0 @@ -58,6 +67,13 @@ public class SpringBootPlugin implements Plugin { */ public static final String BOOT_WAR_TASK_NAME = "bootWar"; + /** + * The coordinates {@code (group:name:version)} of the + * {@code spring-boot-dependencies} bom. + */ + public static final String BOM_COORDINATES = "org.springframework.boot:spring-boot-dependencies:" + + SPRING_BOOT_VERSION; + @Override public void apply(Project project) { verifyGradleVersion(); @@ -110,4 +126,32 @@ public class SpringBootPlugin implements Plugin { (buildResult) -> unresolvedDependenciesAnalyzer.buildFinished(project)); } + private static String determineSpringBootVersion() { + String implementationVersion = DependencyManagementPluginAction.class.getPackage() + .getImplementationVersion(); + if (implementationVersion != null) { + return implementationVersion; + } + URL codeSourceLocation = DependencyManagementPluginAction.class + .getProtectionDomain().getCodeSource().getLocation(); + try { + URLConnection connection = codeSourceLocation.openConnection(); + if (connection instanceof JarURLConnection) { + return getImplementationVersion( + ((JarURLConnection) connection).getJarFile()); + } + try (JarFile jarFile = new JarFile(new File(codeSourceLocation.toURI()))) { + return getImplementationVersion(jarFile); + } + } + catch (Exception ex) { + return null; + } + } + + private static String getImplementationVersion(JarFile jarFile) throws IOException { + return jarFile.getManifest().getMainAttributes() + .getValue(Attributes.Name.IMPLEMENTATION_VERSION); + } + } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/ManagingDependenciesDocumentationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/ManagingDependenciesDocumentationTests.java index 0d69c8a0b6f..3394219aa92 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/ManagingDependenciesDocumentationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/ManagingDependenciesDocumentationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -47,4 +47,12 @@ public class ManagingDependenciesDocumentationTests { .build("slf4jVersion").getOutput()).contains("1.7.20"); } + @Test + public void dependencyManagementInIsolation() { + assertThat(this.gradleBuild + .script("src/main/gradle/managing-dependencies/configure-bom.gradle") + .build("dependencyManagement").getOutput()) + .contains("org.springframework.boot:spring-boot-starter "); + } + } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/OnlyDependencyManagementIntegrationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/OnlyDependencyManagementIntegrationTests.java new file mode 100644 index 00000000000..850661e5b24 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/OnlyDependencyManagementIntegrationTests.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-2018 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.plugin; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.boot.gradle.junit.GradleCompatibilitySuite; +import org.springframework.boot.gradle.testkit.GradleBuild; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for configuring a project to only use Spring Boot's dependency + * management. + * + * @author Andy Wilkinson + */ +@RunWith(GradleCompatibilitySuite.class) +public class OnlyDependencyManagementIntegrationTests { + + @Rule + public GradleBuild gradleBuild; + + @Test + public void dependencyManagementCanBeConfiguredUsingCoordinatesConstant() { + assertThat(this.gradleBuild.build("dependencyManagement").getOutput()) + .contains("org.springframework.boot:spring-boot-starter "); + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/OnlyDependencyManagementIntegrationTests.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/OnlyDependencyManagementIntegrationTests.gradle new file mode 100644 index 00000000000..40e2c8ed381 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/OnlyDependencyManagementIntegrationTests.gradle @@ -0,0 +1,25 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +apply plugin: 'io.spring.dependency-management' +apply plugin: 'java' + +repositories { + mavenLocal() +} + +dependencyManagement { + resolutionStrategy { + eachDependency { + if (it.requested.group == 'org.springframework.boot') { + it.useVersion project.bootVersion + } + } + } + imports { + mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES + } +}