95

我有一个 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.

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

4

5 回答 5

177

基于彼得的回答,这就是我导出方法的方式:

内容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)
}

这里有更多关于在 Groovy 中将方法转换为闭包的内容。

于 2014-04-25T10:43:16.693 回答
79

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

于 2013-09-10T12:19:16.320 回答
8

使用Kotlin DSL,它的工作方式如下:

build.gradle.kts

apply {
  from("external.gradle.kts")
}

val foo = extra["foo"] as () -> Unit
foo()

外部.gradle.kts

extra["foo"] = fun() {
  println("Hello world!")
}
于 2018-09-02T17:47:16.650 回答
1

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

我的插件.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))
于 2020-02-16T20:06:25.683 回答
1

我建议对Matthias Braun 的回答稍作调整,而不是两次编写相同的方法名称并且仍然保持清晰和简洁,为什么不简单地执行以下操作:

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

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

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

于 2022-01-04T17:28:28.447 回答