【问题标题】:Extract common methods from Gradle build script从 Gradle 构建脚本中提取常用方法
【发布时间】:2013-09-13 22:33:27
【问题描述】:

我有一个 Gradle 构建脚本 (build.gradle),我在其中创建了一些任务。这些任务主要由方法调用组成。调用的方法也在构建脚本中。

现在,情况如下:

我正在创建大量构建脚本,其中包含不同的任务,但使用原始脚本中的相同方法。因此,我想以某种方式提取这些“常用方法”,这样我就可以轻松地重复使用它们,而不是为我创建的每个新脚本复制它们。

如果 Gradle 是 PHP,那么以下内容将是理想的:

//script content
...
require("common-methods.gradle");
...
//more script content

当然,这是不可能的。还是这样?

无论如何,我怎样才能达到这个结果?最好的方法是什么?我已经阅读了 Gradle 文档,但我似乎无法确定哪种方法最简单且最适合。

提前致谢!


更新:

我已经设法将方法提取到另一个文件中

(使用apply from: 'common-methods.gradle'),

所以结构如下:

parent/
      /build.gradle              // The original build script
      /common-methods.gradle     // The extracted methods
      /gradle.properties         // Properties used by the build script

build.gradle 执行任务后,我遇到了一个新问题:显然,方法在common-methods.gradle 中时无法被识别。

关于如何解决这个问题的任何想法?

【问题讨论】:

  • 你确定你需要编写方法吗?如果您根据方法编写构建脚本,您将错过一些 Gradle 好东西,最重要的是,要使增量构建正常工作需要额外的工作。预期的抽象是使用和重用Tasks。您也可以创建custom tasks。也许您应该考虑将您现在在方法中的实现放入任务中。
  • @Alpar 和 其他人;将timestamp()currentWorkingDirectory() 方法设置为task-s(例如)的目的是什么。实用函数和类似的东西名义上是标量的——它们不会是任务,除非 Gradle 和大多数构建系统内置的代码重用存在限制。我喜欢 DRY 的世界,我可以一次制作一件东西并重复使用它。事实上,扩展@Pieter VDE 的示例我还为我的父项目使用了“root.gradle”模式——build.gradle 文件通常定义了一些项目细节,然后只是apply ${ROOT} ...
  • 如果您需要一种集中的方式来处理属性,也许这个问题可以帮助您:stackoverflow.com/questions/60251228/…

标签: gradle build.gradle


【解决方案1】:

我建议对Matthias Braun's answer 稍作调整, 在那个而不是两次编写相同的方法名称并且仍然拥有它 清晰简洁,为什么不简单地执行以下操作:

ext.commonMethod1 = (param) -> {
    return true
} as Closure<boolean>

as-operator 的用法只是明确地告诉一个人, 这个函数将返回一个值boolean-type。

因为毕竟这仍然是 Groovy 的优点。整齐吧?

【讨论】:

    【解决方案2】:

    Peter's answer 为基础,这是我导出方法的方式:

    helpers/common-methods.gradle的内容:

    // Define methods as usual
    def commonMethod1(param) {
        return true
    }
    def commonMethod2(param) {
        return true
    }
    
    // Export methods by turning them into closures
    ext {
        commonMethod1 = this.&commonMethod1
        otherNameForMethod2 = this.&commonMethod2
    }
    

    这就是我在另一个脚本中使用这些方法的方式:

    // Use double-quotes, otherwise $ won't work
    apply from: "$rootDir/helpers/common-methods.gradle"
    
    // You can also use URLs
    //apply from: "https://bitbucket.org/mb/build_scripts/raw/master/common-methods.gradle"
    
    task myBuildTask {
        def myVar = commonMethod1("parameter1")
        otherNameForMethod2(myVar)
    }
    

    Here's more 在 Groovy 中将方法转换为闭包。

    【讨论】:

    • 使用闭包名称作为分机有什么具体原因吗?
    • @AnoopSS 我们将两个闭包添加到Gradle's extra properties。这些额外的属性捆绑在一个名为 ext 的对象中。
    • 我们能否以某种方式将值转换为包含文件中定义的我们的类?
    • 用示例代码发布一个单独的问题可能是个好主意,@GarouDan。
    【解决方案3】:

    Kotlin DSL 的另一种方法可能是:

    my-plugin.gradle.kts

    extra["sum"] = { x: Int, y: Int -> x + y }
    

    settings.gradle.kts

    @Suppress("unchecked_cast", "nothing_to_inline")
    inline fun <T> uncheckedCast(target: Any?): T = target as T
    
    apply("my-plugin.gradle.kts")
    
    val sum = uncheckedCast<(Int, Int) -> Int>(extra["sum"])
    
    println(sum(1, 2))
    

    【讨论】:

      【解决方案4】:

      使用 Kotlin dsl 它的工作原理如下:

      build.gradle.kts

      apply {
        from("external.gradle.kts")
      }
      
      val foo = extra["foo"] as () -> Unit
      foo()
      

      external.gradle.kts

      extra["foo"] = fun() {
        println("Hello world!")
      }
      

      【讨论】:

      • 有没有办法分享实际类型?你基本上失去了类型安全和编译器的帮助......如果你可以共享包含你的方法的类,那么你可以使用编译器。
      【解决方案5】:

      无法共享方法,但您可以共享包含闭包的额外属性,归结为同一件事。比如在common-methods.gradle中声明ext.foo = { ... },使用apply from:应用脚本,然后用foo()调用闭包。

      【讨论】:

      • 它确实成功了!但我确实有一个问题:方法返回一些东西怎么样? F.e. File foo(String f) 将变为 ext.foo = { f -&gt; ... },然后我可以这样做:File f = foo(...)
      • 显然,我之前评论中的问题是可能的。所以感谢彼得回答这个问题!
      • @PeterNiederwieser 为什么不可能? Gradle.org 不这么认为:docs.gradle.org/current/userguide/…
      • @IgorGanapolsky 感谢您的链接。我想知道如何在 gradle.build 的单独构建文件中使用生成的值 - 这样它会非常有用:)
      • @IgorGanapolsky 您分享的链接应该如何帮助解决 Peter VDE 的问题?
      猜你喜欢
      • 1970-01-01
      • 2014-07-31
      • 2016-12-23
      • 1970-01-01
      • 2014-11-11
      • 1970-01-01
      • 1970-01-01
      • 2014-12-06
      • 2016-04-13
      相关资源
      最近更新 更多