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

故事扮演 提交于 2021-01-28 07:24:07

问题


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.


回答1:


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.




回答2:


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" ...
  }
}


来源:https://stackoverflow.com/questions/57210735/how-can-i-ask-gradle-for-the-value-of-a-property-from-the-command-line

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!