【问题标题】:Avoid duplication between similar Gradle tasks?避免类似 Gradle 任务之间的重复?
【发布时间】:2012-10-25 15:29:35
【问题描述】:

有什么办法可以避免相同类型的两个相似任务之间的配置重复?

例如,我想创建一个debugSomething 任务,其配置与下面的runSomething 相同,但在jvmArgs 中添加了一个远程调试器参数:

task runSomething(dependsOn: jar, type: JavaExec, group: "Run") {
    jvmArgs "-Xmx1024m", "-XX:MaxPermSize=128m"
    main = "com.some.Main"
    classpath = sourceSets.main.runtimeClasspath
}

【问题讨论】:

  • 我知道我可以提取变量中的配置,但由于我要设置几个环境和命令行参数,这对我来说似乎并不理想。

标签: gradle


【解决方案1】:

这可以使用普通的 Groovy 解决:

task runSomething(dependsOn: jar, type: JavaExec, group: "Run") {
}

task debugSomething(dependsOn: jar, type: JavaExec, group: "Run") {
    jvmArgs "-agentlib:jdwp=transport=dt_socket,server=y,address=8000,suspend=y"
}

[runSomething, debugSomething].each { task ->
    task.main = "com.some.Main"
    task.classpath = sourceSets.main.runtimeClasspath
    task.jvmArgs "-Xmx1024m", "-XX:MaxPermSize=128m"
}

即使debugSomething.jvmArgs 被调用了两次,所有三个参数都提供给 JVM。

可以使用 Groovy 的 Spread operator 设置单个参数:

[runSomething, debugSomething]*.main = "com.some.Main"

【讨论】:

  • 我发现,在 each 闭包中,您还可以说 task.with { ... } 来“切换上下文”到 task ——您不再需要在每个闭包中重复 task.那么行。
【解决方案2】:

我一直在寻找类似的东西,不同之处在于我不想所有相同类型的任务之间共享配置,但仅用于其中一些。

我已经尝试过类似接受的答案中所述的方法,但效果不佳。那我再试一次。

既然我已经到了这里,我不介意分享,(至少现在)有一种更好的 Gradle 内置方式来实现这里所要求的事情。它是这样的:

tasks.withType(JavaExec) {
    jvmArgs "-Xmx1024m", "-XX:MaxPermSize=128m"
    main = "com.some.Main"
    classpath = sourceSets.main.runtimeClasspath
}

这样JavaExec 类型的所有任务都将接收默认配置,该默认配置显然可以被任何相同类型的特定任务更改。

【讨论】:

    【解决方案3】:

    我发现使用Task.configure 方法对于集中这样的逻辑非常有帮助。

    我还没有测试过,但在你的情况下,这可能看起来像这样:

    def commonSomething = {
        main = "com.some.Main"
        classpath = sourceSets.main.runtimeClasspath
        jvmArgs "-Xmx1024m", "-XX:MaxPermSize=128m"
    }
    
    task runSomething(dependsOn: jar, type: JavaExec, group: "Run") {
        configure commonSomething
    }
    
    task debugSomething(dependsOn: jar, type: JavaExec, group: "Run") {
        configure commonSomething
        jvmArgs ...add debug arguments...
    }
    

    【讨论】:

    • 它工作正常,但是当将 dependsOn 添加到 commonSomething 闭包时,Eclipse 说它已被弃用。是 Eclipse 错误地将其评估为 Project.dependsOn 而不是 Task.dependsOn
    • commonSomething 只是传递给配置的闭包,而不是任务定义。我相信当您在那里调用dependsOn 时,您调用的是Project.dependsOn 方法,该方法确实已被弃用。 gradle.org/docs/current/javadoc/org/gradle/api/…
    • 好的,所以澄清一下:在定义多个公共依赖项时,最好使用[tasks].each 方法。对吗?
    • 如果它们都有效,那么您选择哪一个可能归结为口味。我 [也许很明显] 更喜欢我发布的常用闭包方法。
    【解决方案4】:

    请参阅section 51.2 of the manual。 AFAICT,它准确地显示了您想要的内容。

    【讨论】:

    • 我希望有一种方法可以重用(现有任务类型的)现有任务定义,而不是创建一个全新的任务类型,但这确实可以减少一些重复。我创建了一个新的任务类型,在构造函数中设置属性。然而,此时无法获取 sourceSets,因此仍会留下一些重复。
    • @DavidPärsson - 我是新手......但是如果你扩展了你想要模拟的现有类型 (JavaExec) 而不是 DefaultTask,那会满足你的需要吗?
    • 对不起,如果我不清楚,这正是我尝试过的。它适用于配置的静态部分,至少更好。如果没有更好的解决方案,我会接受你的。
    • 我试图做这样的事情,但遇到项目额外属性不可见。似乎与上述问题不同,我创建了一个新问题:stackoverflow.com/questions/14530901/…
    猜你喜欢
    • 1970-01-01
    • 2016-01-20
    • 2021-07-08
    • 1970-01-01
    • 1970-01-01
    • 2015-01-11
    • 2011-12-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多