Skip to content

Commit f11ddb4

Browse files
committed
Prevent eager creation of bootWar task
Previously, querying the artifact's extension in SinglePublishedArtifact would result in eager creation of the task that creates the artifact. Typically, this is the bootWar task. Instead of querying the extension, this commit reworks SinglePublishedArtifact and its callers to call separate methods for jar and war artifacts so that the extension check is no longer required. Tests have been added to ensure that running help does not trigger any unexpected task creation. The tests' assertions tolerate some variation in behavior that depend on the version of Gradle and whether the configuration cache is enabled. Closes gh-30211
1 parent 75693c1 commit f11ddb4

12 files changed

+165
-13
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ private void configureBootBuildImageTask(Project project, TaskProvider<BootJar>
133133

134134
private void configureArtifactPublication(TaskProvider<BootJar> bootJar) {
135135
LazyPublishArtifact artifact = new LazyPublishArtifact(bootJar);
136-
this.singlePublishedArtifact.addCandidate(artifact);
136+
this.singlePublishedArtifact.addJarCandidate(artifact);
137137
}
138138

139139
private void configureBootRunTask(Project project) {

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

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -38,14 +38,22 @@ final class SinglePublishedArtifact implements Buildable {
3838
this.artifacts = artifacts;
3939
}
4040

41-
void addCandidate(PublishArtifact candidate) {
42-
if (this.currentArtifact == null || "war".equals(candidate.getExtension())) {
43-
this.artifacts.remove(this.currentArtifact);
44-
this.artifacts.add(candidate);
45-
this.currentArtifact = candidate;
41+
void addWarCandidate(PublishArtifact candidate) {
42+
add(candidate);
43+
}
44+
45+
void addJarCandidate(PublishArtifact candidate) {
46+
if (this.currentArtifact == null) {
47+
add(candidate);
4648
}
4749
}
4850

51+
private void add(PublishArtifact artifact) {
52+
this.artifacts.remove(this.currentArtifact);
53+
this.artifacts.add(artifact);
54+
this.currentArtifact = artifact;
55+
}
56+
4957
@Override
5058
public TaskDependency getBuildDependencies() {
5159
return this.artifacts.getBuildDependencies();

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ private void configureBootBuildImageTask(Project project, TaskProvider<BootWar>
108108

109109
private void configureArtifactPublication(TaskProvider<BootWar> bootWar) {
110110
LazyPublishArtifact artifact = new LazyPublishArtifact(bootWar);
111-
this.singlePublishedArtifact.addCandidate(artifact);
111+
this.singlePublishedArtifact.addWarCandidate(artifact);
112112
}
113113

114114
}

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

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,19 +16,25 @@
1616

1717
package org.springframework.boot.gradle.plugin;
1818

19+
import java.io.BufferedReader;
1920
import java.io.File;
2021
import java.io.FileInputStream;
2122
import java.io.IOException;
23+
import java.io.StringReader;
2224
import java.util.ArrayList;
2325
import java.util.Enumeration;
26+
import java.util.HashSet;
2427
import java.util.List;
28+
import java.util.Set;
2529
import java.util.function.Consumer;
2630
import java.util.zip.ZipEntry;
2731
import java.util.zip.ZipFile;
2832

2933
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
3034
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
35+
import org.gradle.testkit.runner.BuildResult;
3136
import org.gradle.testkit.runner.TaskOutcome;
37+
import org.gradle.util.GradleVersion;
3238
import org.junit.jupiter.api.TestTemplate;
3339

3440
import org.springframework.boot.gradle.junit.GradleCompatibility;
@@ -154,6 +160,26 @@ void scriptsHaveCorrectPermissions() throws IOException {
154160
});
155161
}
156162

163+
@TestTemplate
164+
void taskConfigurationIsAvoided() throws IOException {
165+
BuildResult result = this.gradleBuild.build("help");
166+
String output = result.getOutput();
167+
BufferedReader reader = new BufferedReader(new StringReader(output));
168+
String line;
169+
Set<String> configured = new HashSet<>();
170+
while ((line = reader.readLine()) != null) {
171+
if (line.startsWith("Configuring :")) {
172+
configured.add(line.substring("Configuring :".length()));
173+
}
174+
}
175+
if (GradleVersion.version(this.gradleBuild.getGradleVersion()).compareTo(GradleVersion.version("7.3.3")) < 0) {
176+
assertThat(configured).containsExactly("help");
177+
}
178+
else {
179+
assertThat(configured).containsExactlyInAnyOrder("help", "clean");
180+
}
181+
}
182+
157183
private List<String> zipEntryNames(File distribution) throws IOException {
158184
List<String> entryNames = new ArrayList<>();
159185
try (ZipFile zipFile = new ZipFile(distribution)) {

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

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors.
2+
* Copyright 2012-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,13 +16,18 @@
1616

1717
package org.springframework.boot.gradle.plugin;
1818

19+
import java.io.BufferedReader;
1920
import java.io.File;
2021
import java.io.FileOutputStream;
2122
import java.io.IOException;
23+
import java.io.StringReader;
24+
import java.util.HashSet;
25+
import java.util.Set;
2226
import java.util.jar.JarOutputStream;
2327

2428
import org.gradle.testkit.runner.BuildResult;
2529
import org.gradle.testkit.runner.TaskOutcome;
30+
import org.gradle.util.GradleVersion;
2631
import org.junit.jupiter.api.TestTemplate;
2732

2833
import org.springframework.boot.gradle.junit.GradleCompatibility;
@@ -159,6 +164,27 @@ void productionRuntimeClasspathIsConfiguredWithResolvabilityAndConsumabilityThat
159164
assertThat(productionRuntime).contains("canBeConsumed: false");
160165
}
161166

167+
@TestTemplate
168+
void taskConfigurationIsAvoided() throws IOException {
169+
BuildResult result = this.gradleBuild.build("help");
170+
String output = result.getOutput();
171+
BufferedReader reader = new BufferedReader(new StringReader(output));
172+
String line;
173+
Set<String> configured = new HashSet<>();
174+
while ((line = reader.readLine()) != null) {
175+
if (line.startsWith("Configuring :")) {
176+
configured.add(line.substring("Configuring :".length()));
177+
}
178+
}
179+
if (!this.gradleBuild.isConfigurationCache() && GradleVersion.version(this.gradleBuild.getGradleVersion())
180+
.compareTo(GradleVersion.version("7.3.3")) < 0) {
181+
assertThat(configured).containsExactly("help");
182+
}
183+
else {
184+
assertThat(configured).containsExactlyInAnyOrder("help", "clean");
185+
}
186+
}
187+
162188
private void createMinimalMainSource() throws IOException {
163189
File examplePackage = new File(this.gradleBuild.getProjectDir(), "src/main/java/com/example");
164190
examplePackage.mkdirs();

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

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,6 +16,14 @@
1616

1717
package org.springframework.boot.gradle.plugin;
1818

19+
import java.io.BufferedReader;
20+
import java.io.IOException;
21+
import java.io.StringReader;
22+
import java.util.HashSet;
23+
import java.util.Set;
24+
25+
import org.gradle.testkit.runner.BuildResult;
26+
import org.gradle.util.GradleVersion;
1927
import org.junit.jupiter.api.TestTemplate;
2028

2129
import org.springframework.boot.gradle.junit.GradleCompatibility;
@@ -57,4 +65,24 @@ void kotlinCompileTasksCanOverrideDefaultJavaParametersFlag() {
5765
.contains("compileKotlin java parameters: false").contains("compileTestKotlin java parameters: false");
5866
}
5967

68+
@TestTemplate
69+
void taskConfigurationIsAvoided() throws IOException {
70+
BuildResult result = this.gradleBuild.build("help");
71+
String output = result.getOutput();
72+
BufferedReader reader = new BufferedReader(new StringReader(output));
73+
String line;
74+
Set<String> configured = new HashSet<>();
75+
while ((line = reader.readLine()) != null) {
76+
if (line.startsWith("Configuring :")) {
77+
configured.add(line.substring("Configuring :".length()));
78+
}
79+
}
80+
if (GradleVersion.version(this.gradleBuild.getGradleVersion()).compareTo(GradleVersion.version("7.3.3")) < 0) {
81+
assertThat(configured).containsExactly("help");
82+
}
83+
else {
84+
assertThat(configured).containsExactlyInAnyOrder("help", "clean", "compileKotlin", "compileTestKotlin");
85+
}
86+
}
87+
6088
}

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

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors.
2+
* Copyright 2012-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,10 +16,16 @@
1616

1717
package org.springframework.boot.gradle.plugin;
1818

19+
import java.io.BufferedReader;
1920
import java.io.File;
21+
import java.io.IOException;
22+
import java.io.StringReader;
23+
import java.util.HashSet;
24+
import java.util.Set;
2025

2126
import org.gradle.testkit.runner.BuildResult;
2227
import org.gradle.testkit.runner.TaskOutcome;
28+
import org.gradle.util.GradleVersion;
2329
import org.junit.jupiter.api.TestTemplate;
2430

2531
import org.springframework.boot.gradle.junit.GradleCompatibility;
@@ -67,4 +73,24 @@ void errorMessageIsHelpfulWhenMainClassCannotBeResolved() {
6773
assertThat(result.getOutput()).contains("Main class name has not been configured and it could not be resolved");
6874
}
6975

76+
@TestTemplate
77+
void taskConfigurationIsAvoided() throws IOException {
78+
BuildResult result = this.gradleBuild.build("help");
79+
String output = result.getOutput();
80+
BufferedReader reader = new BufferedReader(new StringReader(output));
81+
String line;
82+
Set<String> configured = new HashSet<>();
83+
while ((line = reader.readLine()) != null) {
84+
if (line.startsWith("Configuring :")) {
85+
configured.add(line.substring("Configuring :".length()));
86+
}
87+
}
88+
if (GradleVersion.version(this.gradleBuild.getGradleVersion()).compareTo(GradleVersion.version("7.3.3")) < 0) {
89+
assertThat(configured).containsExactly("help");
90+
}
91+
else {
92+
assertThat(configured).containsExactlyInAnyOrder("help", "clean");
93+
}
94+
}
95+
7096
}

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors.
2+
* Copyright 2012-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -150,6 +150,10 @@ public GradleBuild configurationCache() {
150150
return this;
151151
}
152152

153+
public boolean isConfigurationCache() {
154+
return this.configurationCache;
155+
}
156+
153157
public GradleBuild scriptProperty(String key, String value) {
154158
this.scriptProperties.put(key, value);
155159
return this;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
plugins {
2+
id 'org.springframework.boot' version '{version}'
3+
id 'java'
4+
id 'application'
5+
}
6+
7+
tasks.configureEach {
8+
println "Configuring ${it.path}"
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
plugins {
2+
id 'org.springframework.boot' version '{version}'
3+
id 'java'
4+
}
5+
6+
tasks.configureEach {
7+
println "Configuring ${it.path}"
8+
}

0 commit comments

Comments
 (0)