我有一个kts gradle构建脚本,其中使用了这个plugin。
该插件将project.version
属性设置为字符串,并添加了一些其他属性:
虽然version属性是一个字符串,但它确实暴露了一些其他属性 属性。它们是
snapshot
,major
,minor
,patch
和preRelease
。
现在,如何从build.gradle.kts
访问这些属性?
由于Kotlin是静态键入的,因此尝试val major = project.version.major as Integer
之类的操作总是失败:
未解决的参考文献:专业
有什么方法可以访问这些属性,还是必须回到基于Groovy的gradle.build
构建脚本?
答案 0 :(得分:1)
有趣的问题。该插件正在使用Groovy元编程将这些属性(主要,次要,补丁...)添加到version属性中。
据我所知,Kotlin无法访问Groovy的MetaClass属性。
插件应该为version属性使用普通的类结构,或者(希望保留版本为String对象)向项目添加一个专用属性,该属性包含这些值作为新类的属性。但是当前的实现似乎与Gradle Kotlin DSL不兼容。
这是代码部分,他们在其中设置project.version
并将属性添加到其MetaClass(Source code):
project.version = semanticBuildVersion as String
// Attach snapshot boolean-property to version - says whether version is snapshot or not
project.version.metaClass.snapshot = semanticBuildVersion.snapshot
// Attach version components
def versionComponents = project.version.split(/[.-]/, 4)
project.version.metaClass.major = versionComponents[VersionComponent.MAJOR.index] as int
project.version.metaClass.minor = versionComponents[VersionComponent.MINOR.index] as int
project.version.metaClass.patch = versionComponents[VersionComponent.PATCH.index] as int
Groovy官方文档实际上记录了其他JVM语言不可见运行时元编程,而编译时元编程将可见(link):
Groovy中的编译时元编程允许在编译时生成代码。这些转换正在改变程序的抽象语法树(AST),这就是为什么在Groovy中我们将其称为AST转换。 AST转换使您可以进入编译过程,修改AST并继续编译过程以生成常规字节码。与运行时元编程相比,这具有使更改在类文件本身(即在字节码中)可见的优点。例如,如果您希望将转换作为类协定的一部分(实现接口,扩展抽象类等),或者需要从Java(或其他JVM语言)调用类,则使其在字节码中可见非常重要。 )。例如,AST转换可以将方法添加到类中。 如果使用运行时元编程进行此操作,则只能从Groovy中看到新方法。如果使用编译时元编程进行此操作,则该方法也将从Java中可见。最后但并非最不重要的一点是,编译时元编程的性能可能会更好(因为不需要初始化阶段)。