diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/SpringBootExtension.java b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/SpringBootExtension.java
index e534317b2e..ae0a73d3ac 100644
--- a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/SpringBootExtension.java
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/SpringBootExtension.java
@@ -16,9 +16,15 @@
package org.springframework.boot.gradle;
+import java.io.File;
+import java.util.concurrent.Callable;
+
import org.gradle.api.Action;
import org.gradle.api.Project;
import org.gradle.api.plugins.JavaPlugin;
+import org.gradle.api.plugins.JavaPluginConvention;
+import org.gradle.api.tasks.SourceSet;
+import org.gradle.api.tasks.bundling.Jar;
import org.springframework.boot.gradle.buildinfo.BuildInfo;
@@ -43,7 +49,11 @@ public class SpringBootExtension {
/**
* Creates a new {@link BuildInfo} task named {@code bootBuildInfo} and configures the
- * {@code classes} task to depend upon it.
+ * Java plugin's {@code classes} task to depend upon it.
+ *
+ * By default, the task's destination dir will be a directory named {@code META-INF}
+ * beneath the main source set's resources output directory, and the task's project
+ * artifact will be the base name of the {@code bootWar} or {@code bootJar} task.
*/
public void buildInfo() {
this.buildInfo(null);
@@ -51,16 +61,39 @@ public class SpringBootExtension {
/**
* Creates a new {@link BuildInfo} task named {@code bootBuildInfo} and configures the
- * {@code classes} task to depend upon it. The task is passed to the given
- * {@code configurer} for further configuration.
+ * Java plugin's {@code classes} task to depend upon it. The task is passed to the
+ * given {@code configurer} for further configuration.
+ *
+ * By default, the task's destination dir will be a directory named {@code META-INF}
+ * beneath the main source set's resources output directory, and the task's project
+ * artifact will be the base name of the {@code bootWar} or {@code bootJar} task.
*
* @param configurer the task configurer
*/
public void buildInfo(Action configurer) {
BuildInfo bootBuildInfo = this.project.getTasks().create("bootBuildInfo",
BuildInfo.class);
- this.project.getTasks().getByName(JavaPlugin.CLASSES_TASK_NAME)
- .dependsOn(bootBuildInfo);
+ this.project.getPlugins().withType(JavaPlugin.class, (plugin) -> {
+ this.project.getTasks().getByName(JavaPlugin.CLASSES_TASK_NAME)
+ .dependsOn(bootBuildInfo);
+ bootBuildInfo.getConventionMapping().map("projectArtifact",
+ (Callable) () -> {
+ Jar artifactTask = (Jar) this.project.getTasks().findByName("bootWar");
+ if (artifactTask == null) {
+ artifactTask = (Jar) this.project.getTasks().findByName("bootJar");
+ }
+ String result = artifactTask == null ? null : artifactTask.getBaseName();
+ return result;
+ });
+ bootBuildInfo.getConventionMapping().map("destinationDir",
+ (Callable) () -> {
+ return new File(
+ this.project.getConvention().getPlugin(JavaPluginConvention.class)
+ .getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME)
+ .getOutput().getResourcesDir(),
+ "META-INF");
+ });
+ });
if (configurer != null) {
configurer.execute(bootBuildInfo);
}
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/buildinfo/BuildInfo.java b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/buildinfo/BuildInfo.java
index b7d30287f0..c88797ce61 100644
--- a/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/buildinfo/BuildInfo.java
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/buildinfo/BuildInfo.java
@@ -22,62 +22,53 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
-import org.gradle.api.DefaultTask;
-import org.gradle.api.plugins.JavaPlugin;
+import org.gradle.api.Task;
+import org.gradle.api.internal.ConventionTask;
import org.gradle.api.tasks.Input;
-import org.gradle.api.tasks.OutputFile;
+import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.TaskExecutionException;
-import org.gradle.api.tasks.bundling.Jar;
import org.springframework.boot.loader.tools.BuildPropertiesWriter;
import org.springframework.boot.loader.tools.BuildPropertiesWriter.ProjectDetails;
/**
- * {@link DefaultTask} for generating a {@code build-info.properties} file from a
- * {@code Project}.
- *
- * By default, the {@code build-info.properties} file is generated in
- * project.buildDir/resources/main/META-INF.
- *
+ * {@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.
*
* @author Andy Wilkinson
*/
-public class BuildInfo extends DefaultTask {
+public class BuildInfo extends ConventionTask {
- @OutputFile
- private File outputFile = getProject().file(new File(getProject().getBuildDir(),
- "resources/main/META-INF/build-info.properties"));
+ private File destinationDir;
- @Input
private String projectGroup = getProject().getGroup().toString();
- @Input
- private String projectArtifact = ((Jar) getProject().getTasks()
- .getByName(JavaPlugin.JAR_TASK_NAME)).getBaseName();
+ private String projectArtifact;
- @Input
private String projectVersion = getProject().getVersion().toString();
- @Input
private String projectName = getProject().getName();
- @Input
private Map additionalProperties = new HashMap<>();
@TaskAction
public void generateBuildProperties() {
try {
- new BuildPropertiesWriter(this.outputFile)
- .writeBuildProperties(new ProjectDetails(this.projectGroup,
- this.projectArtifact, this.projectVersion, this.projectName,
- coerceToStringValues(this.additionalProperties)));
+ new BuildPropertiesWriter(
+ new File(getDestinationDir(), "build-info.properties"))
+ .writeBuildProperties(new ProjectDetails(this.projectGroup,
+ getProjectArtifact(), this.projectVersion,
+ this.projectName,
+ coerceToStringValues(this.additionalProperties)));
}
catch (IOException ex) {
throw new TaskExecutionException(this, ex);
}
}
+ @Input
public String getProjectGroup() {
return this.projectGroup;
}
@@ -86,6 +77,7 @@ public class BuildInfo extends DefaultTask {
this.projectGroup = projectGroup;
}
+ @Input
public String getProjectArtifact() {
return this.projectArtifact;
}
@@ -94,6 +86,7 @@ public class BuildInfo extends DefaultTask {
this.projectArtifact = projectArtifact;
}
+ @Input
public String getProjectVersion() {
return this.projectVersion;
}
@@ -102,6 +95,7 @@ public class BuildInfo extends DefaultTask {
this.projectVersion = projectVersion;
}
+ @Input
public String getProjectName() {
return this.projectName;
}
@@ -110,14 +104,16 @@ public class BuildInfo extends DefaultTask {
this.projectName = projectName;
}
- public File getOutputFile() {
- return this.outputFile;
+ @OutputDirectory
+ public File getDestinationDir() {
+ return this.destinationDir;
}
- public void setOutputFile(File outputFile) {
- this.outputFile = outputFile;
+ public void setDestinationDir(File destinationDir) {
+ this.destinationDir = destinationDir;
}
+ @Input
public Map getAdditionalProperties() {
return this.additionalProperties;
}
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/buildinfo/BuildInfoDslIntegrationTests.java b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/buildinfo/BuildInfoDslIntegrationTests.java
new file mode 100644
index 0000000000..01fd1a622f
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/buildinfo/BuildInfoDslIntegrationTests.java
@@ -0,0 +1,128 @@
+/*
+ * 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.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;
+
+import org.springframework.boot.gradle.testkit.GradleBuild;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Integration tests for {@link BuildInfo} created using the
+ * {@link org.springframework.boot.gradle.SpringBootExtension DSL}.
+ *
+ * @author Andy Wilkinson
+ */
+public class BuildInfoDslIntegrationTests {
+
+ @Rule
+ public final GradleBuild gradleBuild = new GradleBuild();
+
+ @Test
+ public void basicJar() throws IOException {
+ assertThat(this.gradleBuild.build("bootBuildInfo", "--stacktrace")
+ .task(":bootBuildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
+ Properties properties = buildInfoProperties();
+ assertThat(properties).containsEntry("build.name",
+ this.gradleBuild.getProjectDir().getName());
+ assertThat(properties).containsEntry("build.artifact",
+ this.gradleBuild.getProjectDir().getName());
+ assertThat(properties).containsEntry("build.group", "com.example");
+ assertThat(properties).containsEntry("build.version", "1.0");
+ }
+
+ @Test
+ public void jarWithCustomName() throws IOException {
+ assertThat(this.gradleBuild.build("bootBuildInfo", "--stacktrace")
+ .task(":bootBuildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
+ Properties properties = buildInfoProperties();
+ assertThat(properties).containsEntry("build.name",
+ this.gradleBuild.getProjectDir().getName());
+ assertThat(properties).containsEntry("build.artifact", "foo");
+ assertThat(properties).containsEntry("build.group", "com.example");
+ assertThat(properties).containsEntry("build.version", "1.0");
+ }
+
+ @Test
+ public void basicWar() throws IOException {
+ assertThat(this.gradleBuild.build("bootBuildInfo", "--stacktrace")
+ .task(":bootBuildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
+ Properties properties = buildInfoProperties();
+ assertThat(properties).containsEntry("build.name",
+ this.gradleBuild.getProjectDir().getName());
+ assertThat(properties).containsEntry("build.artifact",
+ this.gradleBuild.getProjectDir().getName());
+ assertThat(properties).containsEntry("build.group", "com.example");
+ assertThat(properties).containsEntry("build.version", "1.0");
+ }
+
+ @Test
+ public void warWithCustomName() throws IOException {
+ assertThat(this.gradleBuild.build("bootBuildInfo", "--stacktrace")
+ .task(":bootBuildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
+ Properties properties = buildInfoProperties();
+ assertThat(properties).containsEntry("build.name",
+ this.gradleBuild.getProjectDir().getName());
+ assertThat(properties).containsEntry("build.artifact", "foo");
+ assertThat(properties).containsEntry("build.group", "com.example");
+ assertThat(properties).containsEntry("build.version", "1.0");
+ }
+
+ @Test
+ public void additionalProperties() throws IOException {
+ assertThat(this.gradleBuild.build("bootBuildInfo", "--stacktrace")
+ .task(":bootBuildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
+ Properties properties = buildInfoProperties();
+ assertThat(properties).containsEntry("build.name",
+ this.gradleBuild.getProjectDir().getName());
+ assertThat(properties).containsEntry("build.artifact",
+ this.gradleBuild.getProjectDir().getName());
+ assertThat(properties).containsEntry("build.group", "com.example");
+ assertThat(properties).containsEntry("build.version", "1.0");
+ assertThat(properties).containsEntry("build.a", "alpha");
+ assertThat(properties).containsEntry("build.b", "bravo");
+ }
+
+ @Test
+ public void classesDependency() throws IOException {
+ assertThat(this.gradleBuild.build("classes", "--stacktrace")
+ .task(":bootBuildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
+ }
+
+ private Properties buildInfoProperties() {
+ File file = new File(this.gradleBuild.getProjectDir(),
+ "build/resources/main/META-INF/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/buildinfo/BuildInfoIntegrationTests.java b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/buildinfo/BuildInfoIntegrationTests.java
new file mode 100644
index 0000000000..ddeac1bb97
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/buildinfo/BuildInfoIntegrationTests.java
@@ -0,0 +1,88 @@
+/*
+ * 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.buildinfo;
+
+import org.gradle.testkit.runner.TaskOutcome;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.springframework.boot.gradle.testkit.GradleBuild;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Integration tests for {@link BuildInfo}.
+ *
+ * @author Andy Wilkinson
+ */
+public class BuildInfoIntegrationTests {
+
+ @Rule
+ public final GradleBuild gradleBuild = new GradleBuild();
+
+ @Test
+ public void basicExecution() {
+ assertThat(this.gradleBuild.build("buildInfo").task(":buildInfo").getOutcome())
+ .isEqualTo(TaskOutcome.SUCCESS);
+ }
+
+ @Test
+ public void upToDateWhenExecutedTwice() {
+ assertThat(this.gradleBuild.build("buildInfo").task(":buildInfo").getOutcome())
+ .isEqualTo(TaskOutcome.SUCCESS);
+ assertThat(this.gradleBuild.build("buildInfo").task(":buildInfo").getOutcome())
+ .isEqualTo(TaskOutcome.UP_TO_DATE);
+ }
+
+ @Test
+ public void notUpToDateWhenDestinationDirChanges() {
+ notUpToDateWithChangeToProperty("buildInfoDestinationDir");
+ }
+
+ @Test
+ public void notUpToDateWhenProjectArtifactChanges() {
+ notUpToDateWithChangeToProperty("buildInfoProjectArtifact");
+ }
+
+ @Test
+ public void notUpToDateWhenProjectGroupChanges() {
+ notUpToDateWithChangeToProperty("buildInfoProjectGroup");
+ }
+
+ @Test
+ public void notUpToDateWhenProjectVersionChanges() {
+ notUpToDateWithChangeToProperty("buildInfoProjectVersion");
+ }
+
+ @Test
+ public void notUpToDateWhenProjectNameChanges() {
+ notUpToDateWithChangeToProperty("buildInfoProjectName");
+ }
+
+ @Test
+ public void notUpToDateWhenAdditionalPropertyChanges() {
+ notUpToDateWithChangeToProperty("buildInfoAdditionalProperty");
+ }
+
+ private void notUpToDateWithChangeToProperty(String name) {
+ assertThat(this.gradleBuild.build("buildInfo").task(":buildInfo").getOutcome())
+ .isEqualTo(TaskOutcome.SUCCESS);
+ assertThat(this.gradleBuild.build("buildInfo", "-P" + name + "=changed")
+ .task(":buildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
+ }
+
+}
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/buildinfo/BuildInfoDslIntegrationTests-additionalProperties.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/buildinfo/BuildInfoDslIntegrationTests-additionalProperties.gradle
new file mode 100644
index 0000000000..93162070be
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/buildinfo/BuildInfoDslIntegrationTests-additionalProperties.gradle
@@ -0,0 +1,17 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'java'
+
+group = 'com.example'
+version = '1.0'
+
+springBoot {
+ buildInfo {
+ additionalProperties 'a': 'alpha', 'b': 'bravo'
+ }
+}
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/buildinfo/BuildInfoDslIntegrationTests-basicJar.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/buildinfo/BuildInfoDslIntegrationTests-basicJar.gradle
new file mode 100644
index 0000000000..92cd745563
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/buildinfo/BuildInfoDslIntegrationTests-basicJar.gradle
@@ -0,0 +1,15 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'java'
+
+group = 'com.example'
+version = '1.0'
+
+springBoot {
+ buildInfo()
+}
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/buildinfo/BuildInfoDslIntegrationTests-basicWar.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/buildinfo/BuildInfoDslIntegrationTests-basicWar.gradle
new file mode 100644
index 0000000000..6a627257c2
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/buildinfo/BuildInfoDslIntegrationTests-basicWar.gradle
@@ -0,0 +1,15 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'war'
+
+group = 'com.example'
+version = '1.0'
+
+springBoot {
+ buildInfo()
+}
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/buildinfo/BuildInfoDslIntegrationTests-classesDependency.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/buildinfo/BuildInfoDslIntegrationTests-classesDependency.gradle
new file mode 100644
index 0000000000..e217894ff2
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/buildinfo/BuildInfoDslIntegrationTests-classesDependency.gradle
@@ -0,0 +1,12 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'java'
+
+springBoot {
+ buildInfo()
+}
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/buildinfo/BuildInfoDslIntegrationTests-jarWithCustomName.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/buildinfo/BuildInfoDslIntegrationTests-jarWithCustomName.gradle
new file mode 100644
index 0000000000..adb3428ee0
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/buildinfo/BuildInfoDslIntegrationTests-jarWithCustomName.gradle
@@ -0,0 +1,19 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'java'
+
+group = 'com.example'
+version = '1.0'
+
+bootJar {
+ baseName = 'foo'
+}
+
+springBoot {
+ buildInfo()
+}
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/buildinfo/BuildInfoDslIntegrationTests-warWithCustomName.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/buildinfo/BuildInfoDslIntegrationTests-warWithCustomName.gradle
new file mode 100644
index 0000000000..e679477c15
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/buildinfo/BuildInfoDslIntegrationTests-warWithCustomName.gradle
@@ -0,0 +1,19 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'war'
+
+group = 'com.example'
+version = '1.0'
+
+bootWar {
+ baseName = 'foo'
+}
+
+springBoot {
+ buildInfo()
+}
diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/buildinfo/BuildInfoIntegrationTests.gradle b/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/buildinfo/BuildInfoIntegrationTests.gradle
new file mode 100644
index 0000000000..fe973b6bee
--- /dev/null
+++ b/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/buildinfo/BuildInfoIntegrationTests.gradle
@@ -0,0 +1,18 @@
+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.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')
+}