Add Kotlin DSL examples to Gradle Plugin's documentation

See gh-14585
This commit is contained in:
jnizet
2018-09-22 22:39:36 +02:00
committed by Andy Wilkinson
parent f8f6b474eb
commit 5ed6c0d1ab
52 changed files with 1193 additions and 120 deletions

View File

@@ -0,0 +1,48 @@
/*
* 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.docs;
/**
* The DSLs supported by Gradle and demonstrated in the documentation samples
*/
public enum DSL {
GROOVY("Groovy", ".gradle"), KOTLIN("Kotlin", ".gradle.kts");
private final String name;
private final String extension;
DSL(String name, String extension) {
this.name = name;
this.extension = extension;
}
/**
* Gets the user-friendly name of the DSL
*/
public String getName() {
return this.name;
}
/**
* Gets the file extension of build scripts (starting with a dot)
*/
public String getExtension() {
return this.extension;
}
}

View File

@@ -18,6 +18,7 @@ package org.springframework.boot.gradle.docs;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.gradle.testkit.GradleBuild;
@@ -25,19 +26,23 @@ import org.springframework.boot.gradle.testkit.GradleBuild;
* Tests for the getting started documentation.
*
* @author Andy Wilkinson
* @author Jean-Baptiste Nizet
*/
@RunWith(GradleMultiDslSuite.class)
public class GettingStartedDocumentationTests {
@Rule
public GradleBuild gradleBuild = new GradleBuild();
public GradleBuild gradleBuild;
public DSL dsl;
// NOTE: We can't run any `apply-plugin` tests because during a release the
// jar won't be there
@Test
public void typicalPluginsAppliesExceptedPlugins() {
this.gradleBuild.script("src/main/gradle/getting-started/typical-plugins.gradle")
.build("verify");
this.gradleBuild.script("src/main/gradle/getting-started/typical-plugins"
+ this.dsl.getExtension()).build("verify");
}
}

View File

@@ -0,0 +1,90 @@
/*
* 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.docs;
import java.util.ArrayList;
import java.util.List;
import org.gradle.api.Rule;
import org.junit.runner.Runner;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.Suite;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.springframework.boot.gradle.testkit.GradleBuild;
/**
* Custom {@link Suite} that runs tests against the Groovy and the Kotlin DSLs. Test
* classes using the suite must have a public {@link DSL} field named {@code dsl} and a
* public {@link GradleBuild} field named {@code gradleBuild} and annotated with
* {@link Rule}
*
* @author Jean-Baptiste Nizet
*/
public final class GradleMultiDslSuite extends Suite {
public GradleMultiDslSuite(Class<?> clazz) throws InitializationError {
super(clazz, createRunners(clazz));
}
private static List<Runner> createRunners(Class<?> clazz) throws InitializationError {
List<Runner> runners = new ArrayList<>();
runners.add(new GradleDslClassRunner(clazz, new GradleBuild(), DSL.GROOVY));
runners.add(new GradleDslClassRunner(clazz,
new GradleBuild().withMinimalGradleVersionForKotlinDSL(), DSL.KOTLIN));
return runners;
}
private static final class GradleDslClassRunner extends BlockJUnit4ClassRunner {
private final GradleBuild gradleBuild;
private final DSL dsl;
private GradleDslClassRunner(Class<?> klass, GradleBuild gradleBuild, DSL dsl)
throws InitializationError {
super(klass);
this.gradleBuild = gradleBuild;
this.dsl = dsl;
}
@Override
protected Object createTest() throws Exception {
Object test = super.createTest();
configureTest(test);
return test;
}
private void configureTest(Object test) throws Exception {
test.getClass().getField("gradleBuild").set(test, this.gradleBuild);
test.getClass().getField("dsl").set(test, this.dsl);
}
@Override
protected String getName() {
return this.dsl.getName() + " DSL";
}
@Override
protected String testName(FrameworkMethod method) {
return method.getName() + " [" + getName() + "]";
}
}
}

View File

@@ -23,6 +23,7 @@ import java.util.Properties;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.gradle.testkit.GradleBuild;
@@ -32,16 +33,21 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for the generating build info documentation.
*
* @author Andy Wilkinson
* @author Jean-Baptiste Nizet
*/
@RunWith(GradleMultiDslSuite.class)
public class IntegratingWithActuatorDocumentationTests {
@Rule
public GradleBuild gradleBuild = new GradleBuild();
public GradleBuild gradleBuild;
public DSL dsl;
@Test
public void basicBuildInfo() throws IOException {
this.gradleBuild.script(
"src/main/gradle/integrating-with-actuator/build-info-basic.gradle")
this.gradleBuild
.script("src/main/gradle/integrating-with-actuator/build-info-basic"
+ this.dsl.getExtension())
.build("bootBuildInfo");
assertThat(new File(this.gradleBuild.getProjectDir(),
"build/resources/main/META-INF/build-info.properties")).isFile();
@@ -50,7 +56,8 @@ public class IntegratingWithActuatorDocumentationTests {
@Test
public void buildInfoCustomValues() throws IOException {
this.gradleBuild.script(
"src/main/gradle/integrating-with-actuator/build-info-custom-values.gradle")
"src/main/gradle/integrating-with-actuator/build-info-custom-values"
+ this.dsl.getExtension())
.build("bootBuildInfo");
File file = new File(this.gradleBuild.getProjectDir(),
"build/resources/main/META-INF/build-info.properties");
@@ -64,8 +71,9 @@ public class IntegratingWithActuatorDocumentationTests {
@Test
public void buildInfoAdditional() throws IOException {
this.gradleBuild.script(
"src/main/gradle/integrating-with-actuator/build-info-additional.gradle")
this.gradleBuild
.script("src/main/gradle/integrating-with-actuator/build-info-additional"
+ this.dsl.getExtension())
.build("bootBuildInfo");
File file = new File(this.gradleBuild.getProjectDir(),
"build/resources/main/META-INF/build-info.properties");

View File

@@ -18,6 +18,7 @@ package org.springframework.boot.gradle.docs;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.gradle.testkit.GradleBuild;
@@ -27,32 +28,49 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for the managing dependencies documentation.
*
* @author Andy Wilkinson
* @author Jean-Baptiste Nizet
*/
@RunWith(GradleMultiDslSuite.class)
public class ManagingDependenciesDocumentationTests {
@Rule
public GradleBuild gradleBuild = new GradleBuild();
public GradleBuild gradleBuild;
public DSL dsl;
@Test
public void dependenciesExampleEvaluatesSuccessfully() {
this.gradleBuild
.script("src/main/gradle/managing-dependencies/dependencies.gradle")
.build();
this.gradleBuild.script("src/main/gradle/managing-dependencies/dependencies"
+ this.dsl.getExtension()).build();
}
@Test
public void customManagedVersions() {
assertThat(this.gradleBuild
.script("src/main/gradle/managing-dependencies/custom-version.gradle")
.build("slf4jVersion").getOutput()).contains("1.7.20");
assertThat(
this.gradleBuild
.script("src/main/gradle/managing-dependencies/custom-version"
+ this.dsl.getExtension())
.build("slf4jVersion").getOutput()).contains("1.7.20");
}
@Test
public void dependencyManagementInIsolation() {
assertThat(this.gradleBuild
.script("src/main/gradle/managing-dependencies/configure-bom.gradle")
.script("src/main/gradle/managing-dependencies/configure-bom"
+ this.dsl.getExtension())
.build("dependencyManagement").getOutput())
.contains("org.springframework.boot:spring-boot-starter ");
}
@Test
public void dependencyManagementInIsolationWithPluginsBlock() {
if (this.dsl == DSL.KOTLIN) {
assertThat(this.gradleBuild.script(
"src/main/gradle/managing-dependencies/configure-bom-with-plugins"
+ this.dsl.getExtension())
.build("dependencyManagement").getOutput())
.contains("org.springframework.boot:spring-boot-starter ");
}
}
}

View File

@@ -25,6 +25,7 @@ import java.util.jar.JarFile;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.gradle.testkit.GradleBuild;
import org.springframework.util.FileCopyUtils;
@@ -35,22 +36,26 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for the packaging documentation.
*
* @author Andy Wilkinson
* @author Jean-Baptiste Nizet
*/
@RunWith(GradleMultiDslSuite.class)
public class PackagingDocumentationTests {
@Rule
public GradleBuild gradleBuild = new GradleBuild();
public GradleBuild gradleBuild;
public DSL dsl;
@Test
public void warContainerDependencyEvaluatesSuccessfully() {
this.gradleBuild
.script("src/main/gradle/packaging/war-container-dependency.gradle")
.build();
this.gradleBuild.script("src/main/gradle/packaging/war-container-dependency"
+ this.dsl.getExtension()).build();
}
@Test
public void bootJarMainClass() throws IOException {
this.gradleBuild.script("src/main/gradle/packaging/boot-jar-main-class.gradle")
this.gradleBuild.script(
"src/main/gradle/packaging/boot-jar-main-class" + this.dsl.getExtension())
.build("bootJar");
File file = new File(this.gradleBuild.getProjectDir(),
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
@@ -63,9 +68,8 @@ public class PackagingDocumentationTests {
@Test
public void bootJarManifestMainClass() throws IOException {
this.gradleBuild
.script("src/main/gradle/packaging/boot-jar-manifest-main-class.gradle")
.build("bootJar");
this.gradleBuild.script("src/main/gradle/packaging/boot-jar-manifest-main-class"
+ this.dsl.getExtension()).build("bootJar");
File file = new File(this.gradleBuild.getProjectDir(),
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
assertThat(file).isFile();
@@ -77,9 +81,8 @@ public class PackagingDocumentationTests {
@Test
public void applicationPluginMainClass() throws IOException {
this.gradleBuild
.script("src/main/gradle/packaging/application-plugin-main-class.gradle")
.build("bootJar");
this.gradleBuild.script("src/main/gradle/packaging/application-plugin-main-class"
+ this.dsl.getExtension()).build("bootJar");
File file = new File(this.gradleBuild.getProjectDir(),
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
assertThat(file).isFile();
@@ -91,9 +94,8 @@ public class PackagingDocumentationTests {
@Test
public void springBootDslMainClass() throws IOException {
this.gradleBuild
.script("src/main/gradle/packaging/spring-boot-dsl-main-class.gradle")
.build("bootJar");
this.gradleBuild.script("src/main/gradle/packaging/spring-boot-dsl-main-class"
+ this.dsl.getExtension()).build("bootJar");
File file = new File(this.gradleBuild.getProjectDir(),
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
assertThat(file).isFile();
@@ -107,9 +109,8 @@ public class PackagingDocumentationTests {
public void bootWarIncludeDevtools() throws IOException {
new File(this.gradleBuild.getProjectDir(),
"spring-boot-devtools-1.2.3.RELEASE.jar").createNewFile();
this.gradleBuild
.script("src/main/gradle/packaging/boot-war-include-devtools.gradle")
.build("bootWar");
this.gradleBuild.script("src/main/gradle/packaging/boot-war-include-devtools"
+ this.dsl.getExtension()).build("bootWar");
File file = new File(this.gradleBuild.getProjectDir(),
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".war");
assertThat(file).isFile();
@@ -121,9 +122,8 @@ public class PackagingDocumentationTests {
@Test
public void bootJarRequiresUnpack() throws IOException {
this.gradleBuild
.script("src/main/gradle/packaging/boot-jar-requires-unpack.gradle")
.build("bootJar");
this.gradleBuild.script("src/main/gradle/packaging/boot-jar-requires-unpack"
+ this.dsl.getExtension()).build("bootJar");
File file = new File(this.gradleBuild.getProjectDir(),
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
assertThat(file).isFile();
@@ -136,9 +136,8 @@ public class PackagingDocumentationTests {
@Test
public void bootJarIncludeLaunchScript() throws IOException {
this.gradleBuild
.script("src/main/gradle/packaging/boot-jar-include-launch-script.gradle")
.build("bootJar");
this.gradleBuild.script("src/main/gradle/packaging/boot-jar-include-launch-script"
+ this.dsl.getExtension()).build("bootJar");
File file = new File(this.gradleBuild.getProjectDir(),
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
assertThat(file).isFile();
@@ -148,8 +147,9 @@ public class PackagingDocumentationTests {
@Test
public void bootJarLaunchScriptProperties() throws IOException {
this.gradleBuild.script(
"src/main/gradle/packaging/boot-jar-launch-script-properties.gradle")
this.gradleBuild
.script("src/main/gradle/packaging/boot-jar-launch-script-properties"
+ this.dsl.getExtension())
.build("bootJar");
File file = new File(this.gradleBuild.getProjectDir(),
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
@@ -164,9 +164,8 @@ public class PackagingDocumentationTests {
"src/custom.script");
customScriptFile.getParentFile().mkdirs();
FileCopyUtils.copy("custom", new FileWriter(customScriptFile));
this.gradleBuild
.script("src/main/gradle/packaging/boot-jar-custom-launch-script.gradle")
.build("bootJar");
this.gradleBuild.script("src/main/gradle/packaging/boot-jar-custom-launch-script"
+ this.dsl.getExtension()).build("bootJar");
File file = new File(this.gradleBuild.getProjectDir(),
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
assertThat(file).isFile();
@@ -175,9 +174,8 @@ public class PackagingDocumentationTests {
@Test
public void bootWarPropertiesLauncher() throws IOException {
this.gradleBuild
.script("src/main/gradle/packaging/boot-war-properties-launcher.gradle")
.build("bootWar");
this.gradleBuild.script("src/main/gradle/packaging/boot-war-properties-launcher"
+ this.dsl.getExtension()).build("bootWar");
File file = new File(this.gradleBuild.getProjectDir(),
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".war");
assertThat(file).isFile();
@@ -188,8 +186,9 @@ public class PackagingDocumentationTests {
}
@Test
public void bootJarAndJar() throws IOException {
this.gradleBuild.script("src/main/gradle/packaging/boot-jar-and-jar.gradle")
public void bootJarAndJar() {
this.gradleBuild.script(
"src/main/gradle/packaging/boot-jar-and-jar" + this.dsl.getExtension())
.build("assemble");
File jar = new File(this.gradleBuild.getProjectDir(),
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");

View File

@@ -20,6 +20,7 @@ import java.io.IOException;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.gradle.testkit.GradleBuild;
@@ -29,26 +30,32 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for the publishing documentation.
*
* @author Andy Wilkinson
* @author Jean-Baptiste Nizet
*/
@RunWith(GradleMultiDslSuite.class)
public class PublishingDocumentationTests {
@Rule
public GradleBuild gradleBuild = new GradleBuild();
public GradleBuild gradleBuild;
public DSL dsl;
@Test
public void mavenUpload() throws IOException {
assertThat(this.gradleBuild.script("src/main/gradle/publishing/maven.gradle")
assertThat(this.gradleBuild
.script("src/main/gradle/publishing/maven" + this.dsl.getExtension())
.build("deployerRepository").getOutput())
.contains("https://repo.example.com");
}
@Test
public void mavenPublish() throws IOException {
assertThat(
this.gradleBuild.script("src/main/gradle/publishing/maven-publish.gradle")
.build("publishingConfiguration").getOutput())
.contains("MavenPublication")
.contains("https://repo.example.com");
assertThat(this.gradleBuild
.script("src/main/gradle/publishing/maven-publish"
+ this.dsl.getExtension())
.build("publishingConfiguration").getOutput())
.contains("MavenPublication")
.contains("https://repo.example.com");
}
}

View File

@@ -21,6 +21,7 @@ import java.io.IOException;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.gradle.testkit.GradleBuild;
@@ -30,23 +31,29 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for the documentation about running a Spring Boot application.
*
* @author Andy Wilkinson
* @author Jean-Baptiste Nizet
*/
@RunWith(GradleMultiDslSuite.class)
public class RunningDocumentationTests {
@Rule
public GradleBuild gradleBuild = new GradleBuild();
public GradleBuild gradleBuild;
public DSL dsl;
@Test
public void bootRunMain() throws IOException {
assertThat(this.gradleBuild.script("src/main/gradle/running/boot-run-main.gradle")
assertThat(this.gradleBuild
.script("src/main/gradle/running/boot-run-main" + this.dsl.getExtension())
.build("configuredMainClass").getOutput())
.contains("com.example.ExampleApplication");
}
@Test
public void applicationPluginMainClassName() throws IOException {
assertThat(this.gradleBuild.script(
"src/main/gradle/running/application-plugin-main-class-name.gradle")
public void applicationPluginMainClassName() {
assertThat(this.gradleBuild
.script("src/main/gradle/running/application-plugin-main-class-name"
+ this.dsl.getExtension())
.build("configuredMainClass").getOutput())
.contains("com.example.ExampleApplication");
}
@@ -54,7 +61,8 @@ public class RunningDocumentationTests {
@Test
public void springBootDslMainClassName() throws IOException {
assertThat(this.gradleBuild
.script("src/main/gradle/running/spring-boot-dsl-main-class-name.gradle")
.script("src/main/gradle/running/spring-boot-dsl-main-class-name"
+ this.dsl.getExtension())
.build("configuredMainClass").getOutput())
.contains("com.example.ExampleApplication");
}
@@ -62,7 +70,8 @@ public class RunningDocumentationTests {
@Test
public void bootRunSourceResources() throws IOException {
assertThat(this.gradleBuild
.script("src/main/gradle/running/boot-run-source-resources.gradle")
.script("src/main/gradle/running/boot-run-source-resources"
+ this.dsl.getExtension())
.build("configuredClasspath").getOutput())
.contains(new File("src/main/resources").getPath());
}

View File

@@ -26,6 +26,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
@@ -43,6 +44,9 @@ import org.junit.rules.TemporaryFolder;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.springframework.asm.ClassVisitor;
@@ -162,12 +166,19 @@ public class GradleBuild implements TestRule {
public GradleRunner prepareRunner(String... arguments) throws IOException {
String scriptContent = FileCopyUtils.copyToString(new FileReader(this.script))
.replace("{version}", getBootVersion());
.replace("{version}", getBootVersion())
.replace("{dependency-management-plugin-version}",
getDependencyManagementPluginVersion());
boolean isKotlin = this.script.endsWith(".kts");
String extension = isKotlin ? ".kts" : "";
FileCopyUtils.copy(scriptContent,
new FileWriter(new File(this.projectDir, "build.gradle")));
new FileWriter(new File(this.projectDir, "build.gradle" + extension)));
GradleRunner gradleRunner = GradleRunner.create().withProjectDir(this.projectDir)
.withDebug(true).withPluginClasspath(pluginClasspath());
.withPluginClasspath(pluginClasspath());
if (!isKotlin) {
// see https://github.com/gradle/gradle/issues/6862
gradleRunner.withDebug(true);
}
if (this.gradleVersion != null) {
gradleRunner.withGradleVersion(this.gradleVersion);
}
@@ -191,6 +202,11 @@ public class GradleBuild implements TestRule {
return this;
}
public GradleBuild withMinimalGradleVersionForKotlinDSL() {
this.gradleVersion = "4.10.2";
return this;
}
public String getGradleVersion() {
return this.gradleVersion;
}
@@ -201,13 +217,34 @@ public class GradleBuild implements TestRule {
+ "/text()");
}
private static String getDependencyManagementPluginVersion() {
try (FileReader pomReader = new FileReader(".flattened-pom.xml")) {
Document pom = DocumentBuilderFactory.newInstance().newDocumentBuilder()
.parse(new InputSource(pomReader));
NodeList dependencyElements = pom.getElementsByTagName("dependency");
for (int i = 0; i < dependencyElements.getLength(); i++) {
Element dependency = (Element) dependencyElements.item(i);
if (dependency.getElementsByTagName("artifactId").item(0).getTextContent()
.equals("dependency-management-plugin")) {
return dependency.getElementsByTagName("version").item(0)
.getTextContent();
}
}
throw new IllegalStateException(
"dependency management plugin version not found");
}
catch (Exception ex) {
throw new IllegalStateException(
"Failed to find dependency management plugin version", ex);
}
}
private static String evaluateExpression(String expression) {
try {
try (FileReader pomReader = new FileReader(".flattened-pom.xml")) {
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xpath = xPathFactory.newXPath();
XPathExpression expr = xpath.compile(expression);
String version = expr
.evaluate(new InputSource(new FileReader(".flattened-pom.xml")));
String version = expr.evaluate(new InputSource(pomReader));
return version;
}
catch (Exception ex) {