Merge branch '2.3.x'

Closes gh-21649
This commit is contained in:
Phillip Webb 2020-06-01 21:21:20 -07:00
commit ac9482d463

View File

@ -22,11 +22,13 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Arrays; import java.util.Arrays;
import io.spring.javaformat.formatter.FileEdit;
import io.spring.javaformat.formatter.FileFormatter; import io.spring.javaformat.formatter.FileFormatter;
import org.gradle.api.DefaultTask; import org.gradle.api.DefaultTask;
import org.gradle.api.Plugin; import org.gradle.api.Plugin;
import org.gradle.api.Project; import org.gradle.api.Project;
import org.gradle.api.Task; import org.gradle.api.Task;
import org.gradle.api.file.CopySpec;
import org.gradle.api.plugins.JavaLibraryPlugin; import org.gradle.api.plugins.JavaLibraryPlugin;
import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginConvention; import org.gradle.api.plugins.JavaPluginConvention;
@ -52,6 +54,7 @@ import org.springframework.boot.build.test.IntegrationTestPlugin;
* Plugin for building Spring Boot's Maven Plugin. * Plugin for building Spring Boot's Maven Plugin.
* *
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Phillip Webb
*/ */
public class MavenPluginPlugin implements Plugin<Project> { public class MavenPluginPlugin implements Plugin<Project> {
@ -62,113 +65,150 @@ public class MavenPluginPlugin implements Plugin<Project> {
project.getPlugins().apply(DeployedPlugin.class); project.getPlugins().apply(DeployedPlugin.class);
project.getPlugins().apply(MavenRepositoryPlugin.class); project.getPlugins().apply(MavenRepositoryPlugin.class);
project.getPlugins().apply(IntegrationTestPlugin.class); project.getPlugins().apply(IntegrationTestPlugin.class);
Copy populateIntTestMavenRepository = project.getTasks().create("populateIntTestMavenRepository", Copy.class); Jar jarTask = (Jar) project.getTasks().getByName(JavaPlugin.JAR_TASK_NAME);
populateIntTestMavenRepository.setDestinationDir(project.getBuildDir());
populateIntTestMavenRepository.into("int-test-maven-repository", (copy) -> {
copy.from(project.getConfigurations().getByName(MavenRepositoryPlugin.MAVEN_REPOSITORY_CONFIGURATION_NAME));
copy.from(new File(project.getBuildDir(), "maven-repository"));
});
populateIntTestMavenRepository
.dependsOn(project.getTasks().getByName(MavenRepositoryPlugin.PUBLISH_TO_PROJECT_REPOSITORY_TASK_NAME));
configurePomPackaging(project); configurePomPackaging(project);
MavenExec generateHelpMojo = configureMojoGenerationTasks(project); addPopulateIntTestMavenRepositoryTask(project);
MavenExec generatePluginDescriptor = configurePluginDescriptorGenerationTasks(project, generateHelpMojo); MavenExec generateHelpMojoTask = addGenerateHelpMojoTask(project, jarTask);
DocumentPluginGoals documentPluginGoals = project.getTasks().create("documentPluginGoals", MavenExec generatePluginDescriptorTask = addGeneratePluginDescriptorTask(project, jarTask,
DocumentPluginGoals.class); generateHelpMojoTask);
documentPluginGoals.setPluginXml(generatePluginDescriptor.getOutputs().getFiles().getSingleFile()); addDocumentPluginGoalsTask(project, generatePluginDescriptorTask);
documentPluginGoals.setOutputDir(new File(project.getBuildDir(), "docs/generated/goals/")); addPrepareMavenBinariesTask(project);
documentPluginGoals.dependsOn(generatePluginDescriptor);
Jar jar = (Jar) project.getTasks().getByName(JavaPlugin.JAR_TASK_NAME);
includeDescriptorInJar(jar, generatePluginDescriptor);
includeHelpMojoInJar(jar, generateHelpMojo);
PrepareMavenBinaries prepareMavenBinaries = project.getTasks().create("prepareMavenBinaries",
PrepareMavenBinaries.class);
prepareMavenBinaries.setOutputDir(new File(project.getBuildDir(), "maven-binaries"));
project.getTasks().getByName(IntegrationTestPlugin.INT_TEST_TASK_NAME).dependsOn(populateIntTestMavenRepository,
prepareMavenBinaries);
} }
private void configurePomPackaging(Project project) { private void configurePomPackaging(Project project) {
PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class); PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class);
publishing.getPublications().withType(MavenPublication.class, publishing.getPublications().withType(MavenPublication.class, this::setPackaging);
(mavenPublication) -> mavenPublication.pom((pom) -> pom.setPackaging("maven-plugin")));
} }
private MavenExec configureMojoGenerationTasks(Project project) { private void setPackaging(MavenPublication mavenPublication) {
mavenPublication.pom((pom) -> pom.setPackaging("maven-plugin"));
}
private void addPopulateIntTestMavenRepositoryTask(Project project) {
Copy task = project.getTasks().create("populateIntTestMavenRepository", Copy.class);
task.setDestinationDir(project.getBuildDir());
task.into("int-test-maven-repository", (copy) -> copyIntTestMavenRepositoryFiles(project, copy));
task.dependsOn(project.getTasks().getByName(MavenRepositoryPlugin.PUBLISH_TO_PROJECT_REPOSITORY_TASK_NAME));
project.getTasks().getByName(IntegrationTestPlugin.INT_TEST_TASK_NAME).dependsOn(task);
}
private void copyIntTestMavenRepositoryFiles(Project project, CopySpec copy) {
copy.from(project.getConfigurations().getByName(MavenRepositoryPlugin.MAVEN_REPOSITORY_CONFIGURATION_NAME));
copy.from(new File(project.getBuildDir(), "maven-repository"));
}
private void addDocumentPluginGoalsTask(Project project, MavenExec generatePluginDescriptorTask) {
DocumentPluginGoals task = project.getTasks().create("documentPluginGoals", DocumentPluginGoals.class);
File pluginXml = new File(generatePluginDescriptorTask.getOutputs().getFiles().getSingleFile(), "plugin.xml");
task.setPluginXml(pluginXml);
task.setOutputDir(new File(project.getBuildDir(), "docs/generated/goals/"));
task.dependsOn(generatePluginDescriptorTask);
}
private MavenExec addGenerateHelpMojoTask(Project project, Jar jarTask) {
File helpMojoDir = new File(project.getBuildDir(), "help-mojo"); File helpMojoDir = new File(project.getBuildDir(), "help-mojo");
Copy helpMojoInputs = createCopyHelpMojoInputs(project, helpMojoDir); MavenExec task = createGenerateHelpMojoTask(project, helpMojoDir);
MavenExec generateHelpMojo = createGenerateHelpMojo(project, helpMojoDir); task.dependsOn(createCopyHelpMojoInputsTask(project, helpMojoDir));
generateHelpMojo.dependsOn(helpMojoInputs); includeHelpMojoInJar(jarTask, task);
return generateHelpMojo; return task;
} }
private Copy createCopyHelpMojoInputs(Project project, File mavenDir) { private MavenExec createGenerateHelpMojoTask(Project project, File helpMojoDir) {
Copy mojoInputs = project.getTasks().create("copyHelpMojoInputs", Copy.class); MavenExec task = project.getTasks().create("generateHelpMojo", MavenExec.class);
mojoInputs.setDestinationDir(mavenDir); task.setProjectDir(helpMojoDir);
mojoInputs.from(new File(project.getProjectDir(), "src/maven/resources/pom.xml"), task.args("org.apache.maven.plugins:maven-plugin-plugin:3.6.0:helpmojo");
(sync) -> sync.filter((input) -> input.replace("{{version}}", project.getVersion().toString()))); task.getOutputs().dir(new File(helpMojoDir, "target/generated-sources/plugin"));
return mojoInputs; return task;
} }
private MavenExec createGenerateHelpMojo(Project project, File mavenDir) { private Copy createCopyHelpMojoInputsTask(Project project, File helpMojoDir) {
MavenExec generateHelpMojo = project.getTasks().create("generateHelpMojo", MavenExec.class); Copy task = project.getTasks().create("copyHelpMojoInputs", Copy.class);
generateHelpMojo.setProjectDir(mavenDir); task.setDestinationDir(helpMojoDir);
generateHelpMojo.args("org.apache.maven.plugins:maven-plugin-plugin:3.6.0:helpmojo"); File pomFile = new File(project.getProjectDir(), "src/maven/resources/pom.xml");
generateHelpMojo.getOutputs().dir(new File(mavenDir, "target/generated-sources/plugin")); task.from(pomFile, (copy) -> replaceVersionPlaceholder(copy, project));
return generateHelpMojo; return task;
} }
private MavenExec configurePluginDescriptorGenerationTasks(Project project, MavenExec generateHelpMojo) { private void includeHelpMojoInJar(Jar jarTask, JavaExec generateHelpMojoTask) {
jarTask.from(generateHelpMojoTask).exclude("**/*.java");
jarTask.dependsOn(generateHelpMojoTask);
}
private MavenExec addGeneratePluginDescriptorTask(Project project, Jar jarTask, MavenExec generateHelpMojoTask) {
File pluginDescriptorDir = new File(project.getBuildDir(), "plugin-descriptor"); File pluginDescriptorDir = new File(project.getBuildDir(), "plugin-descriptor");
SourceSetContainer sourceSets = project.getConvention().getPlugin(JavaPluginConvention.class).getSourceSets();
SourceSet mainSourceSet = sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
File generatedHelpMojoDir = new File(project.getBuildDir(), "generated/sources/helpMojo"); File generatedHelpMojoDir = new File(project.getBuildDir(), "generated/sources/helpMojo");
project.getTasks().withType(Javadoc.class, SourceSet mainSourceSet = getMainSourceSet(project);
(javadoc) -> ((StandardJavadocDocletOptions) javadoc.getOptions()).addMultilineStringsOption("tag") project.getTasks().withType(Javadoc.class, this::setJavadocOptions);
.setValue(Arrays.asList("goal:X", "requiresProject:X", "threadSafe:X"))); FormatHelpMojoSourceTask copyFormattedHelpMojoSourceTask = createCopyFormattedHelpMojoSourceTask(project,
FormatHelpMojoSource copyFormattedHelpMojoSource = project.getTasks().create("copyFormattedHelpMojoSource", generateHelpMojoTask, generatedHelpMojoDir);
FormatHelpMojoSource.class); project.getTasks().getByName(mainSourceSet.getCompileJavaTaskName()).dependsOn(copyFormattedHelpMojoSourceTask);
copyFormattedHelpMojoSource.setGenerator(generateHelpMojo); mainSourceSet.java((javaSources) -> javaSources.srcDir(generatedHelpMojoDir));
copyFormattedHelpMojoSource.setOutputDir(generatedHelpMojoDir);
mainSourceSet.getAllJava().srcDir(generatedHelpMojoDir);
project.getTasks().getByName(mainSourceSet.getCompileJavaTaskName()).dependsOn(copyFormattedHelpMojoSource);
Copy pluginDescriptorInputs = createCopyPluginDescriptorInputs(project, pluginDescriptorDir, mainSourceSet); Copy pluginDescriptorInputs = createCopyPluginDescriptorInputs(project, pluginDescriptorDir, mainSourceSet);
pluginDescriptorInputs.dependsOn(mainSourceSet.getClassesTaskName()); pluginDescriptorInputs.dependsOn(mainSourceSet.getClassesTaskName());
MavenExec generatePluginDescriptor = createGeneratePluginDescriptor(project, pluginDescriptorDir); MavenExec task = createGeneratePluginDescriptorTask(project, pluginDescriptorDir);
generatePluginDescriptor.dependsOn(pluginDescriptorInputs); task.dependsOn(pluginDescriptorInputs);
return generatePluginDescriptor; includeDescriptorInJar(jarTask, task);
return task;
}
private SourceSet getMainSourceSet(Project project) {
SourceSetContainer sourceSets = project.getConvention().getPlugin(JavaPluginConvention.class).getSourceSets();
return sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
}
private void setJavadocOptions(Javadoc javadoc) {
StandardJavadocDocletOptions options = (StandardJavadocDocletOptions) javadoc.getOptions();
options.addMultilineStringsOption("tag").setValue(Arrays.asList("goal:X", "requiresProject:X", "threadSafe:X"));
}
private FormatHelpMojoSourceTask createCopyFormattedHelpMojoSourceTask(Project project,
MavenExec generateHelpMojoTask, File generatedHelpMojoDir) {
FormatHelpMojoSourceTask copyFormattedHelpMojoSourceTask = project.getTasks()
.create("copyFormattedHelpMojoSource", FormatHelpMojoSourceTask.class);
copyFormattedHelpMojoSourceTask.setGenerator(generateHelpMojoTask);
copyFormattedHelpMojoSourceTask.setOutputDir(generatedHelpMojoDir);
return copyFormattedHelpMojoSourceTask;
} }
private Copy createCopyPluginDescriptorInputs(Project project, File destination, SourceSet sourceSet) { private Copy createCopyPluginDescriptorInputs(Project project, File destination, SourceSet sourceSet) {
Copy pluginDescriptorInputs = project.getTasks().create("copyPluginDescriptorInputs", Copy.class); Copy pluginDescriptorInputs = project.getTasks().create("copyPluginDescriptorInputs", Copy.class);
pluginDescriptorInputs.setDestinationDir(destination); pluginDescriptorInputs.setDestinationDir(destination);
pluginDescriptorInputs.from(new File(project.getProjectDir(), "src/maven/resources/pom.xml"), File pomFile = new File(project.getProjectDir(), "src/maven/resources/pom.xml");
(sync) -> sync.filter((input) -> input.replace("{{version}}", project.getVersion().toString()))); pluginDescriptorInputs.from(pomFile, (copy) -> replaceVersionPlaceholder(copy, project));
pluginDescriptorInputs.from(sourceSet.getOutput().getClassesDirs(), (sync) -> sync.into("target/classes")); pluginDescriptorInputs.from(sourceSet.getOutput().getClassesDirs(), (sync) -> sync.into("target/classes"));
pluginDescriptorInputs.from(sourceSet.getAllJava().getSrcDirs(), (sync) -> sync.into("src/main/java")); pluginDescriptorInputs.from(sourceSet.getAllJava().getSrcDirs(), (sync) -> sync.into("src/main/java"));
return pluginDescriptorInputs; return pluginDescriptorInputs;
} }
private MavenExec createGeneratePluginDescriptor(Project project, File mavenDir) { private MavenExec createGeneratePluginDescriptorTask(Project project, File mavenDir) {
MavenExec generatePluginDescriptor = project.getTasks().create("generatePluginDescriptor", MavenExec.class); MavenExec generatePluginDescriptor = project.getTasks().create("generatePluginDescriptor", MavenExec.class);
generatePluginDescriptor.args("org.apache.maven.plugins:maven-plugin-plugin:3.6.0:descriptor"); generatePluginDescriptor.args("org.apache.maven.plugins:maven-plugin-plugin:3.6.0:descriptor");
generatePluginDescriptor.getOutputs().file(new File(mavenDir, "target/classes/META-INF/maven/plugin.xml")); generatePluginDescriptor.getOutputs().dir(new File(mavenDir, "target/classes/META-INF/maven"));
generatePluginDescriptor.getInputs().dir(new File(mavenDir, "target/classes/org")); generatePluginDescriptor.getInputs().dir(new File(mavenDir, "target/classes/org"));
generatePluginDescriptor.setProjectDir(mavenDir); generatePluginDescriptor.setProjectDir(mavenDir);
return generatePluginDescriptor; return generatePluginDescriptor;
} }
private void includeDescriptorInJar(Jar jar, JavaExec generatePluginDescriptor) { private void includeDescriptorInJar(Jar jar, JavaExec generatePluginDescriptorTask) {
jar.from(generatePluginDescriptor, (copy) -> copy.into("META-INF/maven/")); jar.from(generatePluginDescriptorTask, (copy) -> copy.into("META-INF/maven/"));
jar.dependsOn(generatePluginDescriptor); jar.dependsOn(generatePluginDescriptorTask);
} }
private void includeHelpMojoInJar(Jar jar, JavaExec generateHelpMojo) { private void addPrepareMavenBinariesTask(Project project) {
jar.from(generateHelpMojo); PrepareMavenBinaries task = project.getTasks().create("prepareMavenBinaries", PrepareMavenBinaries.class);
jar.dependsOn(generateHelpMojo); task.setOutputDir(new File(project.getBuildDir(), "maven-binaries"));
project.getTasks().getByName(IntegrationTestPlugin.INT_TEST_TASK_NAME).dependsOn(task);
} }
public static class FormatHelpMojoSource extends DefaultTask { private void replaceVersionPlaceholder(CopySpec copy, Project project) {
copy.filter((input) -> replaceVersionPlaceholder(project, input));
}
private String replaceVersionPlaceholder(Project project, String input) {
return input.replace("{{version}}", project.getVersion().toString());
}
public static class FormatHelpMojoSourceTask extends DefaultTask {
private Task generator; private Task generator;
@ -190,19 +230,22 @@ public class MavenPluginPlugin implements Plugin<Project> {
@TaskAction @TaskAction
void syncAndFormat() { void syncAndFormat() {
FileFormatter fileFormatter = new FileFormatter(); FileFormatter formatter = new FileFormatter();
for (File output : this.generator.getOutputs().getFiles()) { for (File output : this.generator.getOutputs().getFiles()) {
fileFormatter.formatFiles(getProject().fileTree(output), StandardCharsets.UTF_8).forEach((fileEdit) -> { formatter.formatFiles(getProject().fileTree(output), StandardCharsets.UTF_8)
Path relativePath = output.toPath().relativize(fileEdit.getFile().toPath()); .forEach((edit) -> save(output, edit));
Path outputLocation = this.outputDir.toPath().resolve(relativePath); }
try { }
Files.createDirectories(outputLocation.getParent());
Files.write(outputLocation, fileEdit.getFormattedContent().getBytes(StandardCharsets.UTF_8)); private void save(File output, FileEdit edit) {
} Path relativePath = output.toPath().relativize(edit.getFile().toPath());
catch (Exception ex) { Path outputLocation = this.outputDir.toPath().resolve(relativePath);
throw new TaskExecutionException(this, ex); try {
} Files.createDirectories(outputLocation.getParent());
}); Files.write(outputLocation, edit.getFormattedContent().getBytes(StandardCharsets.UTF_8));
}
catch (Exception ex) {
throw new TaskExecutionException(this, ex);
} }
} }