我有一些用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 39的缩写.extra&#39;我试图整合。而且,似乎典型的Groovy闭包在Kotlin中没有等效物。我卡在这里,不知道我还能尝试什么。欢迎任何想法。
更新
使用:
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
看起来我错过了什么......
答案 0 :(得分: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)
}
对其进行了测试
..或者也许是更惯用的:
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")
}