Add support for Gradle's tasksWithType

This commit adds support for configuring several tasks at once using
a type. It also migrates the Kotlin support so that, instead of
configuring compileKotlin and compileTestKotlin, it configures all
tasks of type KotlinCompile at once.

See gh-890
This commit is contained in:
jnizet
2019-04-12 13:49:49 +02:00
committed by Stephane Nicoll
parent 3409325342
commit 0eeb85697e
9 changed files with 100 additions and 39 deletions

View File

@@ -26,6 +26,7 @@ import io.spring.initializr.generator.spring.build.BuildCustomizer;
* {@link BuildCustomizer} for Kotlin projects build with Gradle.
*
* @author Andy Wilkinson
* @author Jean-Baptiste Nizet
*/
class KotlinGradleBuildCustomizer implements BuildCustomizer<GradleBuild> {
@@ -39,8 +40,8 @@ class KotlinGradleBuildCustomizer implements BuildCustomizer<GradleBuild> {
public void customize(GradleBuild build) {
build.addPlugin("org.jetbrains.kotlin.jvm", this.settings.getVersion());
build.addPlugin("org.jetbrains.kotlin.plugin.spring", this.settings.getVersion());
build.customizeTask("compileKotlin", this::customizeKotlinOptions);
build.customizeTask("compileTestKotlin", this::customizeKotlinOptions);
build.addImportedType("org.jetbrains.kotlin.gradle.tasks.KotlinCompile");
build.customizeTasksWithType("KotlinCompile", this::customizeKotlinOptions);
}
private void customizeKotlinOptions(TaskCustomization compile) {

View File

@@ -48,11 +48,11 @@ class KotlinGradleBuildCustomizerTests {
GradleBuild build = new GradleBuild();
new KotlinGradleBuildCustomizer(new SimpleKotlinProjectSettings("1.2.70"))
.customize(build);
assertThat(build.getTaskCustomizations()).hasSize(2);
assertThat(build.getTaskCustomizations()).containsKeys("compileKotlin",
"compileTestKotlin");
assertKotlinOptions(build.getTaskCustomizations().get("compileKotlin"));
assertKotlinOptions(build.getTaskCustomizations().get("compileTestKotlin"));
assertThat(build.getImportedTypes())
.contains("org.jetbrains.kotlin.gradle.tasks.KotlinCompile");
assertThat(build.getTasksWithTypeCustomizations()).hasSize(1);
assertThat(build.getTasksWithTypeCustomizations()).containsKeys("KotlinCompile");
assertKotlinOptions(build.getTasksWithTypeCustomizations().get("KotlinCompile"));
}
private void assertKotlinOptions(TaskCustomization compileTask) {

View File

@@ -1,3 +1,5 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id 'org.springframework.boot' version '2.1.1.RELEASE'
id 'org.jetbrains.kotlin.jvm' version '1.1.1'
@@ -21,14 +23,7 @@ dependencies {
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
compileKotlin {
kotlinOptions {
freeCompilerArgs = ['-Xjsr305=strict']
jvmTarget = '1.8'
}
}
compileTestKotlin {
tasks.withType(KotlinCompile) {
kotlinOptions {
freeCompilerArgs = ['-Xjsr305=strict']
jvmTarget = '1.8'

View File

@@ -1,3 +1,5 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
buildscript {
repositories {
mavenCentral()
@@ -29,14 +31,7 @@ dependencies {
testCompile 'org.springframework.boot:spring-boot-starter-test'
}
compileKotlin {
kotlinOptions {
freeCompilerArgs = ['-Xjsr305=strict']
jvmTarget = '1.8'
}
}
compileTestKotlin {
tasks.withType(KotlinCompile) {
kotlinOptions {
freeCompilerArgs = ['-Xjsr305=strict']
jvmTarget = '1.8'

View File

@@ -1,3 +1,5 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id 'org.springframework.boot' version '2.1.1.RELEASE'
id 'org.jetbrains.kotlin.jvm' version '1.1.1'
@@ -21,14 +23,7 @@ dependencies {
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
compileKotlin {
kotlinOptions {
freeCompilerArgs = ['-Xjsr305=strict']
jvmTarget = '1.8'
}
}
compileTestKotlin {
tasks.withType(KotlinCompile) {
kotlinOptions {
freeCompilerArgs = ['-Xjsr305=strict']
jvmTarget = '1.8'

View File

@@ -1,3 +1,5 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id 'org.springframework.boot' version '2.1.1.RELEASE'
id 'war'
@@ -23,14 +25,7 @@ dependencies {
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
compileKotlin {
kotlinOptions {
freeCompilerArgs = ['-Xjsr305=strict']
jvmTarget = '1.8'
}
}
compileTestKotlin {
tasks.withType(KotlinCompile) {
kotlinOptions {
freeCompilerArgs = ['-Xjsr305=strict']
jvmTarget = '1.8'

View File

@@ -19,6 +19,7 @@ package io.spring.initializr.generator.buildsystem.gradle;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
@@ -34,6 +35,7 @@ import io.spring.initializr.generator.buildsystem.BuildItemResolver;
* Gradle build configuration for a project.
*
* @author Andy Wilkinson
* @author Jean-Baptiste Nizet
*/
public class GradleBuild extends Build {
@@ -49,6 +51,10 @@ public class GradleBuild extends Build {
private final Map<String, TaskCustomization> taskCustomizations = new LinkedHashMap<>();
private final Set<String> importedTypes = new HashSet<>();
private final Map<String, TaskCustomization> tasksWithTypeCustomizations = new LinkedHashMap<>();
private final Buildscript buildscript = new Buildscript();
public GradleBuild(BuildItemResolver buildItemResolver) {
@@ -121,6 +127,24 @@ public class GradleBuild extends Build {
return Collections.unmodifiableMap(this.configurationCustomizations);
}
public void addImportedType(String type) {
this.importedTypes.add(type);
}
public Set<String> getImportedTypes() {
return Collections.unmodifiableSet(this.importedTypes);
}
public void customizeTasksWithType(String typeName,
Consumer<TaskCustomization> customizer) {
customizer.accept(this.tasksWithTypeCustomizations.computeIfAbsent(typeName,
(name) -> new TaskCustomization()));
}
public Map<String, TaskCustomization> getTasksWithTypeCustomizations() {
return Collections.unmodifiableMap(this.tasksWithTypeCustomizations);
}
public void customizeTask(String taskName, Consumer<TaskCustomization> customizer) {
customizer.accept(this.taskCustomizations.computeIfAbsent(taskName,
(name) -> new TaskCustomization()));

View File

@@ -47,10 +47,12 @@ import io.spring.initializr.generator.version.VersionReference;
*
* @author Andy Wilkinson
* @author Stephane Nicoll
* @author Jean-Baptiste Nizet
*/
public class GradleBuildWriter {
public void writeTo(IndentingWriter writer, GradleBuild build) throws IOException {
writeImports(writer, build);
boolean buildScriptWritten = writeBuildscript(writer, build);
writePlugins(writer, build, buildScriptWritten);
writeProperty(writer, "group", build.getGroup());
@@ -61,9 +63,18 @@ public class GradleBuildWriter {
writeProperties(writer, build);
writeDependencies(writer, build);
writeBoms(writer, build);
writeTasksWithTypeCustomizations(writer, build);
writeTaskCustomizations(writer, build);
}
private void writeImports(IndentingWriter writer, GradleBuild build) {
build.getImportedTypes().stream().sorted().forEachOrdered(
(importedType) -> writer.println("import " + importedType));
if (!build.getImportedTypes().isEmpty()) {
writer.println();
}
}
private boolean writeBuildscript(IndentingWriter writer, GradleBuild build) {
List<String> dependencies = build.getBuildscript().getDependencies();
Map<String, String> ext = build.getBuildscript().getExt();
@@ -276,6 +287,19 @@ public class GradleBuildWriter {
return null;
}
private void writeTasksWithTypeCustomizations(IndentingWriter writer,
GradleBuild build) {
Map<String, GradleBuild.TaskCustomization> tasksWithTypeCustomizations = build
.getTasksWithTypeCustomizations();
tasksWithTypeCustomizations.forEach((typeName, customization) -> {
writer.println();
writer.println("tasks.withType(" + typeName + ") {");
writer.indented(() -> writeTaskCustomization(writer, customization));
writer.println("}");
});
}
private void writeTaskCustomizations(IndentingWriter writer, GradleBuild build) {
Map<String, TaskCustomization> taskCustomizations = build.getTaskCustomizations();
taskCustomizations.forEach((name, customization) -> {

View File

@@ -33,9 +33,25 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for {@link GradleBuildWriter}
*
* @author Andy Wilkinson
* @author Jean-Baptiste Nizet
*/
class GradleBuildWriterTests {
@Test
void gradleBuildWithImports() throws IOException {
GradleBuild build = new GradleBuild();
build.addImportedType(
"org.springframework.boot.gradle.tasks.buildinfo.BuildInfo");
build.addImportedType("org.jetbrains.kotlin.gradle.tasks.KotlinCompile");
// same import added twice on purpose
build.addImportedType("org.jetbrains.kotlin.gradle.tasks.KotlinCompile");
List<String> lines = generateBuild(build);
assertThat(lines.subList(0, 3)).containsExactly(
"import org.jetbrains.kotlin.gradle.tasks.KotlinCompile",
"import org.springframework.boot.gradle.tasks.buildinfo.BuildInfo", "");
}
@Test
void gradleBuildWithCoordinates() throws IOException {
GradleBuild build = new GradleBuild();
@@ -139,6 +155,22 @@ class GradleBuildWriterTests {
assertThat(lines).doesNotContain("repositories {");
}
@Test
void gradleBuildWithTaskWithTypesCustomizedWithNestedAssignments()
throws IOException {
GradleBuild build = new GradleBuild();
build.customizeTasksWithType("KotlinCompile", (task) -> {
task.nested("kotlinOptions", (kotlinOptions) -> {
kotlinOptions.set("freeCompilerArgs", "['-Xjsr305=strict']");
kotlinOptions.set("jvmTarget", "'1.8'");
});
});
List<String> lines = generateBuild(build);
assertThat(lines).containsSequence("tasks.withType(KotlinCompile) {",
" kotlinOptions {", " freeCompilerArgs = ['-Xjsr305=strict']",
" jvmTarget = '1.8'", " }", "}");
}
@Test
void gradleBuildWithTaskCustomizedWithInvocations() throws IOException {
GradleBuild build = new GradleBuild();