如何从命令行向gradle询问属性的值?

时间:2019-07-25 22:10:18

标签: gradle

例如,如果我希望shell脚本能够获得rootProject.name的值,我该怎么做?理想情况下,我想使用一组参数调用./gradlew并让其将属性值(以及其他所有内容)打印到stdout。

2 个答案:

答案 0 :(得分:2)

为清楚起见,这是我的Gradle包装器版本:

$ ./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

这是一项现有任务,可让您了解可用的属性:

$ ./gradlew properties


> Task :properties

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

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

这是我用来打印项目属性的自定义任务

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)

这就是我如何通过--prop参数(由@Option(option = 'prop'来使用自定义任务。我正在使用-q(安静)Gradle选项来抑制一些额外的操作输出。

$ ./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

由于找不到属性时会抛出GradleException,因此在Bash中,您可以检查命令的返回码以了解何时解析该值。成功输出的格式由您决定,您可以轻松对其进行解析。

$ ./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

如果发生类似上面的失败,我们将在Bash中得到一个非零的返回码,并且我们知道我们不需要尝试解析出该值:

$ echo $?
1

不幸的是,我不知道Gradle中仅提供 的简单方法来将您关注的值提供给stdout(防止进行某些解析),但这可以使您获得大部分一种灵活的方式。

答案 1 :(得分:0)

如果仍然有用...

可能的解决方法A:在cmd行上打印“ rootProject.name ”的值

在build.gradle中添加任务

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

可能的解决方案B:打印cmd行中提供的属性值

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