diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/integrating-with-actuator.adoc b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/integrating-with-actuator.adoc index 928448551e..535e7948e0 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/integrating-with-actuator.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/integrating-with-actuator.adoc @@ -30,8 +30,7 @@ By default, the generated build information is derived from the project: | Property | Default value | `build.artifact` -| The base name of the `bootJar` or `bootWar` task, or `unspecified` if no such task - exists +| The base name of the `bootJar` or `bootWar` task | `build.group` | The group of the project @@ -61,6 +60,8 @@ include::../gradle/integrating-with-actuator/build-info-custom-values.gradle[tag include::../gradle/integrating-with-actuator/build-info-custom-values.gradle.kts[tags=custom-values] ---- +NOTE: To omit any of the default properties from the generated build information, set its value to `null`. + The default value for `build.time` is the instant at which the project is being built. A side-effect of this is that the task will never be up-to-date. As a result, builds will take longer as more tasks, including the project's tests, will have to be executed. diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfo.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfo.java index 2246248790..f48226e5d8 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfo.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2021 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. @@ -59,13 +59,11 @@ public class BuildInfo extends ConventionTask { @TaskAction public void generateBuildProperties() { try { + ProjectDetails details = new ProjectDetails(this.properties.getGroup(), this.properties.getArtifact(), + this.properties.getVersion(), this.properties.getName(), this.properties.getTime(), + coerceToStringValues(this.properties.getAdditional())); new BuildPropertiesWriter(new File(getDestinationDir(), "build-info.properties")) - .writeBuildProperties( - new ProjectDetails(this.properties.getGroup(), - (this.properties.getArtifact() != null) ? this.properties.getArtifact() - : "unspecified", - this.properties.getVersion(), this.properties.getName(), this.properties.getTime(), - coerceToStringValues(this.properties.getAdditional()))); + .writeBuildProperties(details); } catch (IOException ex) { throw new TaskExecutionException(this, ex); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoIntegrationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoIntegrationTests.java index bc9e7a4fe7..a792c552e2 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoIntegrationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoIntegrationTests.java @@ -39,6 +39,7 @@ import static org.assertj.core.api.Assertions.assertThat; * Integration tests for the {@link BuildInfo} task. * * @author Andy Wilkinson + * @author Vedran Pavic */ @GradleCompatibility(configurationCache = true) class BuildInfoIntegrationTests { @@ -50,8 +51,8 @@ class BuildInfoIntegrationTests { assertThat(this.gradleBuild.build("buildInfo").task(":buildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); Properties buildInfoProperties = buildInfoProperties(); assertThat(buildInfoProperties).containsKey("build.time"); - assertThat(buildInfoProperties).containsEntry("build.artifact", "unspecified"); - assertThat(buildInfoProperties).containsEntry("build.group", ""); + assertThat(buildInfoProperties).doesNotContainKey("build.artifact"); + assertThat(buildInfoProperties).doesNotContainKey("build.group"); assertThat(buildInfoProperties).containsEntry("build.name", this.gradleBuild.getProjectDir().getName()); assertThat(buildInfoProperties).containsEntry("build.version", "unspecified"); } @@ -122,6 +123,26 @@ class BuildInfoIntegrationTests { assertThat(firstHash).isEqualTo(secondHash); } + @TestTemplate + void removePropertiesUsingNulls() { + assertThat(this.gradleBuild.build("buildInfo").task(":buildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); + Properties buildInfoProperties = buildInfoProperties(); + assertThat(buildInfoProperties).doesNotContainKey("build.group"); + assertThat(buildInfoProperties).doesNotContainKey("build.artifact"); + assertThat(buildInfoProperties).doesNotContainKey("build.version"); + assertThat(buildInfoProperties).doesNotContainKey("build.name"); + } + + @TestTemplate + void removePropertiesUsingEmptyStrings() { + assertThat(this.gradleBuild.build("buildInfo").task(":buildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); + Properties buildInfoProperties = buildInfoProperties(); + assertThat(buildInfoProperties).doesNotContainKey("build.group"); + assertThat(buildInfoProperties).doesNotContainKey("build.artifact"); + assertThat(buildInfoProperties).doesNotContainKey("build.version"); + assertThat(buildInfoProperties).doesNotContainKey("build.name"); + } + private Properties buildInfoProperties() { File file = new File(this.gradleBuild.getProjectDir(), "build/build-info.properties"); assertThat(file).isFile(); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoTests.java index 61d2629dfd..441ebd4d24 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoTests.java @@ -38,6 +38,7 @@ import static org.assertj.core.api.Assertions.assertThat; * Tests for {@link BuildInfo}. * * @author Andy Wilkinson + * @author Vedran Pavic */ @ClassPathExclusions("kotlin-daemon-client-*") class BuildInfoTests { @@ -49,8 +50,8 @@ class BuildInfoTests { void basicExecution() { Properties properties = buildInfoProperties(createTask(createProject("test"))); assertThat(properties).containsKey("build.time"); - assertThat(properties).containsEntry("build.artifact", "unspecified"); - assertThat(properties).containsEntry("build.group", ""); + assertThat(properties).doesNotContainKey("build.artifact"); + assertThat(properties).doesNotContainKey("build.group"); assertThat(properties).containsEntry("build.name", "test"); assertThat(properties).containsEntry("build.version", "unspecified"); } @@ -62,6 +63,20 @@ class BuildInfoTests { assertThat(buildInfoProperties(task)).containsEntry("build.artifact", "custom"); } + @Test + void artifactCanBeRemovedFromPropertiesUsingNull() { + BuildInfo task = createTask(createProject("test")); + task.getProperties().setArtifact(null); + assertThat(buildInfoProperties(task)).doesNotContainKey("build.artifact"); + } + + @Test + void artifactCanBeRemovedFromPropertiesUsingEmptyString() { + BuildInfo task = createTask(createProject("test")); + task.getProperties().setArtifact(""); + assertThat(buildInfoProperties(task)).doesNotContainKey("build.artifact"); + } + @Test void projectGroupIsReflectedInProperties() { BuildInfo task = createTask(createProject("test")); @@ -76,6 +91,20 @@ class BuildInfoTests { assertThat(buildInfoProperties(task)).containsEntry("build.group", "com.example"); } + @Test + void groupCanBeRemovedFromPropertiesUsingNull() { + BuildInfo task = createTask(createProject("test")); + task.getProperties().setGroup(null); + assertThat(buildInfoProperties(task)).doesNotContainKey("build.group"); + } + + @Test + void groupCanBeRemovedFromPropertiesUsingEmptyString() { + BuildInfo task = createTask(createProject("test")); + task.getProperties().setGroup(""); + assertThat(buildInfoProperties(task)).doesNotContainKey("build.group"); + } + @Test void customNameIsReflectedInProperties() { BuildInfo task = createTask(createProject("test")); @@ -83,6 +112,20 @@ class BuildInfoTests { assertThat(buildInfoProperties(task)).containsEntry("build.name", "Example"); } + @Test + void nameCanBeRemovedFromPropertiesUsingNull() { + BuildInfo task = createTask(createProject("test")); + task.getProperties().setName(null); + assertThat(buildInfoProperties(task)).doesNotContainKey("build.name"); + } + + @Test + void nameCanBeRemovedFromPropertiesUsingEmptyString() { + BuildInfo task = createTask(createProject("test")); + task.getProperties().setName(""); + assertThat(buildInfoProperties(task)).doesNotContainKey("build.name"); + } + @Test void projectVersionIsReflectedInProperties() { BuildInfo task = createTask(createProject("test")); @@ -97,6 +140,20 @@ class BuildInfoTests { assertThat(buildInfoProperties(task)).containsEntry("build.version", "2.3.4"); } + @Test + void versionCanBeRemovedFromPropertiesUsingNull() { + BuildInfo task = createTask(createProject("test")); + task.getProperties().setVersion(null); + assertThat(buildInfoProperties(task)).doesNotContainKey("build.version"); + } + + @Test + void versionCanBeRemovedFromPropertiesUsingEmptyString() { + BuildInfo task = createTask(createProject("test")); + task.getProperties().setVersion(""); + assertThat(buildInfoProperties(task)).doesNotContainKey("build.version"); + } + @Test void timeIsSetInProperties() { BuildInfo task = createTask(createProject("test")); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoIntegrationTests-removePropertiesUsingEmptyStrings.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoIntegrationTests-removePropertiesUsingEmptyStrings.gradle new file mode 100644 index 0000000000..f14ef603c3 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoIntegrationTests-removePropertiesUsingEmptyStrings.gradle @@ -0,0 +1,16 @@ +plugins { + id 'org.springframework.boot' version '{version}' apply false +} + +group = 'foo' +version = '0.1.0' + +task buildInfo(type: org.springframework.boot.gradle.tasks.buildinfo.BuildInfo) { + destinationDir project.buildDir + properties { + group = '' + artifact = '' + version = '' + name = '' + } +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoIntegrationTests-removePropertiesUsingNulls.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoIntegrationTests-removePropertiesUsingNulls.gradle new file mode 100644 index 0000000000..0ec0aba36c --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoIntegrationTests-removePropertiesUsingNulls.gradle @@ -0,0 +1,16 @@ +plugins { + id 'org.springframework.boot' version '{version}' apply false +} + +group = 'foo' +version = '0.1.0' + +task buildInfo(type: org.springframework.boot.gradle.tasks.buildinfo.BuildInfo) { + destinationDir project.buildDir + properties { + group = null + artifact = null + version = null + name = null + } +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/BuildPropertiesWriter.java b/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/BuildPropertiesWriter.java index 0ba85f4ecd..fe103f2101 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/BuildPropertiesWriter.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/BuildPropertiesWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2021 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. @@ -25,6 +25,7 @@ import java.util.Map; import java.util.Properties; import org.springframework.core.CollectionFactory; +import org.springframework.util.StringUtils; /** * A {@code BuildPropertiesWriter} writes the {@code build-info.properties} for @@ -32,6 +33,7 @@ import org.springframework.core.CollectionFactory; * * @author Andy Wilkinson * @author Stephane Nicoll + * @author Vedran Pavic * @since 1.0.0 */ public final class BuildPropertiesWriter { @@ -71,10 +73,10 @@ public final class BuildPropertiesWriter { protected Properties createBuildInfo(ProjectDetails project) { Properties properties = CollectionFactory.createSortedProperties(true); - properties.put("build.group", project.getGroup()); - properties.put("build.artifact", project.getArtifact()); - properties.put("build.name", project.getName()); - properties.put("build.version", project.getVersion()); + addIfHasValue(properties, "build.group", project.getGroup()); + addIfHasValue(properties, "build.artifact", project.getArtifact()); + addIfHasValue(properties, "build.name", project.getName()); + addIfHasValue(properties, "build.version", project.getVersion()); if (project.getTime() != null) { properties.put("build.time", DateTimeFormatter.ISO_INSTANT.format(project.getTime())); } @@ -84,6 +86,12 @@ public final class BuildPropertiesWriter { return properties; } + private void addIfHasValue(Properties properties, String name, String value) { + if (StringUtils.hasText(value)) { + properties.put(name, value); + } + } + /** * Build-system agnostic details of a project. */ diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/BuildInfoIntegrationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/BuildInfoIntegrationTests.java index bd28abeea9..3c648a0d98 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/BuildInfoIntegrationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/BuildInfoIntegrationTests.java @@ -35,6 +35,7 @@ import static org.assertj.core.api.Assertions.assertThat; * Integration tests for the Maven plugin's build info support. * * @author Andy Wilkinson + * @author Vedran Pavic */ @ExtendWith(MavenBuildExtension.class) class BuildInfoIntegrationTests { @@ -89,6 +90,21 @@ class BuildInfoIntegrationTests { .doesNotContainBuildTime())); } + @TestTemplate + void whenBuildTimeIsExcludedIfDoesNotAppearInGeneratedBuildInfo(MavenBuild mavenBuild) { + mavenBuild.project("build-info-exclude-build-time").execute(buildInfo((buildInfo) -> assertThat(buildInfo) + .hasBuildGroup("org.springframework.boot.maven.it").hasBuildArtifact("build-info-exclude-build-time") + .hasBuildName("Generate build info with excluded build time").hasBuildVersion("0.0.1.BUILD-SNAPSHOT") + .doesNotContainBuildTime())); + } + + @TestTemplate + void whenBuildPropertiesAreExcludedTheyDoNotAppearInGeneratedBuildInfo(MavenBuild mavenBuild) { + mavenBuild.project("build-info-exclude-build-properties").execute( + buildInfo((buildInfo) -> assertThat(buildInfo).doesNotContainBuildGroup().doesNotContainBuildArtifact() + .doesNotContainBuildName().doesNotContainBuildVersion().containsBuildTime())); + } + private ProjectCallback buildInfo(Consumer> buildInfo) { return buildInfo("target/classes/META-INF/build-info.properties", buildInfo); } @@ -130,18 +146,34 @@ class BuildInfoIntegrationTests { return containsEntry("build.group", expected); } + BuildInfoAssert doesNotContainBuildGroup() { + return doesNotContainKey("build.group"); + } + BuildInfoAssert hasBuildArtifact(String expected) { return containsEntry("build.artifact", expected); } + BuildInfoAssert doesNotContainBuildArtifact() { + return doesNotContainKey("build.artifact"); + } + BuildInfoAssert hasBuildName(String expected) { return containsEntry("build.name", expected); } + BuildInfoAssert doesNotContainBuildName() { + return doesNotContainKey("build.name"); + } + BuildInfoAssert hasBuildVersion(String expected) { return containsEntry("build.version", expected); } + BuildInfoAssert doesNotContainBuildVersion() { + return doesNotContainKey("build.version"); + } + BuildInfoAssert containsBuildTime() { return containsKey("build.time"); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/build-info-exclude-build-properties/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/build-info-exclude-build-properties/pom.xml new file mode 100644 index 0000000000..f58f33a49a --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/build-info-exclude-build-properties/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + org.springframework.boot.maven.it + build-info-exclude-build-properties + 0.0.1.BUILD-SNAPSHOT + Generate build info with excluded build properties + + UTF-8 + @java.version@ + @java.version@ + + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + + + group + artifact + version + name + + + + build-info + + + + + + + diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/build-info-exclude-build-properties/src/main/java/org/test/SampleApplication.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/build-info-exclude-build-properties/src/main/java/org/test/SampleApplication.java new file mode 100644 index 0000000000..16c76e92c5 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/build-info-exclude-build-properties/src/main/java/org/test/SampleApplication.java @@ -0,0 +1,24 @@ +/* + * Copyright 2012-2021 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.test; + +public class SampleApplication { + + public static void main(String[] args) { + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/build-info-exclude-build-time/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/build-info-exclude-build-time/pom.xml new file mode 100644 index 0000000000..e2d702508e --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/build-info-exclude-build-time/pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + org.springframework.boot.maven.it + build-info-exclude-build-time + 0.0.1.BUILD-SNAPSHOT + Generate build info with excluded build time + + UTF-8 + @java.version@ + @java.version@ + + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + + + time + + + + build-info + + + + + + + + + org.springframework + spring-context + @spring-framework.version@ + + + jakarta.servlet + jakarta.servlet-api + @jakarta-servlet.version@ + provided + + + diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/build-info-exclude-build-time/src/main/java/org/test/SampleApplication.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/build-info-exclude-build-time/src/main/java/org/test/SampleApplication.java new file mode 100644 index 0000000000..16c76e92c5 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/build-info-exclude-build-time/src/main/java/org/test/SampleApplication.java @@ -0,0 +1,24 @@ +/* + * Copyright 2012-2021 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.test; + +public class SampleApplication { + + public static void main(String[] args) { + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/BuildInfoMojo.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/BuildInfoMojo.java index 871d077e8c..c4b3a111ae 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/BuildInfoMojo.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/BuildInfoMojo.java @@ -19,6 +19,8 @@ package org.springframework.boot.maven; import java.io.File; import java.time.Instant; import java.util.Date; +import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import org.apache.maven.execution.MavenSession; @@ -41,6 +43,7 @@ import org.springframework.boot.loader.tools.BuildPropertiesWriter.ProjectDetail * {@link MavenProject}. * * @author Stephane Nicoll + * @author Vedran Pavic * @since 1.4.0 */ @Mojo(name = "build-info", defaultPhase = LifecyclePhase.GENERATE_RESOURCES, threadSafe = true) @@ -72,7 +75,7 @@ public class BuildInfoMojo extends AbstractMojo { * {@link Instant#parse(CharSequence)}. Defaults to * {@code project.build.outputTimestamp} or {@code session.request.startTime} if the * former is not set. To disable the {@code build.time} property entirely, use - * {@code 'off'}. + * {@code 'off'} or add it to {@code excludeInfoProperties}. * @since 2.2.0 */ @Parameter(defaultValue = "${project.build.outputTimestamp}") @@ -85,11 +88,19 @@ public class BuildInfoMojo extends AbstractMojo { @Parameter private Map additionalProperties; + /** + * Properties that should be excluded {@code build-info.properties} file. Can be used + * to exclude the standard {@code group}, {@code artifact}, {@code name}, + * {@code version} or {@code time} properties as well as items from + * {@code additionalProperties}. + */ + @Parameter + private List excludeInfoProperties; + @Override public void execute() throws MojoExecutionException, MojoFailureException { try { - ProjectDetails details = new ProjectDetails(this.project.getGroupId(), this.project.getArtifactId(), - this.project.getVersion(), this.project.getName(), getBuildTime(), this.additionalProperties); + ProjectDetails details = getProjectDetails(); new BuildPropertiesWriter(this.outputFile).writeBuildProperties(details); this.buildContext.refresh(this.outputFile); } @@ -101,6 +112,29 @@ public class BuildInfoMojo extends AbstractMojo { } } + private ProjectDetails getProjectDetails() { + String group = getIfNotExcluded("group", this.project.getGroupId()); + String artifact = getIfNotExcluded("artifact", this.project.getArtifactId()); + String version = getIfNotExcluded("version", this.project.getVersion()); + String name = getIfNotExcluded("name", this.project.getName()); + Instant time = getIfNotExcluded("time", getBuildTime()); + Map additionalProperties = applyExclusions(this.additionalProperties); + return new ProjectDetails(group, artifact, version, name, time, additionalProperties); + } + + private T getIfNotExcluded(String name, T value) { + return (this.excludeInfoProperties == null || !this.excludeInfoProperties.contains(name)) ? value : null; + } + + private Map applyExclusions(Map source) { + if (source == null || this.excludeInfoProperties == null) { + return source; + } + Map result = new LinkedHashMap<>(source); + this.excludeInfoProperties.forEach(result::remove); + return result; + } + private Instant getBuildTime() { if (this.time == null || this.time.isEmpty()) { Date startTime = this.session.getRequest().getStartTime();