11

在自定义 gradle 插件中,project.version似乎总是unspecified. 为什么以及如何project.version在自定义插件(类)中检索?

例如:

apply plugin: 'java'
apply plugin: MyPlugin

version = "1.0.0"

println "In build file: $project.version" 

class MyPlugin implements Plugin<Project> {
  public void apply(Project project) {
    project.task('myTask') {
      println "In plugin: $project.version"
    }
  }
}

打印出来:

%> gradle -q myTask
  In plugin: unspecified
  In build file: 1.0.0

除了我真的很想知道为什么吗?

4

3 回答 3

11

调用后设置属性apply

如果你搬家

version = "1.0.0"

到前线

apply plugin: MyPlugin

它应该工作

编辑

按照彼得的回答,您可以看到这也有效:

apply plugin: 'java'
apply plugin: MyPlugin

version = "1.0.0"

println "In build file: $project.version" 

class MyPlugin implements Plugin<Project> {
  public void apply(Project project) {
    project.task('myTask') {
      project.gradle.projectsEvaluated { 
        println "In plugin: $project.version"
      }
    }
  }
}

延迟评估$project.version直到构建评估完成

于 2012-11-02T15:38:30.887 回答
6

处理评估顺序是编写插件时挑战,需要一些知识和专业知识才能掌握。

请注意,在构建脚本中,插件在设置版本之前被应用(并因此被执行!)。这是常态,插件必须处理它。粗略地说,每当插件访问 Gradle 对象模型的可变属性时,它必须将该访问推迟到配置阶段结束。(在此之前,该属性的值仍然可以更改。)

Gradle 的一些 API(惰性集合、接受回调的方法等)为处理这个问题提供了特殊的支持。除此之外,您可以将受影响的代码包装在 中project.gradle.projectsEvaluated { ... },或者使用更复杂的“约定映射”技术。

Gradle 用户指南http://forums.gradle.org提供了有关这些主题的更多信息。

于 2012-11-02T15:53:52.700 回答
1

在这里查看我的答案

您可以将此块放置在 projectEvaluated 闭包或 afterTask 闭包之后。我还没有测试过纯独立的,但它可能会起作用。

AppExtension android = (AppExtension) project.extensions.findByName("android")
String versionName = android.defaultConfig.versionName
String versionCode = android.defaultConfig.versionCode
于 2015-03-30T20:15:43.337 回答