I am trying to implement a gradle task to dynamically create a buildsignature.properties file from a series of environment variable values and shell executions. I have it mostly working, but I can't seem to get the output of the shell commands. Here's my task...
task generateBuildSignature << {
ext.whoami = exec() {
executable = "whoami"
}
ext.hostname = exec() {
executable = "hostname"
}
ext.buildTag = System.env.BUILD_TAG ?: "dev"
ant.propertyfile(
file: "${buildDir}/buildsignature.properties",
comment: "This file is automatically generated - DO NOT EDIT!" ) {
entry( key: "version", value: "${project.version}" )
entry( key: "buildTimestamp", value: "${new Date().format('yyyy-MM-dd HH:mm:ss z')}" )
entry( key: "buildUser", value: "${ext.whoami}" )
entry( key: "buildSystem", value: "${ext.hostname}" )
entry( key: "buildTag", value: "$ext.buildTag" )
}
}
But the resulting properties field does not get the desired results for buildUser and buildSystem.
#This file is automatically generated - DO NOT EDIT!
#Mon, 18 Jun 2012 18:14:14 -0700
version=1.1.0
buildTimestamp=2012-06-18 18\:14\:14 PDT
buildUser=org.gradle.process.internal.DefaultExecHandle$ExecResultImpl@2e6a54f9
buildSystem=org.gradle.process.internal.DefaultExecHandle$ExecResultImpl@46f0bf3d
buildTag=dev
How do I get buildUser and buildSystem to match the output of the corresponding exec rather than some default ExecResultImpl toString? This really can't be that hard, can it?
This post describes how to parse the output from an Exec
invocation. Below you'll find two tasks that run your commands.
task setWhoamiProperty {
doLast {
new ByteArrayOutputStream().withStream { os ->
def result = exec {
executable = 'whoami'
standardOutput = os
}
ext.whoami = os.toString()
}
}
}
task setHostnameProperty {
doLast {
new ByteArrayOutputStream().withStream { os ->
def result = exec {
executable = 'hostname'
standardOutput = os
}
ext.hostname = os.toString()
}
}
}
task printBuildInfo {
dependsOn setWhoamiProperty, setHostnameProperty
doLast {
println whoami
println hostname
}
}
There's actually an easier way to get this information without having to invoke a shell command.
Currently logged in user: System.getProperty('user.name')
Hostname: InetAddress.getLocalHost().getHostName()
This is my preferred syntax for getting the stdout from exec:
def stdout = new ByteArrayOutputStream()
exec{
commandLine "whoami"
standardOutput = stdout;
}
println "Output:\n$stdout";
Found here: http://gradle.1045684.n5.nabble.com/external-process-execution-td1431883.html
(Note that page has a typo though and mentions ByteArrayInputStream instead of ByteArrayOutputStream)
Paraphrased from the Gradle docs for Exec:
task execSomething {
doFirst {
exec {
workingDir '/some/dir'
commandLine '/some/command', 'arg'
...
//store the output instead of printing to the console:
standardOutput = new ByteArrayOutputStream()
//extension method execSomething.output() can be used to obtain the output:
ext.output = {
return standardOutput.toString()
}
}
}
}
Using the kotlin-dsl
:
import java.io.ByteArrayOutputStream
val outputText: String = ByteArrayOutputStream().use { outputStream ->
project.exec {
commandLine("whoami")
standardOutput = outputStream
}
outputStream.toString()
}