Skip to content

Commit

Permalink
Prevent eager creation of bootWar task
Browse files Browse the repository at this point in the history
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
  • Loading branch information
wilkinsona committed Mar 15, 2022
1 parent 75693c1 commit f11ddb4
Show file tree
Hide file tree
Showing 12 changed files with 165 additions and 13 deletions.
Expand Up @@ -133,7 +133,7 @@ private void configureBootBuildImageTask(Project project, TaskProvider<BootJar>

private void configureArtifactPublication(TaskProvider<BootJar> bootJar) {
LazyPublishArtifact artifact = new LazyPublishArtifact(bootJar);
this.singlePublishedArtifact.addCandidate(artifact);
this.singlePublishedArtifact.addJarCandidate(artifact);
}

private void configureBootRunTask(Project project) {
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -38,14 +38,22 @@ final class SinglePublishedArtifact implements Buildable {
this.artifacts = artifacts;
}

void addCandidate(PublishArtifact candidate) {
if (this.currentArtifact == null || "war".equals(candidate.getExtension())) {
this.artifacts.remove(this.currentArtifact);
this.artifacts.add(candidate);
this.currentArtifact = candidate;
void addWarCandidate(PublishArtifact candidate) {
add(candidate);
}

void addJarCandidate(PublishArtifact candidate) {
if (this.currentArtifact == null) {
add(candidate);
}
}

private void add(PublishArtifact artifact) {
this.artifacts.remove(this.currentArtifact);
this.artifacts.add(artifact);
this.currentArtifact = artifact;
}

@Override
public TaskDependency getBuildDependencies() {
return this.artifacts.getBuildDependencies();
Expand Down
Expand Up @@ -108,7 +108,7 @@ private void configureBootBuildImageTask(Project project, TaskProvider<BootWar>

private void configureArtifactPublication(TaskProvider<BootWar> bootWar) {
LazyPublishArtifact artifact = new LazyPublishArtifact(bootWar);
this.singlePublishedArtifact.addCandidate(artifact);
this.singlePublishedArtifact.addWarCandidate(artifact);
}

}
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,19 +16,25 @@

package org.springframework.boot.gradle.plugin;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.TaskOutcome;
import org.gradle.util.GradleVersion;
import org.junit.jupiter.api.TestTemplate;

import org.springframework.boot.gradle.junit.GradleCompatibility;
Expand Down Expand Up @@ -154,6 +160,26 @@ void scriptsHaveCorrectPermissions() throws IOException {
});
}

@TestTemplate
void taskConfigurationIsAvoided() throws IOException {
BuildResult result = this.gradleBuild.build("help");
String output = result.getOutput();
BufferedReader reader = new BufferedReader(new StringReader(output));
String line;
Set<String> configured = new HashSet<>();
while ((line = reader.readLine()) != null) {
if (line.startsWith("Configuring :")) {
configured.add(line.substring("Configuring :".length()));
}
}
if (GradleVersion.version(this.gradleBuild.getGradleVersion()).compareTo(GradleVersion.version("7.3.3")) < 0) {
assertThat(configured).containsExactly("help");
}
else {
assertThat(configured).containsExactlyInAnyOrder("help", "clean");
}
}

private List<String> zipEntryNames(File distribution) throws IOException {
List<String> entryNames = new ArrayList<>();
try (ZipFile zipFile = new ZipFile(distribution)) {
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,13 +16,18 @@

package org.springframework.boot.gradle.plugin;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.util.HashSet;
import java.util.Set;
import java.util.jar.JarOutputStream;

import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.TaskOutcome;
import org.gradle.util.GradleVersion;
import org.junit.jupiter.api.TestTemplate;

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

@TestTemplate
void taskConfigurationIsAvoided() throws IOException {
BuildResult result = this.gradleBuild.build("help");
String output = result.getOutput();
BufferedReader reader = new BufferedReader(new StringReader(output));
String line;
Set<String> configured = new HashSet<>();
while ((line = reader.readLine()) != null) {
if (line.startsWith("Configuring :")) {
configured.add(line.substring("Configuring :".length()));
}
}
if (!this.gradleBuild.isConfigurationCache() && GradleVersion.version(this.gradleBuild.getGradleVersion())
.compareTo(GradleVersion.version("7.3.3")) < 0) {
assertThat(configured).containsExactly("help");
}
else {
assertThat(configured).containsExactlyInAnyOrder("help", "clean");
}
}

private void createMinimalMainSource() throws IOException {
File examplePackage = new File(this.gradleBuild.getProjectDir(), "src/main/java/com/example");
examplePackage.mkdirs();
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,6 +16,14 @@

package org.springframework.boot.gradle.plugin;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.HashSet;
import java.util.Set;

import org.gradle.testkit.runner.BuildResult;
import org.gradle.util.GradleVersion;
import org.junit.jupiter.api.TestTemplate;

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

@TestTemplate
void taskConfigurationIsAvoided() throws IOException {
BuildResult result = this.gradleBuild.build("help");
String output = result.getOutput();
BufferedReader reader = new BufferedReader(new StringReader(output));
String line;
Set<String> configured = new HashSet<>();
while ((line = reader.readLine()) != null) {
if (line.startsWith("Configuring :")) {
configured.add(line.substring("Configuring :".length()));
}
}
if (GradleVersion.version(this.gradleBuild.getGradleVersion()).compareTo(GradleVersion.version("7.3.3")) < 0) {
assertThat(configured).containsExactly("help");
}
else {
assertThat(configured).containsExactlyInAnyOrder("help", "clean", "compileKotlin", "compileTestKotlin");
}
}

}
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,10 +16,16 @@

package org.springframework.boot.gradle.plugin;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.HashSet;
import java.util.Set;

import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.TaskOutcome;
import org.gradle.util.GradleVersion;
import org.junit.jupiter.api.TestTemplate;

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

@TestTemplate
void taskConfigurationIsAvoided() throws IOException {
BuildResult result = this.gradleBuild.build("help");
String output = result.getOutput();
BufferedReader reader = new BufferedReader(new StringReader(output));
String line;
Set<String> configured = new HashSet<>();
while ((line = reader.readLine()) != null) {
if (line.startsWith("Configuring :")) {
configured.add(line.substring("Configuring :".length()));
}
}
if (GradleVersion.version(this.gradleBuild.getGradleVersion()).compareTo(GradleVersion.version("7.3.3")) < 0) {
assertThat(configured).containsExactly("help");
}
else {
assertThat(configured).containsExactlyInAnyOrder("help", "clean");
}
}

}
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -150,6 +150,10 @@ public GradleBuild configurationCache() {
return this;
}

public boolean isConfigurationCache() {
return this.configurationCache;
}

public GradleBuild scriptProperty(String key, String value) {
this.scriptProperties.put(key, value);
return this;
Expand Down
@@ -0,0 +1,9 @@
plugins {
id 'org.springframework.boot' version '{version}'
id 'java'
id 'application'
}

tasks.configureEach {
println "Configuring ${it.path}"
}
@@ -0,0 +1,8 @@
plugins {
id 'org.springframework.boot' version '{version}'
id 'java'
}

tasks.configureEach {
println "Configuring ${it.path}"
}
@@ -0,0 +1,9 @@
plugins {
id 'org.springframework.boot' version '{version}'
}

apply plugin: 'org.jetbrains.kotlin.jvm'

tasks.configureEach {
println "Configuring ${it.path}"
}
@@ -0,0 +1,8 @@
plugins {
id 'org.springframework.boot' version '{version}'
id 'war'
}

tasks.configureEach {
println "Configuring ${it.path}"
}

0 comments on commit f11ddb4

Please sign in to comment.