Кто-нибудь, чтобы объяснить магию заводной закрытия / Дженкинс - PullRequest
1 голос
/ 21 мая 2019

Я хочу понять часть кода моего конвейера Jenkins, основанного на Groovy DSL и замыкании.

У меня есть файл Jenkins следующим образом:

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

У меня есть скрипт groovy(foo.groovy в каталоге vars) в общей библиотеке моей Jenkins:

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.

Я понимаю (почти) механизм закрытия и метод делегата, но как мы можем знать, что влияние карты конфигурации на поле делегата замыкания позволяет построить карту с переменными, объявленными в моемДженкинсфайл?

Надеюсь, у меня все ясно в вопросе!:)

С уважением,

Stef

1 Ответ

2 голосов
/ 21 мая 2019

Когда на свойство ссылаются в замыкании, и эта ссылка не может быть разрешена в замыкании, предпринимаются попытки разрешить его в различных «местах»

  1. this
  2. Свойство замыкания delegate, которое можно переназначить
  3. Закрытие owner

В вашем примере var1 и var2 являются примерами ссылок, которые не могут быть разрешены в закрытии.

Следующее присваивает делегату замыкания config и гарантирует, что это первое «место», которое будет использоваться для разрешения неразрешенных ссылок

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

Поэтому, когда мы устанавливаем свойства var1 и var2 в замыкании, они разрешаются в 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"

, что является сокращенным сокращением для

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 Console, вы увидите, что он также печатает «foo value 1».

Если вы все еще боретесь, возможно, этот вопрос поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...