Commit 3dea2201 authored by Scott Frederick's avatar Scott Frederick

Use Gradle's configuration avoidance API

Register Boot Gradle tasks instead of creating them so they can be
loaded lazily.

Closes gh-18881
parent f2dadf5a
......@@ -24,6 +24,7 @@ import org.gradle.api.plugins.BasePlugin;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.TaskProvider;
import org.gradle.jvm.tasks.Jar;
import org.springframework.boot.gradle.tasks.buildinfo.BuildInfo;
......@@ -33,6 +34,7 @@ import org.springframework.boot.gradle.tasks.buildinfo.BuildInfoProperties;
* Entry point to Spring Boot's Gradle DSL.
*
* @author Andy Wilkinson
* @author Scott Frederick
* @since 2.0.0
*/
public class SpringBootExtension {
......@@ -89,22 +91,24 @@ public class SpringBootExtension {
* @param configurer the task configurer
*/
public void buildInfo(Action<BuildInfo> configurer) {
BuildInfo bootBuildInfo = this.project.getTasks().create("bootBuildInfo", BuildInfo.class);
bootBuildInfo.setGroup(BasePlugin.BUILD_GROUP);
bootBuildInfo.setDescription("Generates a META-INF/build-info.properties file.");
TaskProvider<BuildInfo> bootBuildInfo = this.project.getTasks().register("bootBuildInfo", BuildInfo.class,
(task) -> {
task.setGroup(BasePlugin.BUILD_GROUP);
task.setDescription("Generates a META-INF/build-info.properties file.");
task.getConventionMapping().map("destinationDir",
() -> new File(determineMainSourceSetResourcesOutputDir(), "META-INF"));
});
this.project.getPlugins().withType(JavaPlugin.class, (plugin) -> {
this.project.getTasks().getByName(JavaPlugin.CLASSES_TASK_NAME).dependsOn(bootBuildInfo);
this.project.getTasks().getByName(JavaPlugin.CLASSES_TASK_NAME).dependsOn(bootBuildInfo.get());
this.project.afterEvaluate((evaluated) -> {
BuildInfoProperties properties = bootBuildInfo.getProperties();
BuildInfoProperties properties = bootBuildInfo.get().getProperties();
if (properties.getArtifact() == null) {
properties.setArtifact(determineArtifactBaseName());
}
});
bootBuildInfo.getConventionMapping().map("destinationDir",
() -> new File(determineMainSourceSetResourcesOutputDir(), "META-INF"));
});
if (configurer != null) {
configurer.execute(bootBuildInfo);
configurer.execute(bootBuildInfo.get());
}
}
......
......@@ -29,12 +29,13 @@ import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.file.FileCollection;
import org.gradle.api.internal.artifacts.publish.ArchivePublishArtifact;
import org.gradle.api.internal.artifacts.dsl.LazyPublishArtifact;
import org.gradle.api.plugins.ApplicationPlugin;
import org.gradle.api.plugins.BasePlugin;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.TaskProvider;
import org.gradle.api.tasks.compile.JavaCompile;
import org.springframework.boot.gradle.tasks.bundling.BootBuildImage;
......@@ -46,6 +47,7 @@ import org.springframework.util.StringUtils;
* {@link Action} that is executed in response to the {@link JavaPlugin} being applied.
*
* @author Andy Wilkinson
* @author Scott Frederick
*/
final class JavaPluginAction implements PluginApplicationAction {
......@@ -66,7 +68,7 @@ final class JavaPluginAction implements PluginApplicationAction {
public void execute(Project project) {
disableJarTask(project);
configureBuildTask(project);
BootJar bootJar = configureBootJarTask(project);
TaskProvider<BootJar> bootJar = configureBootJarTask(project);
configureBootBuildImageTask(project, bootJar);
configureArtifactPublication(bootJar);
configureBootRunTask(project);
......@@ -76,55 +78,57 @@ final class JavaPluginAction implements PluginApplicationAction {
}
private void disableJarTask(Project project) {
project.getTasks().getByName(JavaPlugin.JAR_TASK_NAME).setEnabled(false);
project.getTasks().named(JavaPlugin.JAR_TASK_NAME).configure((task) -> task.setEnabled(false));
}
private void configureBuildTask(Project project) {
project.getTasks().getByName(BasePlugin.ASSEMBLE_TASK_NAME).dependsOn(this.singlePublishedArtifact);
project.getTasks().named(BasePlugin.ASSEMBLE_TASK_NAME)
.configure((task) -> task.dependsOn(this.singlePublishedArtifact));
}
private BootJar configureBootJarTask(Project project) {
BootJar bootJar = project.getTasks().create(SpringBootPlugin.BOOT_JAR_TASK_NAME, BootJar.class);
bootJar.setDescription(
"Assembles an executable jar archive containing the main classes and their dependencies.");
bootJar.setGroup(BasePlugin.BUILD_GROUP);
SourceSet mainSourceSet = javaPluginConvention(project).getSourceSets()
.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
bootJar.classpath((Callable<FileCollection>) () -> mainSourceSet.getRuntimeClasspath());
Configuration runtimeClasspathConfiguration = project.getConfigurations()
.getByName(mainSourceSet.getRuntimeClasspathConfigurationName());
runtimeClasspathConfiguration.getIncoming().afterResolve(bootJar::resolvedDependencies);
bootJar.conventionMapping("mainClassName", new MainClassConvention(project, bootJar::getClasspath));
return bootJar;
private TaskProvider<BootJar> configureBootJarTask(Project project) {
return project.getTasks().register(SpringBootPlugin.BOOT_JAR_TASK_NAME, BootJar.class, (bootJar) -> {
bootJar.setDescription(
"Assembles an executable jar archive containing the main classes and their dependencies.");
bootJar.setGroup(BasePlugin.BUILD_GROUP);
SourceSet mainSourceSet = javaPluginConvention(project).getSourceSets()
.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
bootJar.classpath((Callable<FileCollection>) mainSourceSet::getRuntimeClasspath);
Configuration runtimeClasspathConfiguration = project.getConfigurations()
.getByName(mainSourceSet.getRuntimeClasspathConfigurationName());
runtimeClasspathConfiguration.getIncoming().afterResolve(bootJar::resolvedDependencies);
bootJar.conventionMapping("mainClassName", new MainClassConvention(project, bootJar::getClasspath));
});
}
private void configureBootBuildImageTask(Project project, BootJar bootJar) {
BootBuildImage buildImage = project.getTasks().create(SpringBootPlugin.BOOT_BUILD_IMAGE_TASK_NAME,
BootBuildImage.class);
buildImage.setDescription("Builds an OCI image of the application using the output of the bootJar task");
buildImage.setGroup(BasePlugin.BUILD_GROUP);
buildImage.getJar().set(bootJar.getArchiveFile());
buildImage.getTargetJavaVersion().set(javaPluginConvention(project).getTargetCompatibility());
private void configureBootBuildImageTask(Project project, TaskProvider<BootJar> bootJar) {
project.getTasks().register(SpringBootPlugin.BOOT_BUILD_IMAGE_TASK_NAME, BootBuildImage.class, (buildImage) -> {
buildImage.setDescription("Builds an OCI image of the application using the output of the bootJar task");
buildImage.setGroup(BasePlugin.BUILD_GROUP);
buildImage.getJar().set(bootJar.get().getArchiveFile());
buildImage.getTargetJavaVersion().set(javaPluginConvention(project).getTargetCompatibility());
});
}
private void configureArtifactPublication(BootJar bootJar) {
ArchivePublishArtifact artifact = new ArchivePublishArtifact(bootJar);
private void configureArtifactPublication(TaskProvider<BootJar> bootJar) {
LazyPublishArtifact artifact = new LazyPublishArtifact(bootJar);
this.singlePublishedArtifact.addCandidate(artifact);
}
private void configureBootRunTask(Project project) {
BootRun run = project.getTasks().create("bootRun", BootRun.class);
run.setDescription("Runs this project as a Spring Boot application.");
run.setGroup(ApplicationPlugin.APPLICATION_GROUP);
run.classpath(javaPluginConvention(project).getSourceSets().findByName(SourceSet.MAIN_SOURCE_SET_NAME)
.getRuntimeClasspath());
run.getConventionMapping().map("jvmArgs", () -> {
if (project.hasProperty("applicationDefaultJvmArgs")) {
return project.property("applicationDefaultJvmArgs");
}
return Collections.emptyList();
project.getTasks().register("bootRun", BootRun.class, (run) -> {
run.setDescription("Runs this project as a Spring Boot application.");
run.setGroup(ApplicationPlugin.APPLICATION_GROUP);
run.classpath(javaPluginConvention(project).getSourceSets().findByName(SourceSet.MAIN_SOURCE_SET_NAME)
.getRuntimeClasspath());
run.getConventionMapping().map("jvmArgs", () -> {
if (project.hasProperty("applicationDefaultJvmArgs")) {
return project.property("applicationDefaultJvmArgs");
}
return Collections.emptyList();
});
run.conventionMapping("main", new MainClassConvention(project, run::getClasspath));
});
run.conventionMapping("main", new MainClassConvention(project, run::getClasspath));
}
private JavaPluginConvention javaPluginConvention(Project project) {
......
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2020 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.
......@@ -26,6 +26,7 @@ import org.gradle.api.tasks.TaskDependency;
* published, with a war file taking precedence over a jar file.
*
* @author Andy Wilkinson
* @author Scott Frederick
*/
final class SinglePublishedArtifact implements Buildable {
......@@ -47,7 +48,7 @@ final class SinglePublishedArtifact implements Buildable {
@Override
public TaskDependency getBuildDependencies() {
return this.currentArtifact.getBuildDependencies();
return this.artifacts.getBuildDependencies();
}
}
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2020 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.
......@@ -20,9 +20,10 @@ import org.gradle.api.Action;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.internal.artifacts.publish.ArchivePublishArtifact;
import org.gradle.api.internal.artifacts.dsl.LazyPublishArtifact;
import org.gradle.api.plugins.BasePlugin;
import org.gradle.api.plugins.WarPlugin;
import org.gradle.api.tasks.TaskProvider;
import org.springframework.boot.gradle.tasks.bundling.BootWar;
......@@ -30,6 +31,7 @@ import org.springframework.boot.gradle.tasks.bundling.BootWar;
* {@link Action} that is executed in response to the {@link WarPlugin} being applied.
*
* @author Andy Wilkinson
* @author Scott Frederick
*/
class WarPluginAction implements PluginApplicationAction {
......@@ -46,19 +48,32 @@ class WarPluginAction implements PluginApplicationAction {
@Override
public void execute(Project project) {
project.getTasks().getByName(WarPlugin.WAR_TASK_NAME).setEnabled(false);
BootWar bootWar = project.getTasks().create(SpringBootPlugin.BOOT_WAR_TASK_NAME, BootWar.class);
bootWar.setGroup(BasePlugin.BUILD_GROUP);
bootWar.setDescription("Assembles an executable war archive containing webapp"
+ " content, and the main classes and their dependencies.");
bootWar.providedClasspath(providedRuntimeConfiguration(project));
ArchivePublishArtifact artifact = new ArchivePublishArtifact(bootWar);
this.singlePublishedArtifact.addCandidate(artifact);
bootWar.conventionMapping("mainClassName", new MainClassConvention(project, bootWar::getClasspath));
disableWarTask(project);
TaskProvider<BootWar> bootWar = configureBootWarTask(project);
configureArtifactPublication(bootWar);
}
private void disableWarTask(Project project) {
project.getTasks().named(WarPlugin.WAR_TASK_NAME).configure((war) -> war.setEnabled(false));
}
private TaskProvider<BootWar> configureBootWarTask(Project project) {
return project.getTasks().register(SpringBootPlugin.BOOT_WAR_TASK_NAME, BootWar.class, (bootWar) -> {
bootWar.setGroup(BasePlugin.BUILD_GROUP);
bootWar.setDescription("Assembles an executable war archive containing webapp"
+ " content, and the main classes and their dependencies.");
bootWar.providedClasspath(providedRuntimeConfiguration(project));
bootWar.conventionMapping("mainClassName", new MainClassConvention(project, bootWar::getClasspath));
});
}
private Configuration providedRuntimeConfiguration(Project project) {
return project.getConfigurations().getByName(WarPlugin.PROVIDED_RUNTIME_CONFIGURATION_NAME);
}
private void configureArtifactPublication(TaskProvider<BootWar> bootWar) {
LazyPublishArtifact artifact = new LazyPublishArtifact(bootWar);
this.singlePublishedArtifact.addCandidate(artifact);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment