Как интерпретировать Gradle DSL

Я пытаюсь изучить Gradle. Я предпочитаю стиль обучения, чтобы понять на низком уровне, что происходит. С этой целью я пытаюсь интерпретировать то, что происходит в примере 6.1 документации относительно справки по DSL:

task hello {
    doLast {
        println 'Hello world!'
    }
}

Я понимаю, что этот скрипт выполняется в контексте файла Project. Итак, из Project документации я вижу, что существует ряд перегруженных task(...) методов. Глядя на подписи, мне нужно выбрать ту, у которой есть замыкание в качестве последнего аргумента. И поскольку мы не передаем здесь Map, я предполагаю, что вызывается метод task(String name, Closure closure).

Однако часть, с которой я борюсь, заключается в том, как в этом скрипте литеральная строка hello сопоставляется с String.

Другой пример — пример 6.7:

task taskX(dependsOn: 'taskY') << {
    println 'taskX'
}

task taskY << {
    println 'taskY'
}

Здесь я предполагаю, что мы вызываем task(Map<String, ?> args, String name) форму метода. Но,

  1. Опять же, как литеральная строка taskX заканчивается как String?
  2. Учитывая, что круглые скобки не используются для построения литерала Map, как часть в круглых скобках оказывается Map?
  3. Если я правильно понял, какой метод вызывается, не являются ли аргументы приведенными в сценарии в неправильном порядке по сравнению с документацией по DSL?
  4. Синтаксис с использованием круглых скобок во всем мире выглядит как вызов метода. Что может указывать на делегирование объекту Project разрешения taskX как неизвестного метода. Но, насколько мне известно, вызов метода не будет синтаксически допустимым в этот момент, учитывая вызов метода task, непосредственно предшествующий ему.

Как видите, я немного запутался в том, как синтаксис примера соотносится со справочным руководством по DSL, из-за чего мне немного сложно понять, что происходит на низовом уровне.

Спасибо!


person dty    schedule 07.09.2012    source источник
comment
У меня такое же замешательство, как и у вас. И я очень надеюсь, что gradleware может дать какое-то объяснение.   -  person peacepassion    schedule 25.09.2014
comment
Этот запрос может быть более подробным. синтаксис Groovy в определении задачи gradle   -  person user3875388    schedule 24.11.2016


Ответы (2)


Вариант task foo синтаксиса объявления задачи отличается тем, что он реализован с помощью подключаемого модуля компилятора Groovy. Насколько мне известно, это единственный случай, когда плагин компилятора используется для поддержки специального синтаксиса.

person Peter Niederwieser    schedule 07.09.2012
comment
Интересно. Я относительно новичок в Groovy, и одна из вещей, которые мне не нравятся, это то, как сложно понять, что происходит, когда люди делают такие умные вещи - обычно для того, чтобы сделать свои DSL простыми в использовании/написании. Есть ли у вас какой-либо конкретный совет о том, как я могу переводить (в уме) между сценарием и справочным руководством по DSL? - person dty; 08.09.2012
comment
Синтаксис задокументирован как в руководстве пользователя, так и в справочнике по DSL; обратите внимание, как они говорят о задаче ключевое слово. Оглядываясь назад, это может быть немного чрезмерным, хотя читается лучше, чем немагические альтернативы. Как я уже сказал, это редкое исключение. Учитывая, как вы проанализировали, что здесь должно быть что-то не так, вы уже на пути к пониманию всего остального, что происходит под прикрытием Gradle DSL. - person Peter Niederwieser; 08.09.2012
comment
Спасибо, Питер. Последний вопрос, если позволите. Не могли бы вы указать мне правильное место в исходном коде Gradle, чтобы увидеть этот плагин компилятора в действии, пожалуйста? - person dty; 08.09.2012

Это хороший документ: https://ouyi.github.io/post/2017/12/09/groovy-gradle.html

А вот в конце написано:

Синтаксис пользовательской задачи сложен. Например:

task myTask(type:Tar, dependsOn anotherTask) {
    // clousre
}

Я мог предположить, что это, вероятно, вызов метода Task task(Map<String,?> args, String name, Closure configureClosure), определенного для объекта проекта, но я понятия не имел, как сопоставить конструкцию myTask() с параметром имени. И я не одинок, подобные обсуждения есть здесь и здесь.

Оказывается, Gradle использует некоторые расширенные функции метапрограммирования Groovy (метапрограммирование времени компиляции) для преобразования конструкции myTask() в параметр имени. Честно говоря, это та часть Gradle, которая мне не нравится, потому что она кажется слишком сложной для реализации этих синтаксических сахаров (и слишком много сахара может быть вредным). В конце концов, Gradle — это просто инструмент сборки, который должен быть простым для понимания, использования и расширения.

person Dacian    schedule 24.06.2021