首页 文章

将Groovy gradle迁移到Kotlin gradle(ext缺失或闭包转换,不确定)

提问于
浏览
1

我有一些用groovy编写的Git助手:

git.gradle:

def gitHash() {
    def res = 'git rev-parse --short HEAD'.execute([], project.rootDir).text.trim()

    def diff = 'git diff'.execute([], project.rootDir).text.trim()
    if (diff != null && diff.length() > 0) {
        res += "-dirty"
    }

    return res
}

// method needs to be converted to closure, in order to be visible outside of script
ext.gitHash =  { return gitHash();}

现在我将整个东西转换成Kotlin,现在看起来像这样:

git.gradle.kts:

import java.io.IOException
import java.util.concurrent.TimeUnit

fun gitHash() : String {
    var res = "git rev-parse --short HEAD".runCommand(project.rootDir)?.trim()

    val diff = "git diff".runCommand(project.rootDir)?.trim()
    if (diff != null && diff.isNotEmpty()) {
        res += "-dirty"
    }
    return res!!
}

fun String.runCommand(workingDir: File): String? {
    ...
}

// method needs to be converted to closure, in order to be visible outside of script
//ext.gitHash =  { return gitHash();} // <-- HERE'S THE PROBLEM

task("gitTask") { // <-- calling ./gradlew gitTask works
    println(gitHash())
}

主脚本包括以下内容:

//apply from: 'git.gradle'
apply from: 'git.gradle.kts'

println gitHash() // works with Groovy, doesn't with Kotlin

现在,问题是,主脚本无法识别gitHash()方法,很可能是因为我无法通过ext闭包暴露它 . 与Groovy脚本相同,此方法似乎是该文件中的私有(或本地) .

据我所知,ext closure是我试图整合的'project.extra'的简写 . 而且,似乎典型的Groovy闭包在Kotlin中没有等价物 . 我卡在这里,不知道我还能尝试什么 . 任何想法欢迎 .

UPDATE

附:

var gitHash: Closure<Any?> by extra
gitHash = closureOf<String> { }
gitHash.delegate = { gitHash() }

我可以在Groovy中使用它,如:

println gitHash.invoke()

但它不适用于Kotlin脚本...因为invoke()指向call()(此处为https://github.com/gradle/gradle-script-kotlin/blob/master/src/main/kotlin/org/gradle/script/lang/kotlin/GroovyInteroperability.kt扩展方法) . 虽然我试图将它用作闭包 gitHash() 但它会导致这样的错误:

Parameter specified as non-null is null: method org.gradle.script.lang.kotlin.KotlinClosure.doCall, parameter it

看起来我错过了一些东西......

1 回答

  • 0

    如果你还在寻找解决方案,我建议这就是:

    import java.io.ByteArrayOutputStream
    
    inline
    fun String.runCommand(workingDir: File): String {
        val command = this
        val stdout = ByteArrayOutputStream()
        project.exec {
            this.workingDir = workingDir
            this.commandLine = command.split(" ")
            this.standardOutput = stdout
        }
        return String(stdout.toByteArray()).trim()
    }
    
    task("gitHash") {
        var res = "git rev-parse --short HEAD".runCommand(project.rootDir)
        val diff = "git diff".runCommand(project.rootDir)
        if (!diff.isNullOrBlank()) { res += "-dirty" }
        println(res)
    }
    

    我用Gradle 4.6+测试了它

    ..或者更可能是惯用语:

    inline
    fun String.runCommand(workingDir: File): String {
        val stdout = ByteArrayOutputStream()
        project.exec {
            this.workingDir = workingDir
            this.commandLine = this@runCommand.split(" ")
            this.standardOutput = stdout
        }
        return String(stdout.toByteArray()).trim()
    }
    
    val commitHash by lazy { "git rev-parse --short HEAD".runCommand(project.rootDir) }
    val workingCopyDiff by lazy { "git diff".runCommand(project.rootDir) }
    
    val gitHash by tasks.creating {
        println(commitHash + if (workingCopyDiff.isBlank()) "" else "-dirty")
    }
    

相关问题