如何在Kotlin DSL Gradle脚本中的插件中访问属性?

4

我有一个kts gradle buildscript,其中使用了plugin

该插件将project.version属性设置为字符串并添加了一些其他属性:

尽管版本属性是一个字符串,但它确实公开了一些其他属性。这些属性包括snapshotmajorminorpatchpreRelease

现在,我如何从build.gradle.kts中访问这些属性?

尝试像val major = project.version.major as Integer这样的操作总是失败,因为Kotlin是静态类型的:

未解决的引用:major

是否有任何方法可以访问这些属性,或者我必须回到基于groovy的gradle.build buildscript?

1个回答

1
有趣的问题。该插件使用Groovy元编程将这些属性(major,minor,patch等)添加到version属性中。
据我所知,Kotlin无法访问Groovy的MetaClass属性。
该插件应该使用普通的类结构来处理version属性,或者(希望保持version为String对象)向项目添加一个专用属性,该属性包含这些值作为新类的属性。但是目前的实现似乎与Gradle Kotlin DSL不兼容。

以下是设置project.version并向其MetaClass添加属性的代码部分(源代码):

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中看到。最后但并非最不重要的是,编译时元编程的性能可能会更好(因为不需要初始化阶段)。

虽然保留插件代码行的具体参考是很好的,但最好也将相关代码部分添加到您在此处的答案中。外部资源的链接可能会随着时间的推移而不可用。请确保您的答案本身是完整的。 - Ivo Mori

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接