From b9b402e3db05dd5e737e578be15a59f1d4e618f7 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 30 Mar 2017 12:06:10 +0100 Subject: [PATCH] Rework BuildInfo to separate task and build info properties Previously, the properties that applied to the BuildInfo task itself and those that would be written into the build-info.properties file were all configured on BuildInfo directly. This lack of separation could be confusing. This commit rework BuildInfo to separate the task's own properties from those that are written into the build-info.properties file. The task has also been updated so that changes to a project's properties made after the task has been configured are reflected in the build info properties. --- .../boot/gradle/dsl/SpringBootExtension.java | 9 +- .../gradle/tasks/buildinfo/BuildInfo.java | 101 ++++----- .../tasks/buildinfo/BuildInfoProperties.java | 212 ++++++++++++++++++ .../buildinfo/BuildInfoIntegrationTests.java | 53 ++++- .../tasks/buildinfo/BuildInfoTests.java | 136 +++++++++++ ...tegrationTests-additionalProperties.gradle | 6 +- ...dInfoIntegrationTests-defaultValues.gradle | 11 + .../BuildInfoIntegrationTests.gradle | 12 +- 8 files changed, 468 insertions(+), 72 deletions(-) create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoProperties.java create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoTests.java create mode 100644 spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoIntegrationTests-defaultValues.gradle diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/dsl/SpringBootExtension.java b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/dsl/SpringBootExtension.java index 8cbb99bc6c..468dd12303 100644 --- a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/dsl/SpringBootExtension.java +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/dsl/SpringBootExtension.java @@ -27,6 +27,7 @@ import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.bundling.Jar; import org.springframework.boot.gradle.tasks.buildinfo.BuildInfo; +import org.springframework.boot.gradle.tasks.buildinfo.BuildInfoProperties; /** * Entry point to Spring Boot's Gradle DSL. @@ -76,8 +77,12 @@ public class SpringBootExtension { this.project.getPlugins().withType(JavaPlugin.class, plugin -> { this.project.getTasks().getByName(JavaPlugin.CLASSES_TASK_NAME) .dependsOn(bootBuildInfo); - bootBuildInfo.getConventionMapping().map("projectArtifact", - (Callable) () -> determineArtifactBaseName()); + this.project.afterEvaluate(evaluated -> { + BuildInfoProperties properties = bootBuildInfo.getProperties(); + if (properties.getArtifact() == null) { + properties.setArtifact(determineArtifactBaseName()); + } + }); bootBuildInfo.getConventionMapping() .map("destinationDir", (Callable) () -> new File( diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfo.java b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfo.java index 1f4239e702..273f7600e7 100644 --- a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfo.java +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfo.java @@ -22,6 +22,8 @@ import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; +import org.gradle.api.Action; +import org.gradle.api.Project; import org.gradle.api.Task; import org.gradle.api.internal.ConventionTask; import org.gradle.api.tasks.Input; @@ -34,92 +36,77 @@ import org.springframework.boot.loader.tools.BuildPropertiesWriter.ProjectDetail /** * {@link Task} for generating a {@code build-info.properties} file from a - * {@code Project}. The {@link #setDestinationDir destination dir} and - * {@link #setProjectArtifact project artifact} must be configured before execution. + * {@code Project}. * * @author Andy Wilkinson */ public class BuildInfo extends ConventionTask { + private final BuildInfoProperties properties = new BuildInfoProperties(getProject()); + private File destinationDir; - private String projectGroup = getProject().getGroup().toString(); - - private String projectArtifact; - - private String projectVersion = getProject().getVersion().toString(); - - private String projectName = getProject().getName(); - - private Map additionalProperties = new HashMap<>(); - + /** + * Generates the {@code build-info.properties} file in the configured + * {@link #setDestinationDir(File) destination}. + */ @TaskAction public void generateBuildProperties() { try { new BuildPropertiesWriter( new File(getDestinationDir(), "build-info.properties")) - .writeBuildProperties(new ProjectDetails(this.projectGroup, - getProjectArtifact(), this.projectVersion, - this.projectName, - coerceToStringValues(this.additionalProperties))); + .writeBuildProperties(new ProjectDetails( + this.properties.getGroup(), + this.properties.getArtifact() == null ? "unspecified" + : this.properties.getArtifact(), + this.properties.getVersion(), + this.properties.getName(), coerceToStringValues( + this.properties.getAdditional()))); } catch (IOException ex) { throw new TaskExecutionException(this, ex); } } - @Input - public String getProjectGroup() { - return this.projectGroup; - } - - public void setProjectGroup(String projectGroup) { - this.projectGroup = projectGroup; - } - - @Input - public String getProjectArtifact() { - return this.projectArtifact; - } - - public void setProjectArtifact(String projectArtifact) { - this.projectArtifact = projectArtifact; - } - - @Input - public String getProjectVersion() { - return this.projectVersion; - } - - public void setProjectVersion(String projectVersion) { - this.projectVersion = projectVersion; - } - - @Input - public String getProjectName() { - return this.projectName; - } - - public void setProjectName(String projectName) { - this.projectName = projectName; - } - + /** + * Returns the directory to which the {@code build-info.properties} file will be + * written. Defaults to the {@link Project#getBuildDir() Project's build directory}. + * + * @return the destination directory + */ @OutputDirectory public File getDestinationDir() { - return this.destinationDir; + return this.destinationDir != null ? this.destinationDir + : getProject().getBuildDir(); } + /** + * Sets the directory to which the {@code build-info.properties} file will be written. + * + * @param destinationDir the destination directory + */ public void setDestinationDir(File destinationDir) { this.destinationDir = destinationDir; } + /** + * Returns the {@link BuildInfoProperties properties} that will be included in the + * {@code build-info.properties} file. + * + * @return the properties + */ @Input - public Map getAdditionalProperties() { - return this.additionalProperties; + public BuildInfoProperties getProperties() { + return this.properties; } - public void setAdditionalProperties(Map additionalProperties) { - this.additionalProperties = additionalProperties; + /** + * Executes the given {@code action} on the {@link #getProperties()} properties. + * + * @param action the action + */ + public void properties(Action action) { + action.execute(this.properties); } private Map coerceToStringValues(Map input) { diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoProperties.java b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoProperties.java new file mode 100644 index 0000000000..6cbc243ef0 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoProperties.java @@ -0,0 +1,212 @@ +/* + * Copyright 2012-2017 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 + * + * http://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.springframework.boot.gradle.tasks.buildinfo; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import org.gradle.api.Project; + +/** + * The properties that are written into the {@code build-info.properties} file. + * + * @author Andy Wilkinson + */ +public class BuildInfoProperties implements Serializable { + + private final transient Project project; + + private String group; + + private String artifact; + + private String version; + + private String name; + + private Map additionalProperties = new HashMap<>(); + + BuildInfoProperties(Project project) { + this.project = project; + } + + /** + * Returns the value used for the {@code build.group} property. Defaults to the + * {@link Project#getGroup() Project's group}. + * + * @return the group + */ + public String getGroup() { + return this.group != null ? this.group : this.project.getGroup().toString(); + } + + /** + * Sets the value used for the {@code build.group} property. + * + * @param group the group name + */ + public void setGroup(String group) { + this.group = group; + } + + /** + * Returns the value used for the {@code build.artifact} property. + * + * @return the artifact + */ + public String getArtifact() { + return this.artifact; + } + + /** + * Sets the value used for the {@code build.artifact} property. + * + * @param artifact the artifact + */ + public void setArtifact(String artifact) { + this.artifact = artifact; + } + + /** + * Returns the value used for the {@code build.version} property. Defaults to the + * {@link Project#getVersion() Project's version}. + * + * @return the version + */ + public String getVersion() { + return this.version != null ? this.version : this.project.getVersion().toString(); + } + + /** + * Sets the value used for the {@code build.version} property. + * + * @param version the version + */ + public void setVersion(String version) { + this.version = version; + } + + /** + * Returns the value used for the {@code build.name} property. Defaults to the + * {@link Project#getDisplayName() Project's display name}. + * + * @return the name + */ + public String getName() { + return this.name != null ? this.name : this.project.getName(); + } + + /** + * Sets the value used for the {@code build.name} property. + * + * @param name the name + */ + public void setName(String name) { + this.name = name; + } + + /** + * Returns the additional properties that will be included. When written, the name of + * each additional property is prefixed with {@code build.}. + * + * @return the additional properties + */ + public Map getAdditional() { + return this.additionalProperties; + } + + /** + * Sets the additional properties that will be included. When written, the name of + * each additional property is prefixed with {@code build.}. + * + * @param additionalProperties the additional properties + */ + public void setAdditional(Map additionalProperties) { + this.additionalProperties = additionalProperties; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.additionalProperties == null) ? 0 + : this.additionalProperties.hashCode()); + result = prime * result + + ((this.artifact == null) ? 0 : this.artifact.hashCode()); + result = prime * result + ((this.group == null) ? 0 : this.group.hashCode()); + result = prime * result + ((this.name == null) ? 0 : this.name.hashCode()); + result = prime * result + ((this.version == null) ? 0 : this.version.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + BuildInfoProperties other = (BuildInfoProperties) obj; + if (this.additionalProperties == null) { + if (other.additionalProperties != null) { + return false; + } + } + else if (!this.additionalProperties.equals(other.additionalProperties)) { + return false; + } + if (this.artifact == null) { + if (other.artifact != null) { + return false; + } + } + else if (!this.artifact.equals(other.artifact)) { + return false; + } + if (this.group == null) { + if (other.group != null) { + return false; + } + } + else if (!this.group.equals(other.group)) { + return false; + } + if (this.name == null) { + if (other.name != null) { + return false; + } + } + else if (!this.name.equals(other.name)) { + return false; + } + if (this.version == null) { + if (other.version != null) { + return false; + } + } + else if (!this.version.equals(other.version)) { + return false; + } + return true; + } + +} diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoIntegrationTests.java b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoIntegrationTests.java index 41603256d1..fac2498efa 100644 --- a/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoIntegrationTests.java +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoIntegrationTests.java @@ -16,6 +16,11 @@ package org.springframework.boot.gradle.tasks.buildinfo; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.Properties; + import org.gradle.testkit.runner.TaskOutcome; import org.junit.Rule; import org.junit.Test; @@ -34,10 +39,30 @@ public class BuildInfoIntegrationTests { @Rule public final GradleBuild gradleBuild = new GradleBuild(); + @Test + public void defaultValues() { + 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).containsEntry("build.name", + this.gradleBuild.getProjectDir().getName()); + assertThat(buildInfoProperties).containsEntry("build.version", "unspecified"); + } + @Test public void basicExecution() { assertThat(this.gradleBuild.build("buildInfo").task(":buildInfo").getOutcome()) .isEqualTo(TaskOutcome.SUCCESS); + Properties buildInfoProperties = buildInfoProperties(); + assertThat(buildInfoProperties).containsKey("build.time"); + assertThat(buildInfoProperties).containsEntry("build.artifact", "foo"); + assertThat(buildInfoProperties).containsEntry("build.group", "foo"); + assertThat(buildInfoProperties).containsEntry("build.additional", "foo"); + assertThat(buildInfoProperties).containsEntry("build.name", "foo"); + assertThat(buildInfoProperties).containsEntry("build.version", "1.0"); } @Test @@ -55,34 +80,48 @@ public class BuildInfoIntegrationTests { @Test public void notUpToDateWhenProjectArtifactChanges() { - notUpToDateWithChangeToProperty("buildInfoProjectArtifact"); + notUpToDateWithChangeToProperty("buildInfoArtifact"); } @Test public void notUpToDateWhenProjectGroupChanges() { - notUpToDateWithChangeToProperty("buildInfoProjectGroup"); + notUpToDateWithChangeToProperty("buildInfoGroup"); } @Test public void notUpToDateWhenProjectVersionChanges() { - notUpToDateWithChangeToProperty("buildInfoProjectVersion"); + notUpToDateWithChangeToProperty("buildInfoVersion"); } @Test public void notUpToDateWhenProjectNameChanges() { - notUpToDateWithChangeToProperty("buildInfoProjectName"); + notUpToDateWithChangeToProperty("buildInfoName"); } @Test public void notUpToDateWhenAdditionalPropertyChanges() { - notUpToDateWithChangeToProperty("buildInfoAdditionalProperty"); + notUpToDateWithChangeToProperty("buildInfoAdditional"); } private void notUpToDateWithChangeToProperty(String name) { - assertThat(this.gradleBuild.build("buildInfo").task(":buildInfo").getOutcome()) - .isEqualTo(TaskOutcome.SUCCESS); + assertThat(this.gradleBuild.build("buildInfo", "--stacktrace").task(":buildInfo") + .getOutcome()).isEqualTo(TaskOutcome.SUCCESS); assertThat(this.gradleBuild.build("buildInfo", "-P" + name + "=changed") .task(":buildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); } + private Properties buildInfoProperties() { + File file = new File(this.gradleBuild.getProjectDir(), + "build/build-info.properties"); + assertThat(file).isFile(); + Properties properties = new Properties(); + try (FileReader reader = new FileReader(file)) { + properties.load(reader); + return properties; + } + catch (IOException ex) { + throw new RuntimeException(ex); + } + } + } diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoTests.java b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoTests.java new file mode 100644 index 0000000000..f459919e61 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoTests.java @@ -0,0 +1,136 @@ +/* + * Copyright 2012-2017 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 + * + * http://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.springframework.boot.gradle.tasks.buildinfo; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.Properties; + +import org.gradle.api.Project; +import org.gradle.testfixtures.ProjectBuilder; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link BuildInfo}. + * + * @author Andy Wilkinson + */ +public class BuildInfoTests { + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + @Test + public 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).containsEntry("build.name", "test"); + assertThat(properties).containsEntry("build.version", "unspecified"); + } + + @Test + public void customArtifactIsReflectedInProperties() { + BuildInfo task = createTask(createProject("test")); + task.getProperties().setArtifact("custom"); + assertThat(buildInfoProperties(task)).containsEntry("build.artifact", "custom"); + } + + @Test + public void projectGroupIsReflectedInProperties() { + BuildInfo task = createTask(createProject("test")); + task.getProject().setGroup("com.example"); + assertThat(buildInfoProperties(task)).containsEntry("build.group", "com.example"); + } + + @Test + public void customGroupIsReflectedInProperties() { + BuildInfo task = createTask(createProject("test")); + task.getProperties().setGroup("com.example"); + assertThat(buildInfoProperties(task)).containsEntry("build.group", "com.example"); + } + + @Test + public void customNameIsReflectedInProperties() { + BuildInfo task = createTask(createProject("test")); + task.getProperties().setName("Example"); + assertThat(buildInfoProperties(task)).containsEntry("build.name", "Example"); + } + + @Test + public void projectVersionIsReflectedInProperties() { + BuildInfo task = createTask(createProject("test")); + task.getProject().setVersion("1.2.3"); + assertThat(buildInfoProperties(task)).containsEntry("build.version", "1.2.3"); + } + + @Test + public void customVersionIsReflectedInProperties() { + BuildInfo task = createTask(createProject("test")); + task.getProperties().setVersion("2.3.4"); + assertThat(buildInfoProperties(task)).containsEntry("build.version", "2.3.4"); + } + + @Test + public void additionalPropertiesAreReflectedInProperties() { + BuildInfo task = createTask(createProject("test")); + task.getProperties().getAdditional().put("a", "alpha"); + task.getProperties().getAdditional().put("b", "bravo"); + assertThat(buildInfoProperties(task)).containsEntry("build.a", "alpha"); + assertThat(buildInfoProperties(task)).containsEntry("build.b", "bravo"); + } + + private Project createProject(String projectName) { + try { + File projectDir = this.temp.newFolder(projectName); + return ProjectBuilder.builder().withProjectDir(projectDir) + .withName(projectName).build(); + } + catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + private BuildInfo createTask(Project project) { + return project.getTasks().create("testBuildInfo", BuildInfo.class); + } + + private Properties buildInfoProperties(BuildInfo task) { + task.generateBuildProperties(); + return buildInfoProperties( + new File(task.getDestinationDir(), "build-info.properties")); + } + + private Properties buildInfoProperties(File file) { + assertThat(file).isFile(); + Properties properties = new Properties(); + try (FileReader reader = new FileReader(file)) { + properties.load(reader); + return properties; + } + catch (IOException ex) { + throw new RuntimeException(ex); + } + } + +} diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/dsl/BuildInfoDslIntegrationTests-additionalProperties.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/dsl/BuildInfoDslIntegrationTests-additionalProperties.gradle index 93162070be..4335ef8445 100644 --- a/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/dsl/BuildInfoDslIntegrationTests-additionalProperties.gradle +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/dsl/BuildInfoDslIntegrationTests-additionalProperties.gradle @@ -12,6 +12,10 @@ version = '1.0' springBoot { buildInfo { - additionalProperties 'a': 'alpha', 'b': 'bravo' + properties { + additionalProperties = [ + 'a': 'alpha', 'b': 'bravo' + ] + } } } diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoIntegrationTests-defaultValues.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoIntegrationTests-defaultValues.gradle new file mode 100644 index 0000000000..2fe8266de8 --- /dev/null +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoIntegrationTests-defaultValues.gradle @@ -0,0 +1,11 @@ +buildscript { + dependencies { + classpath files(pluginClasspath.split(',')) + } +} + +def property(String name, Object defaultValue) { + project.hasProperty(name) ? project.getProperty(name) : defaultValue +} + +task buildInfo(type: org.springframework.boot.gradle.tasks.buildinfo.BuildInfo) diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoIntegrationTests.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoIntegrationTests.gradle index 23db1b2d8b..26ce586d5b 100644 --- a/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoIntegrationTests.gradle +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/buildinfo/BuildInfoIntegrationTests.gradle @@ -10,9 +10,11 @@ def property(String name, Object defaultValue) { task buildInfo(type: org.springframework.boot.gradle.tasks.buildinfo.BuildInfo) { destinationDir file(property('buildInfoDestinationDir', project.buildDir)) - projectArtifact property('buildInfoProjectArtifact', 'foo') - projectVersion property('buildInfoProjectVersion', '1.0') - projectGroup property('buildInfoProjectGroup', 'foo') - projectName property('buildInfoProjectName', 'foo') - additionalProperties 'additional': property('buildInfoAdditionalProperty', 'foo') + properties { + artifact = property('buildInfoArtifact', 'foo') + version = property('buildInfoVersion', '1.0') + group = property('buildInfoGroup', 'foo') + name = property('buildInfoName', 'foo') + additional = ['additional': property('buildInfoAdditional', 'foo')] + } }