Polish AutoConfigurationPlugin
This commit is contained in:
@@ -16,19 +16,24 @@
|
||||
|
||||
package org.springframework.boot.build.autoconfigure;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.artifacts.ConfigurationContainer;
|
||||
import org.gradle.api.artifacts.Dependency;
|
||||
import org.gradle.api.plugins.JavaBasePlugin;
|
||||
import org.gradle.api.plugins.JavaPlugin;
|
||||
import org.gradle.api.plugins.JavaPluginExtension;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.gradle.api.tasks.TaskContainer;
|
||||
import org.gradle.api.tasks.TaskProvider;
|
||||
|
||||
import org.springframework.boot.build.DeployedPlugin;
|
||||
import org.springframework.boot.build.architecture.ArchitecturePlugin;
|
||||
import org.springframework.boot.build.optional.OptionalDependenciesPlugin;
|
||||
|
||||
/**
|
||||
@@ -41,12 +46,7 @@ import org.springframework.boot.build.optional.OptionalDependenciesPlugin;
|
||||
* <li>Defines a task that produces metadata describing the auto-configuration. The
|
||||
* metadata is made available as an artifact in the {@code autoConfigurationMetadata}
|
||||
* configuration.
|
||||
* <li>Reacts to the {@link ArchitecturePlugin} being applied and:
|
||||
* <ul>
|
||||
* <li>Adds a rule to the {@code checkArchitectureMain} task to verify that all
|
||||
* {@code AutoConfiguration} classes are listed in the {@code AutoConfiguration.imports}
|
||||
* file.
|
||||
* </ul>
|
||||
* <li>Add checks to ensure import files and annotations are correct</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
@@ -62,61 +62,101 @@ public class AutoConfigurationPlugin implements Plugin<Project> {
|
||||
@Override
|
||||
public void apply(Project project) {
|
||||
project.getPlugins().apply(DeployedPlugin.class);
|
||||
project.getPlugins().withType(JavaPlugin.class, (javaPlugin) -> {
|
||||
Configuration annotationProcessors = project.getConfigurations()
|
||||
.getByName(JavaPlugin.ANNOTATION_PROCESSOR_CONFIGURATION_NAME);
|
||||
SourceSet main = project.getExtensions()
|
||||
project.getPlugins().withType(JavaPlugin.class, (javaPlugin) -> new Configurer(project).configure());
|
||||
}
|
||||
|
||||
private static class Configurer {
|
||||
|
||||
private final Project project;
|
||||
|
||||
private SourceSet main;
|
||||
|
||||
Configurer(Project project) {
|
||||
this.project = project;
|
||||
this.main = project.getExtensions()
|
||||
.getByType(JavaPluginExtension.class)
|
||||
.getSourceSets()
|
||||
.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
|
||||
annotationProcessors.getDependencies()
|
||||
.add(project.getDependencies()
|
||||
.project(Collections.singletonMap("path",
|
||||
":spring-boot-project:spring-boot-tools:spring-boot-autoconfigure-processor")));
|
||||
annotationProcessors.getDependencies()
|
||||
.add(project.getDependencies()
|
||||
.project(Collections.singletonMap("path",
|
||||
":spring-boot-project:spring-boot-tools:spring-boot-configuration-processor")));
|
||||
project.getTasks().register("autoConfigurationMetadata", AutoConfigurationMetadata.class, (task) -> {
|
||||
task.setSourceSet(main);
|
||||
task.dependsOn(main.getClassesTaskName());
|
||||
task.getOutputFile()
|
||||
.set(project.getLayout().getBuildDirectory().file("auto-configuration-metadata.properties"));
|
||||
project.getArtifacts()
|
||||
.add(AutoConfigurationPlugin.AUTO_CONFIGURATION_METADATA_CONFIGURATION_NAME, task.getOutputFile(),
|
||||
(artifact) -> artifact.builtBy(task));
|
||||
});
|
||||
project.getTasks()
|
||||
.register("checkAutoConfigurationImports", CheckAutoConfigurationImports.class, (task) -> {
|
||||
task.setSource(main.getResources());
|
||||
task.setClasspath(main.getOutput().getClassesDirs());
|
||||
task.setDescription("Checks the %s file of the main source set."
|
||||
.formatted(AutoConfigurationImportsTask.IMPORTS_FILE));
|
||||
});
|
||||
Configuration requiredClasspath = project.getConfigurations()
|
||||
.create("autoConfigurationRequiredClasspath")
|
||||
.extendsFrom(project.getConfigurations().getByName(main.getImplementationConfigurationName()),
|
||||
project.getConfigurations().getByName(main.getRuntimeOnlyConfigurationName()));
|
||||
}
|
||||
|
||||
void configure() {
|
||||
addAnnotationProcessorsDependencies();
|
||||
TaskContainer tasks = this.project.getTasks();
|
||||
ConfigurationContainer configurations = this.project.getConfigurations();
|
||||
tasks.register("autoConfigurationMetadata", AutoConfigurationMetadata.class,
|
||||
this::configureAutoConfigurationMetadata);
|
||||
TaskProvider<CheckAutoConfigurationImports> checkAutoConfigurationImports = tasks.register(
|
||||
"checkAutoConfigurationImports", CheckAutoConfigurationImports.class,
|
||||
this::configureCheckAutoConfigurationImports);
|
||||
Configuration requiredClasspath = configurations.create("autoConfigurationRequiredClasspath")
|
||||
.extendsFrom(configurations.getByName(this.main.getImplementationConfigurationName()),
|
||||
configurations.getByName(this.main.getRuntimeOnlyConfigurationName()));
|
||||
requiredClasspath.getDependencies()
|
||||
.add(project.getDependencies()
|
||||
.project(Map.of("path", ":spring-boot-project:spring-boot-autoconfigure")));
|
||||
TaskProvider<CheckAutoConfigurationClasses> checkAutoConfigurationClasses = project.getTasks()
|
||||
.register("checkAutoConfigurationClasses", CheckAutoConfigurationClasses.class, (task) -> {
|
||||
task.setSource(main.getResources());
|
||||
task.setClasspath(main.getOutput().getClassesDirs());
|
||||
task.setRequiredDependencies(requiredClasspath);
|
||||
task.setDescription("Checks the auto-configuration classes of the main source set.");
|
||||
});
|
||||
project.getPlugins()
|
||||
.add(projectDependency(":spring-boot-project:spring-boot-autoconfigure"));
|
||||
TaskProvider<CheckAutoConfigurationClasses> checkAutoConfigurationClasses = tasks.register(
|
||||
"checkAutoConfigurationClasses", CheckAutoConfigurationClasses.class,
|
||||
(task) -> configureCheckAutoConfigurationClasses(requiredClasspath, task));
|
||||
this.project.getPlugins()
|
||||
.withType(OptionalDependenciesPlugin.class,
|
||||
(plugin) -> checkAutoConfigurationClasses.configure((check) -> {
|
||||
Configuration optionalClasspath = project.getConfigurations()
|
||||
.create("autoConfigurationOptionalClassPath")
|
||||
.extendsFrom(project.getConfigurations()
|
||||
.getByName(OptionalDependenciesPlugin.OPTIONAL_CONFIGURATION_NAME));
|
||||
check.setOptionalDependencies(optionalClasspath);
|
||||
}));
|
||||
});
|
||||
(plugin) -> configureCheckAutoConfigurationClassesForOptionalDependencies(configurations,
|
||||
checkAutoConfigurationClasses));
|
||||
this.project.getTasks()
|
||||
.getByName(JavaBasePlugin.CHECK_TASK_NAME)
|
||||
.dependsOn(checkAutoConfigurationImports, checkAutoConfigurationClasses);
|
||||
}
|
||||
|
||||
private void addAnnotationProcessorsDependencies() {
|
||||
this.project.getConfigurations()
|
||||
.getByName(JavaPlugin.ANNOTATION_PROCESSOR_CONFIGURATION_NAME)
|
||||
.getDependencies()
|
||||
.addAll(projectDependencies(
|
||||
":spring-boot-project:spring-boot-tools:spring-boot-autoconfigure-processor",
|
||||
":spring-boot-project:spring-boot-tools:spring-boot-configuration-processor"));
|
||||
}
|
||||
|
||||
private void configureAutoConfigurationMetadata(AutoConfigurationMetadata task) {
|
||||
task.setSourceSet(this.main);
|
||||
task.dependsOn(this.main.getClassesTaskName());
|
||||
task.getOutputFile()
|
||||
.set(this.project.getLayout().getBuildDirectory().file("auto-configuration-metadata.properties"));
|
||||
this.project.getArtifacts()
|
||||
.add(AutoConfigurationPlugin.AUTO_CONFIGURATION_METADATA_CONFIGURATION_NAME, task.getOutputFile(),
|
||||
(artifact) -> artifact.builtBy(task));
|
||||
}
|
||||
|
||||
private void configureCheckAutoConfigurationImports(CheckAutoConfigurationImports task) {
|
||||
task.setSource(this.main.getResources());
|
||||
task.setClasspath(this.main.getOutput().getClassesDirs());
|
||||
task.setDescription(
|
||||
"Checks the %s file of the main source set.".formatted(AutoConfigurationImportsTask.IMPORTS_FILE));
|
||||
}
|
||||
|
||||
private void configureCheckAutoConfigurationClasses(Configuration requiredClasspath,
|
||||
CheckAutoConfigurationClasses task) {
|
||||
task.setSource(this.main.getResources());
|
||||
task.setClasspath(this.main.getOutput().getClassesDirs());
|
||||
task.setRequiredDependencies(requiredClasspath);
|
||||
task.setDescription("Checks the auto-configuration classes of the main source set.");
|
||||
}
|
||||
|
||||
private void configureCheckAutoConfigurationClassesForOptionalDependencies(
|
||||
ConfigurationContainer configurations,
|
||||
TaskProvider<CheckAutoConfigurationClasses> checkAutoConfigurationClasses) {
|
||||
checkAutoConfigurationClasses.configure((check) -> {
|
||||
Configuration optionalClasspath = configurations.create("autoConfigurationOptionalClassPath")
|
||||
.extendsFrom(configurations.getByName(OptionalDependenciesPlugin.OPTIONAL_CONFIGURATION_NAME));
|
||||
check.setOptionalDependencies(optionalClasspath);
|
||||
});
|
||||
}
|
||||
|
||||
private Set<Dependency> projectDependencies(String... paths) {
|
||||
return Arrays.stream(paths).map((path) -> projectDependency(path)).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
private Dependency projectDependency(String path) {
|
||||
return this.project.getDependencies().project(Collections.singletonMap("path", path));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -80,14 +80,12 @@ public abstract class DocumentAutoConfigurationClasses extends DefaultTask {
|
||||
writer.println("[cols=\"4,1\"]");
|
||||
writer.println("|===");
|
||||
writer.println("| Configuration Class | Links");
|
||||
|
||||
for (AutoConfigurationClass autoConfigurationClass : autoConfigurationClasses.classes) {
|
||||
writer.println();
|
||||
writer.printf("| {code-spring-boot}/spring-boot-project/%s/src/main/java/%s.java[`%s`]%n",
|
||||
autoConfigurationClasses.module, autoConfigurationClass.path, autoConfigurationClass.name);
|
||||
writer.printf("| xref:api:java/%s.html[javadoc]%n", autoConfigurationClass.path);
|
||||
}
|
||||
|
||||
writer.println("|===");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user