gradle

How to use exec() output in gradle


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?


Solution

  • 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()