Reputation: 1954
I wish to access the build information from inside my java project which uses gradle to build the project. The information I need to access is the build number generated by teamcity, build vcs number etc. These are easily accessed by maven and using the maven-replacer-plugin these can be replaced in a properties file. Firstly, is there an alternative in gradle to achieve the same? And then, how to do it? :)
I tried the approach shared here, but I always get null as the build number.
In maven I placed a properties file (project.properties) in the project to hold key value pairs with keys being those project information like
project.groupId, project.artifactId, project.version, maven.build.timestamp
I wish to access the same build information using gradle. . The pom would look like below:
<!-- Write project version number to file -->
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>maven-replacer-plugin</artifactId>
<version>1.3.8</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>
<!-- replace the token in this file -->
<include>target/classes/project.properties</include>
</includes>
<replacements>
<replacement>
<token>PROJECT_GROUP</token>
<value>${project.groupId}</value>
</replacement>
<replacement>
<token>PROJECT_ARTIFACT</token>
<value>${project.artifactId}</value>
</replacement>
<replacement>
<token>PROJECT_VERSION</token>
<value>${project.version}</value>
</replacement>
<replacement>
<token>PROJECT_BUILD_DATE</token>
<value>${maven.build.timestamp}</value>
</replacement>
<replacement>
<token>BUILD_NUMBER</token>
<value>${build.number}</value>
</replacement>
</replacements>
</configuration>
</plugin>
What the maven replacer plugin does is replace the values in the properties object, that can be used in the java application.
I need to access the same properties using gradle.
Team City configuration in the pom is below:
<ciManagement>
<system>Team City</system>
<url>http://teamcity.mycompany.com/teamcity/project.html?projectId=bt007
</url>
</ciManagement>
In the build.gradle
file, I have a task defined as below:
task getProjectGroup << {
ext.projectGroup = System.getProperty("project.group")
println "Project Group: $projectGroup"
}
I get the following output when executing this task:
:service:getProjectGroup
Project Group: null
BUILD SUCCESSFUL
Upvotes: 4
Views: 5267
Reputation: 5673
I do something very similar on my project - packaging up build info into a properties file that can be read from the classpath in your Java application.
Here's how I accomplish that in a Gradle script:
tasks.withType(Jar).all { Jar jar ->
jar.doFirst {
String jarType = jar.extension
if(jar.classifier) jarType = jar.classifier
String fileName = "project.properties"
ant.propertyfile(file: "${jar.temporaryDir}/${fileName}") {
entry(key: "PROJECT_GROUP", value: project.group)
entry(key: "PROJECT_ARTIFACT", value: project.archivesBaseName)
entry(key: "PROJECT_VERSION", value: project.version)
entry(key: "PROJECT_BUILD_DATE", value: new Date())
entry(key: "BUILD_NUMBER", value: hasProperty("teamcity") ? teamcity["build.number"] : "local")
}
String intoPath = "your/package/name/here/${project.name}/${jarType}"
jar.from(jar.temporaryDir) {
include fileName
if(jar instanceof War) intoPath = "WEB-INF/classes/${intoPath}"
into(intoPath)
}
println "\tCreated ${intoPath}/${fileName}"
}
}
Here, I'm adding functionality to every Jar
task (including War
) that creates a properties file for that archive and includes it on the classpath under your/package/name/here/${project.name}/${jarType}/project.properties
.
This is the beauty of Gradle. It makes customizations like this very simple - no plugin required.
Then, to read the properties in my app, I inject or hardcode the expected path to the file and load the properties like this:
public Properties lookupClassPathResource(String pathToResource) {
Properties p = null;
org.springframework.core.io.Resource r = new org.springframework.core.io.ClassPathResource(pathToResource);
if(r.exists()) {
try {
p = org.springframework.core.io.support.PropertiesLoaderUtils.loadProperties(r);
} catch (IOException e) {
//log or wrap/rethrow exception
}
}
return p;
}
And fun times are had by all!
EDIT: Apparently the question/answer linked in the OP (about accessing build.number
) is a little out-of-date. Instead of doing System.getProperty("build.number")
, you can use the teamcity
properties that TeamCity implicitly adds to your project via a Gradle init script. The code above has been modified to reflect this. Also see this question for other examples.
Upvotes: 1