Skip to content

Commit 14f47bd

Browse files
committed
Merge pull request #27412 from vpavic
* pr/27412: Polish "Allow build info properties to be excluded" Allow build info properties to be excluded Closes gh-27412
2 parents 2034ad4 + f4bd895 commit 14f47bd

File tree

13 files changed

+338
-21
lines changed

13 files changed

+338
-21
lines changed

spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/integrating-with-actuator.adoc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ By default, the generated build information is derived from the project:
3030
| Property | Default value
3131

3232
| `build.artifact`
33-
| The base name of the `bootJar` or `bootWar` task, or `unspecified` if no such task
34-
exists
33+
| The base name of the `bootJar` or `bootWar` task
3534

3635
| `build.group`
3736
| The group of the project
@@ -61,6 +60,8 @@ include::../gradle/integrating-with-actuator/build-info-custom-values.gradle[tag
6160
include::../gradle/integrating-with-actuator/build-info-custom-values.gradle.kts[tags=custom-values]
6261
----
6362

63+
NOTE: To omit any of the default properties from the generated build information, set its value to `null`.
64+
6465
The default value for `build.time` is the instant at which the project is being built.
6566
A side-effect of this is that the task will never be up-to-date.
6667
As a result, builds will take longer as more tasks, including the project's tests, will have to be executed.

spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfo.java

Lines changed: 5 additions & 7 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-2021 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.
@@ -59,13 +59,11 @@ public BuildInfo() {
5959
@TaskAction
6060
public void generateBuildProperties() {
6161
try {
62+
ProjectDetails details = new ProjectDetails(this.properties.getGroup(), this.properties.getArtifact(),
63+
this.properties.getVersion(), this.properties.getName(), this.properties.getTime(),
64+
coerceToStringValues(this.properties.getAdditional()));
6265
new BuildPropertiesWriter(new File(getDestinationDir(), "build-info.properties"))
63-
.writeBuildProperties(
64-
new ProjectDetails(this.properties.getGroup(),
65-
(this.properties.getArtifact() != null) ? this.properties.getArtifact()
66-
: "unspecified",
67-
this.properties.getVersion(), this.properties.getName(), this.properties.getTime(),
68-
coerceToStringValues(this.properties.getAdditional())));
66+
.writeBuildProperties(details);
6967
}
7068
catch (IOException ex) {
7169
throw new TaskExecutionException(this, ex);

spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoIntegrationTests.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
* Integration tests for the {@link BuildInfo} task.
4040
*
4141
* @author Andy Wilkinson
42+
* @author Vedran Pavic
4243
*/
4344
@GradleCompatibility(configurationCache = true)
4445
class BuildInfoIntegrationTests {
@@ -50,8 +51,8 @@ void defaultValues() {
5051
assertThat(this.gradleBuild.build("buildInfo").task(":buildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
5152
Properties buildInfoProperties = buildInfoProperties();
5253
assertThat(buildInfoProperties).containsKey("build.time");
53-
assertThat(buildInfoProperties).containsEntry("build.artifact", "unspecified");
54-
assertThat(buildInfoProperties).containsEntry("build.group", "");
54+
assertThat(buildInfoProperties).doesNotContainKey("build.artifact");
55+
assertThat(buildInfoProperties).doesNotContainKey("build.group");
5556
assertThat(buildInfoProperties).containsEntry("build.name", this.gradleBuild.getProjectDir().getName());
5657
assertThat(buildInfoProperties).containsEntry("build.version", "unspecified");
5758
}
@@ -122,6 +123,26 @@ void reproducibleOutputWithFixedTime() throws IOException, InterruptedException
122123
assertThat(firstHash).isEqualTo(secondHash);
123124
}
124125

126+
@TestTemplate
127+
void removePropertiesUsingNulls() {
128+
assertThat(this.gradleBuild.build("buildInfo").task(":buildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
129+
Properties buildInfoProperties = buildInfoProperties();
130+
assertThat(buildInfoProperties).doesNotContainKey("build.group");
131+
assertThat(buildInfoProperties).doesNotContainKey("build.artifact");
132+
assertThat(buildInfoProperties).doesNotContainKey("build.version");
133+
assertThat(buildInfoProperties).doesNotContainKey("build.name");
134+
}
135+
136+
@TestTemplate
137+
void removePropertiesUsingEmptyStrings() {
138+
assertThat(this.gradleBuild.build("buildInfo").task(":buildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
139+
Properties buildInfoProperties = buildInfoProperties();
140+
assertThat(buildInfoProperties).doesNotContainKey("build.group");
141+
assertThat(buildInfoProperties).doesNotContainKey("build.artifact");
142+
assertThat(buildInfoProperties).doesNotContainKey("build.version");
143+
assertThat(buildInfoProperties).doesNotContainKey("build.name");
144+
}
145+
125146
private Properties buildInfoProperties() {
126147
File file = new File(this.gradleBuild.getProjectDir(), "build/build-info.properties");
127148
assertThat(file).isFile();

spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoTests.java

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
* Tests for {@link BuildInfo}.
3939
*
4040
* @author Andy Wilkinson
41+
* @author Vedran Pavic
4142
*/
4243
@ClassPathExclusions("kotlin-daemon-client-*")
4344
class BuildInfoTests {
@@ -49,8 +50,8 @@ class BuildInfoTests {
4950
void basicExecution() {
5051
Properties properties = buildInfoProperties(createTask(createProject("test")));
5152
assertThat(properties).containsKey("build.time");
52-
assertThat(properties).containsEntry("build.artifact", "unspecified");
53-
assertThat(properties).containsEntry("build.group", "");
53+
assertThat(properties).doesNotContainKey("build.artifact");
54+
assertThat(properties).doesNotContainKey("build.group");
5455
assertThat(properties).containsEntry("build.name", "test");
5556
assertThat(properties).containsEntry("build.version", "unspecified");
5657
}
@@ -62,6 +63,20 @@ void customArtifactIsReflectedInProperties() {
6263
assertThat(buildInfoProperties(task)).containsEntry("build.artifact", "custom");
6364
}
6465

66+
@Test
67+
void artifactCanBeRemovedFromPropertiesUsingNull() {
68+
BuildInfo task = createTask(createProject("test"));
69+
task.getProperties().setArtifact(null);
70+
assertThat(buildInfoProperties(task)).doesNotContainKey("build.artifact");
71+
}
72+
73+
@Test
74+
void artifactCanBeRemovedFromPropertiesUsingEmptyString() {
75+
BuildInfo task = createTask(createProject("test"));
76+
task.getProperties().setArtifact("");
77+
assertThat(buildInfoProperties(task)).doesNotContainKey("build.artifact");
78+
}
79+
6580
@Test
6681
void projectGroupIsReflectedInProperties() {
6782
BuildInfo task = createTask(createProject("test"));
@@ -76,13 +91,41 @@ void customGroupIsReflectedInProperties() {
7691
assertThat(buildInfoProperties(task)).containsEntry("build.group", "com.example");
7792
}
7893

94+
@Test
95+
void groupCanBeRemovedFromPropertiesUsingNull() {
96+
BuildInfo task = createTask(createProject("test"));
97+
task.getProperties().setGroup(null);
98+
assertThat(buildInfoProperties(task)).doesNotContainKey("build.group");
99+
}
100+
101+
@Test
102+
void groupCanBeRemovedFromPropertiesUsingEmptyString() {
103+
BuildInfo task = createTask(createProject("test"));
104+
task.getProperties().setGroup("");
105+
assertThat(buildInfoProperties(task)).doesNotContainKey("build.group");
106+
}
107+
79108
@Test
80109
void customNameIsReflectedInProperties() {
81110
BuildInfo task = createTask(createProject("test"));
82111
task.getProperties().setName("Example");
83112
assertThat(buildInfoProperties(task)).containsEntry("build.name", "Example");
84113
}
85114

115+
@Test
116+
void nameCanBeRemovedFromPropertiesUsingNull() {
117+
BuildInfo task = createTask(createProject("test"));
118+
task.getProperties().setName(null);
119+
assertThat(buildInfoProperties(task)).doesNotContainKey("build.name");
120+
}
121+
122+
@Test
123+
void nameCanBeRemovedFromPropertiesUsingEmptyString() {
124+
BuildInfo task = createTask(createProject("test"));
125+
task.getProperties().setName("");
126+
assertThat(buildInfoProperties(task)).doesNotContainKey("build.name");
127+
}
128+
86129
@Test
87130
void projectVersionIsReflectedInProperties() {
88131
BuildInfo task = createTask(createProject("test"));
@@ -97,6 +140,20 @@ void customVersionIsReflectedInProperties() {
97140
assertThat(buildInfoProperties(task)).containsEntry("build.version", "2.3.4");
98141
}
99142

143+
@Test
144+
void versionCanBeRemovedFromPropertiesUsingNull() {
145+
BuildInfo task = createTask(createProject("test"));
146+
task.getProperties().setVersion(null);
147+
assertThat(buildInfoProperties(task)).doesNotContainKey("build.version");
148+
}
149+
150+
@Test
151+
void versionCanBeRemovedFromPropertiesUsingEmptyString() {
152+
BuildInfo task = createTask(createProject("test"));
153+
task.getProperties().setVersion("");
154+
assertThat(buildInfoProperties(task)).doesNotContainKey("build.version");
155+
}
156+
100157
@Test
101158
void timeIsSetInProperties() {
102159
BuildInfo task = createTask(createProject("test"));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
plugins {
2+
id 'org.springframework.boot' version '{version}' apply false
3+
}
4+
5+
group = 'foo'
6+
version = '0.1.0'
7+
8+
task buildInfo(type: org.springframework.boot.gradle.tasks.buildinfo.BuildInfo) {
9+
destinationDir project.buildDir
10+
properties {
11+
group = ''
12+
artifact = ''
13+
version = ''
14+
name = ''
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
plugins {
2+
id 'org.springframework.boot' version '{version}' apply false
3+
}
4+
5+
group = 'foo'
6+
version = '0.1.0'
7+
8+
task buildInfo(type: org.springframework.boot.gradle.tasks.buildinfo.BuildInfo) {
9+
destinationDir project.buildDir
10+
properties {
11+
group = null
12+
artifact = null
13+
version = null
14+
name = null
15+
}
16+
}

spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/BuildPropertiesWriter.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2021 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.
@@ -25,13 +25,15 @@
2525
import java.util.Properties;
2626

2727
import org.springframework.core.CollectionFactory;
28+
import org.springframework.util.StringUtils;
2829

2930
/**
3031
* A {@code BuildPropertiesWriter} writes the {@code build-info.properties} for
3132
* consumption by the Actuator.
3233
*
3334
* @author Andy Wilkinson
3435
* @author Stephane Nicoll
36+
* @author Vedran Pavic
3537
* @since 1.0.0
3638
*/
3739
public final class BuildPropertiesWriter {
@@ -71,10 +73,10 @@ private void createFileIfNecessary(File file) throws IOException {
7173

7274
protected Properties createBuildInfo(ProjectDetails project) {
7375
Properties properties = CollectionFactory.createSortedProperties(true);
74-
properties.put("build.group", project.getGroup());
75-
properties.put("build.artifact", project.getArtifact());
76-
properties.put("build.name", project.getName());
77-
properties.put("build.version", project.getVersion());
76+
addIfHasValue(properties, "build.group", project.getGroup());
77+
addIfHasValue(properties, "build.artifact", project.getArtifact());
78+
addIfHasValue(properties, "build.name", project.getName());
79+
addIfHasValue(properties, "build.version", project.getVersion());
7880
if (project.getTime() != null) {
7981
properties.put("build.time", DateTimeFormatter.ISO_INSTANT.format(project.getTime()));
8082
}
@@ -84,6 +86,12 @@ protected Properties createBuildInfo(ProjectDetails project) {
8486
return properties;
8587
}
8688

89+
private void addIfHasValue(Properties properties, String name, String value) {
90+
if (StringUtils.hasText(value)) {
91+
properties.put(name, value);
92+
}
93+
}
94+
8795
/**
8896
* Build-system agnostic details of a project.
8997
*/

spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/BuildInfoIntegrationTests.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
* Integration tests for the Maven plugin's build info support.
3636
*
3737
* @author Andy Wilkinson
38+
* @author Vedran Pavic
3839
*/
3940
@ExtendWith(MavenBuildExtension.class)
4041
class BuildInfoIntegrationTests {
@@ -89,6 +90,21 @@ void whenBuildTimeIsDisabledIfDoesNotAppearInGeneratedBuildInfo(MavenBuild maven
8990
.doesNotContainBuildTime()));
9091
}
9192

93+
@TestTemplate
94+
void whenBuildTimeIsExcludedIfDoesNotAppearInGeneratedBuildInfo(MavenBuild mavenBuild) {
95+
mavenBuild.project("build-info-exclude-build-time").execute(buildInfo((buildInfo) -> assertThat(buildInfo)
96+
.hasBuildGroup("org.springframework.boot.maven.it").hasBuildArtifact("build-info-exclude-build-time")
97+
.hasBuildName("Generate build info with excluded build time").hasBuildVersion("0.0.1.BUILD-SNAPSHOT")
98+
.doesNotContainBuildTime()));
99+
}
100+
101+
@TestTemplate
102+
void whenBuildPropertiesAreExcludedTheyDoNotAppearInGeneratedBuildInfo(MavenBuild mavenBuild) {
103+
mavenBuild.project("build-info-exclude-build-properties").execute(
104+
buildInfo((buildInfo) -> assertThat(buildInfo).doesNotContainBuildGroup().doesNotContainBuildArtifact()
105+
.doesNotContainBuildName().doesNotContainBuildVersion().containsBuildTime()));
106+
}
107+
92108
private ProjectCallback buildInfo(Consumer<AssertProvider<BuildInfoAssert>> buildInfo) {
93109
return buildInfo("target/classes/META-INF/build-info.properties", buildInfo);
94110
}
@@ -130,18 +146,34 @@ BuildInfoAssert hasBuildGroup(String expected) {
130146
return containsEntry("build.group", expected);
131147
}
132148

149+
BuildInfoAssert doesNotContainBuildGroup() {
150+
return doesNotContainKey("build.group");
151+
}
152+
133153
BuildInfoAssert hasBuildArtifact(String expected) {
134154
return containsEntry("build.artifact", expected);
135155
}
136156

157+
BuildInfoAssert doesNotContainBuildArtifact() {
158+
return doesNotContainKey("build.artifact");
159+
}
160+
137161
BuildInfoAssert hasBuildName(String expected) {
138162
return containsEntry("build.name", expected);
139163
}
140164

165+
BuildInfoAssert doesNotContainBuildName() {
166+
return doesNotContainKey("build.name");
167+
}
168+
141169
BuildInfoAssert hasBuildVersion(String expected) {
142170
return containsEntry("build.version", expected);
143171
}
144172

173+
BuildInfoAssert doesNotContainBuildVersion() {
174+
return doesNotContainKey("build.version");
175+
}
176+
145177
BuildInfoAssert containsBuildTime() {
146178
return containsKey("build.time");
147179
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<groupId>org.springframework.boot.maven.it</groupId>
6+
<artifactId>build-info-exclude-build-properties</artifactId>
7+
<version>0.0.1.BUILD-SNAPSHOT</version>
8+
<name>Generate build info with excluded build properties</name>
9+
<properties>
10+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
11+
<maven.compiler.source>@java.version@</maven.compiler.source>
12+
<maven.compiler.target>@java.version@</maven.compiler.target>
13+
</properties>
14+
<build>
15+
<plugins>
16+
<plugin>
17+
<groupId>@project.groupId@</groupId>
18+
<artifactId>@project.artifactId@</artifactId>
19+
<version>@project.version@</version>
20+
<executions>
21+
<execution>
22+
<configuration>
23+
<excludeInfoProperties>
24+
<excludeInfoProperty>group</excludeInfoProperty>
25+
<excludeInfoProperty>artifact</excludeInfoProperty>
26+
<excludeInfoProperty>version</excludeInfoProperty>
27+
<excludeInfoProperty>name</excludeInfoProperty>
28+
</excludeInfoProperties>
29+
</configuration>
30+
<goals>
31+
<goal>build-info</goal>
32+
</goals>
33+
</execution>
34+
</executions>
35+
</plugin>
36+
</plugins>
37+
</build>
38+
</project>

0 commit comments

Comments
 (0)