Skip to content

Commit fa81e8c

Browse files
committed
Skip processAot and processTestAot if there is no main or test code
Closes gh-32424
1 parent 64f4da8 commit fa81e8c

File tree

6 files changed

+88
-41
lines changed

6 files changed

+88
-41
lines changed

spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/SpringBootAotPlugin.java

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -71,18 +71,21 @@ public void apply(Project project) {
7171
PluginContainer plugins = project.getPlugins();
7272
plugins.withType(JavaPlugin.class).all((javaPlugin) -> {
7373
plugins.withType(SpringBootPlugin.class).all((bootPlugin) -> {
74-
SourceSet aotSourceSet = configureSourceSet(project, "aot", SourceSet.MAIN_SOURCE_SET_NAME);
75-
registerProcessAotTask(project, aotSourceSet);
76-
SourceSet aotTestSourceSet = configureSourceSet(project, "aotTest", SourceSet.TEST_SOURCE_SET_NAME);
77-
registerProcessTestAotTask(project, aotTestSourceSet);
74+
JavaPluginExtension javaPluginExtension = project.getExtensions().getByType(JavaPluginExtension.class);
75+
SourceSetContainer sourceSets = javaPluginExtension.getSourceSets();
76+
SourceSet mainSourceSet = sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
77+
SourceSet aotSourceSet = configureSourceSet(project, "aot", mainSourceSet);
78+
registerProcessAotTask(project, aotSourceSet, mainSourceSet);
79+
SourceSet testSourceSet = sourceSets.getByName(SourceSet.TEST_SOURCE_SET_NAME);
80+
SourceSet aotTestSourceSet = configureSourceSet(project, "aotTest", testSourceSet);
81+
registerProcessTestAotTask(project, aotTestSourceSet, testSourceSet);
7882
});
7983
});
8084
}
8185

82-
private SourceSet configureSourceSet(Project project, String newSourceSetName, String existingSourceSetName) {
86+
private SourceSet configureSourceSet(Project project, String newSourceSetName, SourceSet existingSourceSet) {
8387
JavaPluginExtension javaPluginExtension = project.getExtensions().getByType(JavaPluginExtension.class);
8488
SourceSetContainer sourceSets = javaPluginExtension.getSourceSets();
85-
SourceSet existingSourceSet = sourceSets.getByName(existingSourceSetName);
8689
return sourceSets.create(newSourceSetName, (sourceSet) -> {
8790
sourceSet.getJava().setSrcDirs(List.of("build/generated/" + newSourceSetName + "Sources"));
8891
sourceSet.getResources().setSrcDirs(List.of("build/generated/" + newSourceSetName + "Resources"));
@@ -112,13 +115,13 @@ private void configureJavaRuntimeUsageAttribute(Project project, AttributeContai
112115
attributes.attribute(Usage.USAGE_ATTRIBUTE, javaRuntime);
113116
}
114117

115-
private void registerProcessAotTask(Project project, SourceSet aotSourceSet) {
118+
private void registerProcessAotTask(Project project, SourceSet aotSourceSet, SourceSet mainSourceSet) {
116119
TaskProvider<ResolveMainClassName> resolveMainClassName = project.getTasks()
117120
.named(SpringBootPlugin.RESOLVE_MAIN_CLASS_NAME_TASK_NAME, ResolveMainClassName.class);
118121
Provider<Directory> aotClasses = project.getLayout().getBuildDirectory().dir("generated/aotClasses");
119122
TaskProvider<ProcessAot> processAot = project.getTasks().register(PROCESS_AOT_TASK_NAME, ProcessAot.class,
120123
(task) -> {
121-
configureAotTask(project, aotSourceSet, task, aotClasses);
124+
configureAotTask(project, aotSourceSet, task, aotClasses, mainSourceSet);
122125
task.getApplicationClass()
123126
.set(resolveMainClassName.flatMap(ResolveMainClassName::readMainClassName));
124127
});
@@ -128,13 +131,14 @@ private void registerProcessAotTask(Project project, SourceSet aotSourceSet) {
128131
}
129132

130133
private void configureAotTask(Project project, SourceSet sourceSet, AbstractAot task,
131-
Provider<Directory> generatedClasses) {
134+
Provider<Directory> generatedClasses, SourceSet inputSourceSet) {
132135
task.setClasspath(sourceSet.getCompileClasspath());
133-
task.getSourcesDir().set(sourceSet.getJava().getSrcDirs().iterator().next());
134-
task.getResourcesDir().set(sourceSet.getResources().getSrcDirs().iterator().next());
135-
task.getClassesDir().set(generatedClasses);
136+
task.getSourcesOutput().set(sourceSet.getJava().getSrcDirs().iterator().next());
137+
task.getResourcesOutput().set(sourceSet.getResources().getSrcDirs().iterator().next());
138+
task.getClassesOutput().set(generatedClasses);
136139
task.getGroupId().set(project.provider(() -> String.valueOf(project.getGroup())));
137140
task.getArtifactId().set(project.provider(() -> project.getName()));
141+
task.setInputClasses(inputSourceSet.getOutput().getClassesDirs());
138142
}
139143

140144
private void configureDependsOn(Project project, SourceSet aotSourceSet,
@@ -145,15 +149,13 @@ private void configureDependsOn(Project project, SourceSet aotSourceSet,
145149
.configure((processResources) -> processResources.dependsOn(processAot));
146150
}
147151

148-
private void registerProcessTestAotTask(Project project, SourceSet aotTestSourceSet) {
149-
JavaPluginExtension javaPluginExtension = project.getExtensions().getByType(JavaPluginExtension.class);
150-
SourceSetContainer sourceSets = javaPluginExtension.getSourceSets();
151-
SourceSet testSourceSet = sourceSets.getByName(SourceSet.TEST_SOURCE_SET_NAME);
152+
private void registerProcessTestAotTask(Project project, SourceSet aotTestSourceSet, SourceSet testSourceSet) {
152153
Provider<Directory> aotTestClasses = project.getLayout().getBuildDirectory().dir("generated/aotTestClasses");
153154
TaskProvider<ProcessTestAot> processTestAot = project.getTasks().register(PROCESS_TEST_AOT_TASK_NAME,
154155
ProcessTestAot.class, (task) -> {
155-
configureAotTask(project, aotTestSourceSet, task, aotTestClasses);
156-
task.setTestSourceSet(testSourceSet);
156+
configureAotTask(project, aotTestSourceSet, task, aotTestClasses, testSourceSet);
157+
task.setTestRuntimeClasspath(
158+
project.getConfigurations().getByName(testSourceSet.getImplementationConfigurationName()));
157159
});
158160
project.getDependencies().add(aotTestSourceSet.getImplementationConfigurationName(),
159161
project.files(aotTestClasses));

spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/aot/AbstractAot.java

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,16 @@
2020
import java.util.List;
2121

2222
import org.gradle.api.file.DirectoryProperty;
23+
import org.gradle.api.file.FileCollection;
2324
import org.gradle.api.provider.Property;
25+
import org.gradle.api.tasks.IgnoreEmptyDirectories;
2426
import org.gradle.api.tasks.Input;
27+
import org.gradle.api.tasks.InputFiles;
2528
import org.gradle.api.tasks.JavaExec;
2629
import org.gradle.api.tasks.OutputDirectory;
30+
import org.gradle.api.tasks.PathSensitive;
31+
import org.gradle.api.tasks.PathSensitivity;
32+
import org.gradle.api.tasks.SkipWhenEmpty;
2733
import org.gradle.work.DisableCachingByDefault;
2834

2935
/**
@@ -46,6 +52,8 @@ public abstract class AbstractAot extends JavaExec {
4652

4753
private final Property<String> artifactId;
4854

55+
private FileCollection inputClasses;
56+
4957
protected AbstractAot() {
5058
this.sourcesDir = getProject().getObjects().directoryProperty();
5159
this.resourcesDir = getProject().getObjects().directoryProperty();
@@ -65,25 +73,37 @@ public final Property<String> getArtifactId() {
6573
}
6674

6775
@OutputDirectory
68-
public final DirectoryProperty getSourcesDir() {
76+
public final DirectoryProperty getSourcesOutput() {
6977
return this.sourcesDir;
7078
}
7179

7280
@OutputDirectory
73-
public final DirectoryProperty getResourcesDir() {
81+
public final DirectoryProperty getResourcesOutput() {
7482
return this.resourcesDir;
7583
}
7684

7785
@OutputDirectory
78-
public final DirectoryProperty getClassesDir() {
86+
public final DirectoryProperty getClassesOutput() {
7987
return this.classesDir;
8088
}
8189

90+
@InputFiles
91+
@SkipWhenEmpty
92+
@IgnoreEmptyDirectories
93+
@PathSensitive(PathSensitivity.RELATIVE)
94+
public final FileCollection getInputClasses() {
95+
return this.inputClasses.getAsFileTree().matching((filter) -> filter.include((spec) -> !spec.isDirectory()));
96+
}
97+
98+
public void setInputClasses(FileCollection inputClasses) {
99+
this.inputClasses = inputClasses;
100+
}
101+
82102
List<String> processorArgs() {
83103
List<String> args = new ArrayList<>();
84-
args.add(getSourcesDir().getAsFile().get().getAbsolutePath());
85-
args.add(getResourcesDir().getAsFile().get().getAbsolutePath());
86-
args.add(getClassesDir().getAsFile().get().getAbsolutePath());
104+
args.add(getSourcesOutput().getAsFile().get().getAbsolutePath());
105+
args.add(getResourcesOutput().getAsFile().get().getAbsolutePath());
106+
args.add(getClassesOutput().getAsFile().get().getAbsolutePath());
87107
args.add(getGroupId().get());
88108
args.add(getArtifactId().get());
89109
args.addAll(super.getArgs());

spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/aot/ProcessTestAot.java

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import org.gradle.api.tasks.CacheableTask;
3030
import org.gradle.api.tasks.Classpath;
3131
import org.gradle.api.tasks.JavaExec;
32-
import org.gradle.api.tasks.SourceSet;
3332
import org.gradle.api.tasks.TaskAction;
3433

3534
import org.springframework.boot.gradle.plugin.SpringBootPlugin;
@@ -45,8 +44,6 @@ public class ProcessTestAot extends AbstractAot {
4544

4645
private final Configuration junitPlatformLauncher;
4746

48-
private FileCollection testClassesDirs;
49-
5047
public ProcessTestAot() {
5148
getMainClass().set("org.springframework.test.context.aot.TestAotProcessor");
5249
this.junitPlatformLauncher = createJUnitPlatformLauncher();
@@ -63,15 +60,6 @@ private Configuration createJUnitPlatformLauncher() {
6360
return configuration;
6461
}
6562

66-
@Classpath
67-
public FileCollection getTestClassesDirs() {
68-
return this.testClassesDirs;
69-
}
70-
71-
public void setTestClassesDirs(FileCollection testClassesDirs) {
72-
this.testClassesDirs = testClassesDirs;
73-
}
74-
7563
@Classpath
7664
FileCollection getJUnitPlatformLauncher() {
7765
return this.junitPlatformLauncher;
@@ -81,18 +69,16 @@ FileCollection getJUnitPlatformLauncher() {
8169
@TaskAction
8270
public void exec() {
8371
List<String> args = new ArrayList<>();
84-
args.add(this.testClassesDirs.getFiles().stream().filter(File::exists).map(File::getAbsolutePath)
72+
args.add(this.getInputClasses().getFiles().stream().filter(File::exists).map(File::getAbsolutePath)
8573
.collect(Collectors.joining(File.pathSeparator)));
8674
args.addAll(processorArgs());
8775
this.setArgs(args);
8876
this.classpath(this.junitPlatformLauncher);
8977
super.exec();
9078
}
9179

92-
public void setTestSourceSet(SourceSet testSourceSet) {
93-
setTestClassesDirs(testSourceSet.getOutput().getClassesDirs());
94-
this.junitPlatformLauncher.extendsFrom(
95-
getProject().getConfigurations().getByName(testSourceSet.getImplementationConfigurationName()));
80+
public void setTestRuntimeClasspath(Configuration configuration) {
81+
this.junitPlatformLauncher.extendsFrom(configuration);
9682
}
9783

9884
}

spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/SpringBootAotPluginIntegrationTests.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.nio.file.Files;
2222
import java.util.List;
2323

24+
import org.gradle.testkit.runner.TaskOutcome;
2425
import org.junit.jupiter.api.TestTemplate;
2526

2627
import org.springframework.boot.gradle.junit.GradleCompatibility;
@@ -94,4 +95,16 @@ void processTestAotHasTransitiveRuntimeDependenciesOnItsClasspath() {
9495
assertThat(output).contains("org.jboss.logging" + File.separatorChar + "jboss-logging");
9596
}
9697

98+
@TestTemplate
99+
void processAotIsSkippedWhenProjectHasNoMainSource() {
100+
assertThat(this.gradleBuild.build("processAot").task(":processAot").getOutcome())
101+
.isEqualTo(TaskOutcome.NO_SOURCE);
102+
}
103+
104+
@TestTemplate
105+
void processTestAotIsSkippedWhenProjectHasNoTestSource() {
106+
assertThat(this.gradleBuild.build("processTestAot").task(":processTestAot").getOutcome())
107+
.isEqualTo(TaskOutcome.NO_SOURCE);
108+
}
109+
97110
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
plugins {
2+
id 'org.springframework.boot'
3+
id 'org.springframework.boot.aot'
4+
id 'java'
5+
}
6+
7+
repositories {
8+
mavenCentral()
9+
}
10+
11+
springBoot {
12+
mainClass = 'com.example.Application'
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
plugins {
2+
id 'org.springframework.boot'
3+
id 'org.springframework.boot.aot'
4+
id 'java'
5+
}
6+
7+
repositories {
8+
mavenCentral()
9+
}
10+
11+
springBoot {
12+
mainClass = 'com.example.Application'
13+
}

0 commit comments

Comments
 (0)