Groovy 如何在自定义Gradle插件中获取$project.version?

Groovy 如何在自定义Gradle插件中获取$project.version?,groovy,gradle,Groovy,Gradle,在自定义gradle插件中,项目.版本似乎总是未指定。为什么以及如何在自定义插件(类)中检索项目.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 pro

在自定义gradle插件中,
项目.版本
似乎总是
未指定
。为什么以及如何在自定义插件(类)中检索
项目.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"
    }
  }
}

除了我真的想知道为什么之外?

在调用
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"
      }
    }
  }
}
apply插件:“java”
应用插件:MyPlugin
version=“1.0.0”
println“内置文件:$project.version”
类MyPlugin实现插件{
公开作废申请(项目){
project.task('myTask'){
project.gradle.projectsevaluate{
插件中的println:$project.version
}
}
}
}

在编写插件时,将
$project.version
的评估推迟到构建评估完成之前

处理评估顺序是一项挑战,需要掌握一些知识和专业技能

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

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

并提供有关这些主题的更多信息。

检查我的答案

可以将此块放置在projectEvaluated闭包或PostTask闭包之后。我还没有测试过纯单机版,但它可能会工作

AppExtension android = (AppExtension) project.extensions.findByName("android")
String versionName = android.defaultConfig.versionName
String versionCode = android.defaultConfig.versionCode

谢谢作品完全有道理。@jonbros Peter Niederwieser必须重新排序您的构建脚本。编辑我的答案以显示其示例。最好立即添加任务(否则生成脚本将无法访问它),并且只延迟需要访问
project.version
的部分配置
println
是一个不幸的例子,因为它通常在任务操作(
doLast{…}
)中完成,该操作只在执行时进行评估,因此不会遇到配置顺序问题。谢谢Peter,这确实是一个更好的解决方案,您认为它具有挑战性是正确的
project.version
应该是插件中引入的扩展的合理默认值。但是我找到了usefor
projectsEvaluated
方法,并注意不要用默认值覆盖设置,检查它是否等于
unspecified
AppExtension android = (AppExtension) project.extensions.findByName("android")
String versionName = android.defaultConfig.versionName
String versionCode = android.defaultConfig.versionCode