16
16
17
17
package org .springframework .boot .build .autoconfigure ;
18
18
19
- import java .io .File ;
20
- import java .io .IOException ;
21
- import java .nio .file .Files ;
22
- import java .nio .file .Path ;
23
19
import java .util .Collections ;
24
- import java .util .List ;
20
+ import java .util .Map ;
25
21
26
- import com .tngtech .archunit .core .domain .JavaClass ;
27
- import com .tngtech .archunit .lang .ArchCondition ;
28
- import com .tngtech .archunit .lang .ArchRule ;
29
- import com .tngtech .archunit .lang .ConditionEvents ;
30
- import com .tngtech .archunit .lang .SimpleConditionEvent ;
31
- import com .tngtech .archunit .lang .syntax .ArchRuleDefinition ;
32
22
import org .gradle .api .Plugin ;
33
23
import org .gradle .api .Project ;
34
24
import org .gradle .api .artifacts .Configuration ;
35
25
import org .gradle .api .plugins .JavaPlugin ;
36
26
import org .gradle .api .plugins .JavaPluginExtension ;
37
- import org .gradle .api .provider .Provider ;
38
- import org .gradle .api .tasks .PathSensitivity ;
39
27
import org .gradle .api .tasks .SourceSet ;
28
+ import org .gradle .api .tasks .TaskProvider ;
40
29
41
30
import org .springframework .boot .build .DeployedPlugin ;
42
- import org .springframework .boot .build .architecture .ArchitectureCheck ;
43
31
import org .springframework .boot .build .architecture .ArchitecturePlugin ;
32
+ import org .springframework .boot .build .optional .OptionalDependenciesPlugin ;
44
33
45
34
/**
46
35
* {@link Plugin} for projects that define auto-configuration. When applied, the plugin
@@ -70,14 +59,16 @@ public class AutoConfigurationPlugin implements Plugin<Project> {
70
59
*/
71
60
public static final String AUTO_CONFIGURATION_METADATA_CONFIGURATION_NAME = "autoConfigurationMetadata" ;
72
61
73
- private static final String AUTO_CONFIGURATION_IMPORTS_PATH = "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports" ;
74
-
75
62
@ Override
76
63
public void apply (Project project ) {
77
64
project .getPlugins ().apply (DeployedPlugin .class );
78
65
project .getPlugins ().withType (JavaPlugin .class , (javaPlugin ) -> {
79
66
Configuration annotationProcessors = project .getConfigurations ()
80
67
.getByName (JavaPlugin .ANNOTATION_PROCESSOR_CONFIGURATION_NAME );
68
+ SourceSet main = project .getExtensions ()
69
+ .getByType (JavaPluginExtension .class )
70
+ .getSourceSets ()
71
+ .getByName (SourceSet .MAIN_SOURCE_SET_NAME );
81
72
annotationProcessors .getDependencies ()
82
73
.add (project .getDependencies ()
83
74
.project (Collections .singletonMap ("path" ,
@@ -87,10 +78,6 @@ public void apply(Project project) {
87
78
.project (Collections .singletonMap ("path" ,
88
79
":spring-boot-project:spring-boot-tools:spring-boot-configuration-processor" )));
89
80
project .getTasks ().register ("autoConfigurationMetadata" , AutoConfigurationMetadata .class , (task ) -> {
90
- SourceSet main = project .getExtensions ()
91
- .getByType (JavaPluginExtension .class )
92
- .getSourceSets ()
93
- .getByName (SourceSet .MAIN_SOURCE_SET_NAME );
94
81
task .setSourceSet (main );
95
82
task .dependsOn (main .getClassesTaskName ());
96
83
task .getOutputFile ()
@@ -99,74 +86,37 @@ public void apply(Project project) {
99
86
.add (AutoConfigurationPlugin .AUTO_CONFIGURATION_METADATA_CONFIGURATION_NAME , task .getOutputFile (),
100
87
(artifact ) -> artifact .builtBy (task ));
101
88
});
89
+ project .getTasks ()
90
+ .register ("checkAutoConfigurationImports" , CheckAutoConfigurationImports .class , (task ) -> {
91
+ task .setSource (main .getResources ());
92
+ task .setClasspath (main .getOutput ().getClassesDirs ());
93
+ task .setDescription ("Checks the %s file of the main source set."
94
+ .formatted (AutoConfigurationImportsTask .IMPORTS_FILE ));
95
+ });
96
+ Configuration requiredClasspath = project .getConfigurations ()
97
+ .create ("autoConfigurationRequiredClasspath" )
98
+ .extendsFrom (project .getConfigurations ().getByName (main .getImplementationConfigurationName ()),
99
+ project .getConfigurations ().getByName (main .getRuntimeOnlyConfigurationName ()));
100
+ requiredClasspath .getDependencies ()
101
+ .add (project .getDependencies ()
102
+ .project (Map .of ("path" , ":spring-boot-project:spring-boot-autoconfigure" )));
103
+ TaskProvider <CheckAutoConfigurationClasses > checkAutoConfigurationClasses = project .getTasks ()
104
+ .register ("checkAutoConfigurationClasses" , CheckAutoConfigurationClasses .class , (task ) -> {
105
+ task .setSource (main .getResources ());
106
+ task .setClasspath (main .getOutput ().getClassesDirs ());
107
+ task .setRequiredDependencies (requiredClasspath );
108
+ task .setDescription ("Checks the auto-configuration classes of the main source set." );
109
+ });
102
110
project .getPlugins ()
103
- .withType (ArchitecturePlugin .class , (plugin ) -> configureArchitecturePluginTasks (project ));
104
- });
105
- }
106
-
107
- private void configureArchitecturePluginTasks (Project project ) {
108
- project .getTasks ().configureEach ((task ) -> {
109
- if ("checkArchitectureMain" .equals (task .getName ()) && task instanceof ArchitectureCheck architectureCheck ) {
110
- configureCheckArchitectureMain (project , architectureCheck );
111
- }
111
+ .withType (OptionalDependenciesPlugin .class ,
112
+ (plugin ) -> checkAutoConfigurationClasses .configure ((check ) -> {
113
+ Configuration optionalClasspath = project .getConfigurations ()
114
+ .create ("autoConfigurationOptionalClassPath" )
115
+ .extendsFrom (project .getConfigurations ()
116
+ .getByName (OptionalDependenciesPlugin .OPTIONAL_CONFIGURATION_NAME ));
117
+ check .setOptionalDependencies (optionalClasspath );
118
+ }));
112
119
});
113
120
}
114
121
115
- private void configureCheckArchitectureMain (Project project , ArchitectureCheck architectureCheck ) {
116
- SourceSet main = project .getExtensions ()
117
- .getByType (JavaPluginExtension .class )
118
- .getSourceSets ()
119
- .getByName (SourceSet .MAIN_SOURCE_SET_NAME );
120
- File resourcesDirectory = main .getOutput ().getResourcesDir ();
121
- architectureCheck .dependsOn (main .getProcessResourcesTaskName ());
122
- architectureCheck .getInputs ()
123
- .files (resourcesDirectory )
124
- .optional ()
125
- .withPathSensitivity (PathSensitivity .RELATIVE );
126
- architectureCheck .getRules ()
127
- .add (allClassesAnnotatedWithAutoConfigurationShouldBeListedInAutoConfigurationImports (
128
- autoConfigurationImports (project , resourcesDirectory )));
129
- }
130
-
131
- private ArchRule allClassesAnnotatedWithAutoConfigurationShouldBeListedInAutoConfigurationImports (
132
- Provider <AutoConfigurationImports > imports ) {
133
- return ArchRuleDefinition .classes ()
134
- .that ()
135
- .areAnnotatedWith ("org.springframework.boot.autoconfigure.AutoConfiguration" )
136
- .should (beListedInAutoConfigurationImports (imports ))
137
- .allowEmptyShould (true );
138
- }
139
-
140
- private ArchCondition <JavaClass > beListedInAutoConfigurationImports (Provider <AutoConfigurationImports > imports ) {
141
- return new ArchCondition <>("be listed in " + AUTO_CONFIGURATION_IMPORTS_PATH ) {
142
-
143
- @ Override
144
- public void check (JavaClass item , ConditionEvents events ) {
145
- AutoConfigurationImports autoConfigurationImports = imports .get ();
146
- if (!autoConfigurationImports .imports .contains (item .getName ())) {
147
- events .add (SimpleConditionEvent .violated (item ,
148
- item .getName () + " was not listed in " + autoConfigurationImports .importsFile ));
149
- }
150
- }
151
-
152
- };
153
- }
154
-
155
- private Provider <AutoConfigurationImports > autoConfigurationImports (Project project , File resourcesDirectory ) {
156
- Path importsFile = new File (resourcesDirectory , AUTO_CONFIGURATION_IMPORTS_PATH ).toPath ();
157
- return project .provider (() -> {
158
- try {
159
- return new AutoConfigurationImports (project .getProjectDir ().toPath ().relativize (importsFile ),
160
- Files .readAllLines (importsFile ));
161
- }
162
- catch (IOException ex ) {
163
- throw new RuntimeException ("Failed to read AutoConfiguration.imports" , ex );
164
- }
165
- });
166
- }
167
-
168
- private record AutoConfigurationImports (Path importsFile , List <String > imports ) {
169
-
170
- }
171
-
172
122
}
0 commit comments