谁能解释groovy封闭的魔力/詹金斯

时间:2019-05-21 08:40:43

标签: jenkins groovy

我想了解基于groovy DSL和闭包的Jenkins管道的一部分代码。

我有一个Jenkins文件,如下所示:

foo {
  var1 = "foo value 1"
  var2 = "foo value 2"
}

我的Jenkins共享库中有一个Groovy脚本(在vars目录中为foo.groovy):

def call(body) {
   def config = [:]
   body.resolveStrategy = Closure.DELEGATE_FIRST
   body.delegate = config
   body()

   println config.var1 // display foo value 1 : for me the magic is here !!
}

我想了解groovy / jenkins机制,即在调用闭包时,使用变量var1和var2设置了地图配置。

我(几乎)理解了闭包机制和委托方法,但是我们如何知道配置映射对闭包的委托字段的影响允许使用在我的Jenkinsfile中声明的变量构造映射? / p>

我希望我的问题很清楚! :)

此致

Stef

1 个答案:

答案 0 :(得分:2)

当一个属性在闭包内被引用,而该引用无法在闭包内解析时,将尝试在各个“位置”解析该属性。

  1. this
  2. 闭包的delegate属性,可以重新分配
  3. 闭包的owner

在您的示例中,var1var2是在闭包内无法解析的引用示例。

以下内容将闭包的委托分配给config,并确保这是将用于解析未解析引用的第一个“位置”

def config = [:]
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = config

因此,当我们在闭包内设置属性var1var2时,它们将针对config进行解析,即设置为该Map的键值对。

如果您的示例更改为:

foo {
   def var3 = "some value"

   var1 = "foo value 1"
   var2 = "foo value 2"
   var3 = "some value"
}

var3 不会config解析,因为它可以在闭包中解析。

更新

(我想)回应您的评论(我想):为什么将闭包的委托设置为映射会导致将键值对添加到该映射?

var1 = "foo value 1"在闭包内无法解析时,因此会针对地图进行解析

def config = [:]
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = config

这实际上意味着我们在打电话

config.var1 = "foo value 1"

是Groovy的简写

config.put("var1", "foo value 1")

例如,如果您更改代码以直接调用put方法,例如,可能会更容易理解

def foo = {
  put('var1', "foo value 1")
}

def call(body) {
   def config = [:]
   body.resolveStrategy = Closure.DELEGATE_FIRST
   body.delegate = config
   body()

   println config.var1 // display foo value 1 : for me the magic is here !!
}

call(foo)

如果在Groovy控制台中运行此代码,您将看到它还会显示“ foo value 1”。

如果您仍在挣扎中,也许this question会有所帮助。