Laurence Gonsalves
Laurence Gonsalves

Reputation: 143104

How can I ask gradle for the value of a property from the command line?

For example, if I wanted a shell script to be able to get the value of rootProject.name, how could I do this? Ideally, I'd like to invoke ./gradlew with some set of arguments and have it print the property value (and nothing else) to stdout.

Upvotes: 7

Views: 12289

Answers (2)

Stefan Hüttemann
Stefan Hüttemann

Reputation: 222

If it is still relevant ...

Possible Solution A: print value of "rootProject.name" on cmd line

Add task in build.gradle:

/**
 * Prints value of property "rootProject.name" to stdout.
 *
 * Usage: ./gradlew -q printRootProjectName
 */
task printRootProjectName {
  doLast {
    println(project.findProperty('rootProject').name)
  }
}

Possible Solution B: print a property value as provided on cmd line

Add task in build.gradle:

/**
 * Print value of property provided in "-Pprop" on command line to stdout.
 *
 * Usage Example: ./gradlew -q printProperty -Pprop=rootProject.name
 */
task printProperty {
  doLast {
    // get the "property name" in question from commandline:
    String prop = project.findProperty('prop')
    if (prop == null) {
      return // or use println ...
    }

    // treat as property name:
    Object theProperty = project.findProperty(prop)

    if (null == theProperty) {
      // try to handle provided information as "nested property"
      List < String > thePropPath = prop.split('\\.').toList()

      theProperty = project.findProperty(thePropPath.head())

      // aux. closure to travel "property path"
      def pp = {
        s,
        t - >
        if (s != null && s.hasProperty(t).is(true)) {
          return s.property(t)
        }
        return null
      }
      thePropPath.tail().each {
        item - >
          theProperty = pp(theProperty, item)
      }
    }
    println(theProperty ? : "") // or print "null" ...
  }
}

Upvotes: 2

forgo
forgo

Reputation: 952

For clarity, here is my Gradle wrapper version:

$ ./gradlew --version

------------------------------------------------------------
Gradle 5.4.1
------------------------------------------------------------

Build time:   2019-04-26 08:14:42 UTC
Revision:     261d171646b36a6a28d5a19a69676cd098a4c19d

Kotlin:       1.3.21
Groovy:       2.5.4
Ant:          Apache Ant(TM) version 1.9.13 compiled on July 10 2018
JVM:          11.0.2 (Oracle Corporation 11.0.2+9-LTS)
OS:           Mac OS X 10.14.4 x86_64

This is an existing task to give you an idea of the properties available:

$ ./gradlew properties


> Task :properties

------------------------------------------------------------
Root project
------------------------------------------------------------

allprojects: [root project 'myProject', project ':otherProject', ...]
...
rootDir: /path/to/rootDir
rootProject: root project 'myProject'
...
version: 2.3.0
...

Here is a custom task I've built to print out a project property

class ResolveProperties extends DefaultTask {

  @Input
  String prop

  ResolveProperties() {
    // if no --prop=<property> is provided, default to spitting out all properties
    prop = "properties"
  }

  @Option(option = 'prop', description = 'Set the property to be evaluated for the project.')
  void setProp(final String prop) {
    this.prop = prop
  }

  @TaskAction
  void resolveProp() {
    List<String> propPath = this.prop.tokenize('.')
    int n = propPath.size()
    def currentProp = project
    propPath.eachWithIndex { p, i ->
        if(currentProp.hasProperty(p)) {
          currentProp = currentProp.property(p)
        }
        else {
          throw new GradleException("failed to resolve property: ${this.prop}")
        }
    }
    println "${this.prop} -> ${currentProp}"
  }
}

task resolveProperties(type: ResolveProperties)

And this is how I use my custom task with a --prop parameter (indicated by @Option(option = 'prop'. I'm using the -q (quiet) Gradle option to suppress some of the extra output.

$ ./gradlew -q resolveProperties --prop=rootProject.name
rootProject.name -> onestop
resolveProperties took 0 seconds
$ ./gradlew -q resolveProperties --prop=rootProject.version
rootProject.version -> 2.3.0
resolveProperties took 0 seconds
$ ./gradlew -q resolveProperties --prop=rootProject.group
rootProject.group -> org.cedar.onestop
resolveProperties took 0 seconds

Because we are throwing a GradleException when we can't find the property, in Bash you can check the return code of the command to know when to parse out the value. The formatting of a successful output is up to you and you could make it easily parsed.

$ ./gradlew -q resolveProperties --prop=does.not.exist
resolveProperties took 0 seconds

FAILURE: Build failed with an exception.

* Where:
Build file '/Users/elliott/Documents/GitHub/onestop/build.gradle' line: 259

* What went wrong:
Execution failed for task ':resolveProperties'.
> failed to resolve property: does.not.exist

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 0s

In case of a failure like the one above, we get a non-zero return code in Bash, and we know we don't need to try and parse out the value:

$ echo $?
1

Unfortunately, I don't know a simple way in Gradle to only give the value you are concerned with to stdout (prevent some parsing), but this gets you most of the way there with some flexibility.

Upvotes: 3

Related Questions