我正在尝试在gradle
中实现支持此类结构的kotlin
插件
env {
app ("ghc-haskell") {
srcLink { "http://downloads.haskell.org/~ghc/8.0.1/ghc-8.0.1-x86_64-unknown-mingw32.tar.xz" }
downloadPath { project(':').projectDir.absolutePath + "\\applications\\plugin" }
installPath { project(':').projectDir.absolutePath + "\\applications\\plugin" }
}
}
但我对内部闭包有问题,例如srcLink
,downloadPath
,installPath
。如何将其invokation委托给相应的kotlin
类?
我的扩展程序如下所示
/**
* Keeps all environments.
*/
open class ApplicationEnvironmentContainerExtension {
val environs = mutableMapOf<String, ApplicationEnvironmentExtension>()
fun app(id: String, closure : ApplicationEnvironmentContainerExtension.() -> String) : ApplicationEnvironmentExtension {
val extension = ApplicationEnvironmentExtension()
extension.installationId = id
environs.put(id, extension)
return extension
}
/**
* Sub extension.
*/
open class ApplicationEnvironmentExtension {
var installationId = ""
var srcLink = ""
var downloadPath = ""
var installPath = ""
fun srcLink(closure: ApplicationEnvironmentExtension.() -> String) {
srcLink = closure()
}
fun downloadPath(closure: ApplicationEnvironmentExtension.() -> String) {
downloadPath = closure()
}
fun installPath(closure: ApplicationEnvironmentExtension.() -> String) {
installPath = closure()
}
override fun toString(): String {
return "ApplicationEnvironmentExtension(" +
"installationId='$installationId', " +
"srcLink='$srcLink', " +
"downloadPath='$downloadPath', " +
"installPath='$installPath')"
}
}
}
当我调用我的print
任务显示环境列表时,它显示只设置installationId
- 其他字段为空
open class PrintingTask : DefaultTask() {
@TaskAction
fun print() {
val extension = this.project.extensions.getByName("env") as ApplicationEnvironmentContainerExtension
extension.environs.forEach {
println(it.value)
}
}
}
如何将closure
委托给ApplicationEnvironmentExtension
?
答案 0 :(得分:0)
您永远不会在closure
函数中调用app
参数。我认为app
函数的签名是错误的。它应该是这样的:
fun app(id: String, closure: ApplicationEnvironmentExtension.() -> Unit)
这使得闭包中的this
引用ApplicationEnvironmentExtension
。这使得对srcLink
,downloadPath
和installPath
的调用击中了正确的对象。
然后通过这样做来调用闭包:
val extension = ApplicationEnvironmentExtension()
extension.closure()
这将填充ApplicationEnvironmentExtension
。
我还认为srcLink
,downloadPath
和installPath
函数的签名是错误的。它们应该像这样定义:
fun srcLink(closure: () -> String)
fun downloadPath(closure: () -> String)
fun installPath(closure: () -> String)
答案 1 :(得分:0)
你甚至需要这些功能吗?您是否可以将scrLink
,downloadPath
和installPath
设置为属性?即
env {
app ("ghc-haskell") {
srcLink = "http://downloads.haskell.org/~ghc/8.0.1/ghc-8.0.1-x86_64-unknown-mingw32.tar.xz"
downloadPath = project(':').projectDir.absolutePath + "\\applications\\plugin"
installPath = project(':').projectDir.absolutePath + "\\applications\\plugin"
}
}
答案 2 :(得分:0)
我使用该解决方法解决了这个问题。
出于一些奇怪的原因,我传递给closure
方法的参数app
总是想要解决ApplicationEnvironmentContainerExtension
,尽管设置是ApplicationEnvironmentExtension
的关闭甚至调用它。
所以我决定使用蛮力并创建字段 - 应该填充在ApplicationEnvironmentExtension
- ApplicationEnvironmentContainerExtension
中,填写它们并在必要的类中手动设置。
open class ApplicationEnvironmentContainerExtension {
val environs = mutableMapOf<String, ApplicationEnvironmentExtension>()
var installationId = ""
var srcLink = ""
var installPath = ""
var downloadPath = ""
fun app(id: String, closure : ApplicationEnvironmentExtension.() -> Unit) {
val extension = ApplicationEnvironmentExtension()
extension.installationId = id
environs.put(id, extension)
extension.process(closure)
extension.setEverything(installationId, srcLink, downloadPath, installPath)
}
}
关于关闭,我决定像James Bassett建议的那样设置它们
env {
app ("ghc-haskell") {
srcLink = "http://downloads.haskell.org/~ghc/8.0.1/ghc-8.0.1-x86_64-unknown-mingw32.tar.xz"
downloadPath = "$path\\applications\\plugin"
installPath = "$path\\applications\\plugin"
}
app ("mongo-db") {
srcLink = "https://fastdl.mongodb.org/win32/mongodb-win32-x86_64-2008plus-ssl-3.4.1-signed.msi"
downloadPath = "$path\\applications\\plugin"
installPath = "$path\\applications\\plugin"
}
}