From 199088b0c9a89495184720b481d013cbea810df5 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 29 Jan 2018 10:13:12 +0000 Subject: [PATCH] Set kotlin.version when Kotlin's Gradle plugin is applied Closes gh-11711 --- .../spring-boot-gradle-plugin/pom.xml | 6 ++ .../src/main/asciidoc/reacting.adoc | 14 +++++ .../gradle/plugin/KotlinPluginAction.java | 56 +++++++++++++++++++ .../plugin/PluginApplicationAction.java | 6 +- .../boot/gradle/plugin/SpringBootPlugin.java | 11 +++- .../KotlinPluginActionIntegrationTests.java | 54 ++++++++++++++++++ ...inVersionMatchesKotlinPluginVersion.gradle | 39 +++++++++++++ ...nVersionPropertyWithoutKotlinPlugin.gradle | 14 +++++ 8 files changed, 194 insertions(+), 6 deletions(-) create mode 100644 spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/KotlinPluginAction.java create mode 100644 spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests.java create mode 100644 spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests-kotlinVersionMatchesKotlinPluginVersion.gradle create mode 100644 spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests-noKotlinVersionPropertyWithoutKotlinPlugin.gradle diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/pom.xml index b61dba0f6021..9870105e2e69 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/pom.xml +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/pom.xml @@ -29,6 +29,12 @@ org.apache.commons commons-compress + + org.jetbrains.kotlin + kotlin-gradle-plugin + ${kotlin.version} + true + diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/reacting.adoc b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/reacting.adoc index 22029c012468..420a74a68f18 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/reacting.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/reacting.adoc @@ -4,6 +4,8 @@ When another plugin is applied the Spring Boot plugin reacts by making various changes to the project's configuration. This section describes those changes. + + [[reacting-to-other-plugins-java]] === Reacting to the Java plugin @@ -25,6 +27,18 @@ plugin: +[[reacting-to-other-plugins-kotlin]] +=== Reacting to the Kotlin plugin + +When {kotlin-plugin}[Kotlin's Gradle plugin] is applied to a project, the Spring Boot +plugin: + +1. Aligns the Koltin version used in Spring Boot's dependency management with the version + of the plugin. This is achieved by setting the `kotlin.version` property with a value + that matches the version of the Kotlin plugin. + + + [[reacting-to-other-plugins-war]] === Reacting to the war plugin diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/KotlinPluginAction.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/KotlinPluginAction.java new file mode 100644 index 000000000000..13c6e213ec19 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/KotlinPluginAction.java @@ -0,0 +1,56 @@ +/* + * 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.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.plugins.ExtraPropertiesExtension; +import org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper; + +/** + * {@link PluginApplicationAction} that reacts to Kotlin's Gradle plugin being applied by + * configuring a {@code kotlin.version} property to align the version used for dependency + * management for Kotlin with the version of its plugin. + * + * @author Andy Wilkinson + */ +class KotlinPluginAction implements PluginApplicationAction { + + @Override + public void execute(Project project) { + String kotlinVersion = project.getPlugins().getPlugin(KotlinPluginWrapper.class) + .getKotlinPluginVersion(); + ExtraPropertiesExtension extraProperties = project.getExtensions() + .getExtraProperties(); + if (!extraProperties.has("kotlin.version")) { + extraProperties.set("kotlin.version", kotlinVersion); + } + } + + @Override + @SuppressWarnings("unchecked") + public Class> getPluginClass() { + try { + return (Class>) Class + .forName("org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper"); + } + catch (Throwable ex) { + return null; + } + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/PluginApplicationAction.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/PluginApplicationAction.java index a02de18610b3..d43b354a096b 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/PluginApplicationAction.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/PluginApplicationAction.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. @@ -30,9 +30,9 @@ interface PluginApplicationAction extends Action { /** * The class of the {@code Plugin} that, when applied, will trigger the execution of - * this action. + * this action. May return {@code null} if the plugin class is not on the classpath. * - * @return the plugin class + * @return the plugin class or {@code null} */ Class> getPluginClass(); 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 ad0dc1662454..dadf55259642 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 @@ -108,10 +108,15 @@ private void registerPluginActions(Project project, Configuration bootArchives) new JavaPluginAction(singlePublishedArtifact), new WarPluginAction(singlePublishedArtifact), new MavenPluginAction(bootArchives.getUploadTaskName()), - new DependencyManagementPluginAction(), new ApplicationPluginAction()); + new DependencyManagementPluginAction(), new ApplicationPluginAction(), + new KotlinPluginAction()); for (PluginApplicationAction action : actions) { - project.getPlugins().withType(action.getPluginClass(), - (plugin) -> action.execute(project)); + Class> pluginClass = action + .getPluginClass(); + if (pluginClass != null) { + project.getPlugins().withType(pluginClass, + (plugin) -> action.execute(project)); + } } } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests.java new file mode 100644 index 000000000000..2df695534782 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests.java @@ -0,0 +1,54 @@ +/* + * 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 {@link KotlinPluginAction}. + * + * @author Andy Wilkinson + */ +@RunWith(GradleCompatibilitySuite.class) +public class KotlinPluginActionIntegrationTests { + + @Rule + public GradleBuild gradleBuild; + + @Test + public void noKotlinVersionPropertyWithoutKotlinPlugin() { + assertThat(this.gradleBuild.build("kotlinVersion").getOutput()) + .contains("Kotlin version: none"); + } + + @Test + public void kotlinVersionMatchesKotlinPluginVersion() { + String output = this.gradleBuild + .build("kotlinVersion", "dependencies", "--configuration", "compile") + .getOutput(); + assertThat(output).contains("Kotlin version: 1.2.10"); + assertThat(output).contains("org.jetbrains.kotlin:kotlin-stdlib-jdk8: -> 1.2.10"); + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests-kotlinVersionMatchesKotlinPluginVersion.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests-kotlinVersionMatchesKotlinPluginVersion.gradle new file mode 100644 index 000000000000..561ae1d224a5 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests-kotlinVersionMatchesKotlinPluginVersion.gradle @@ -0,0 +1,39 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +plugins { + id 'org.jetbrains.kotlin.jvm' version '1.2.10' +} + + +apply plugin: 'org.springframework.boot' +apply plugin: 'io.spring.dependency-management' + +dependencyManagement { + resolutionStrategy { + eachDependency { + if (it.requested.group == 'org.springframework.boot') { + it.useVersion project.bootVersion + } + } + } +} + +repositories { + mavenCentral() + mavenLocal() +} + +dependencies { + compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' +} + +task kotlinVersion { + doLast { + def kotlinVersion = project.hasProperty('kotlin.version') ? project.getProperty('kotlin.version') : 'none' + println "Kotlin version: ${kotlinVersion}" + } +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests-noKotlinVersionPropertyWithoutKotlinPlugin.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests-noKotlinVersionPropertyWithoutKotlinPlugin.gradle new file mode 100644 index 000000000000..1f34d0a34b73 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests-noKotlinVersionPropertyWithoutKotlinPlugin.gradle @@ -0,0 +1,14 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +apply plugin: 'org.springframework.boot' + +task kotlinVersion { + doLast { + def kotlinVersion = project.hasProperty('kotlin.version') ? project.getProperty('kotlin.version') : 'none' + println "Kotlin version: ${kotlinVersion}" + } +}