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