Пользовательская условная конфигурация для проекта Gradle

Наличие выдержки из https://github.com/gradle/gradle/blob/master/build.gradle:

ext {
  isDevBuild = {
    gradle.taskGraph.hasTask(developerBuild)
  }
}

task developerBuild {
  description = 'Builds distributions and runs pre-checkin checks'
  group = 'build'
  dependsOn testedDists
}

Когда я использовал этот подход для создания пользовательской конфигурации в своем проекте, я обнаружил, что:

isDevBuild === true

то есть это всегда верно, потому что задача «developerBuild» находится внутри моего проекта build.gradle и, следовательно, в графике. У них есть пара «разных» конфигураций (isCIBuild, isCommitBuild, isFinalReleaseBuild, ...), так что я полагаю, что здесь что-то не так.

Может кто-нибудь объяснить, как сделать эти конфиги условными на основе какого-то внешнего параметра?


person Artem Oboturov    schedule 11.05.2012    source источник


Ответы (1)


taskGraph.hasTask() указывает, находится ли задача в графе выполнения задач, то есть будет ли она выполнена. Поскольку график выполнения задачи создается только после этапа настройки, этот метод необходимо вызывать из обратного вызова whenReady (или на этапе выполнения):

gradle.taskGraph.whenReady { graph ->
    if (graph.hasTask(developerBuild)) { 
        // do conditional configuration
    }
} 

Чтобы сделать это более читабельным, мы можем ввести новый метод:

def onlyFor(task, config) {
    gradle.taskGraph.whenReady { graph ->
        if (graph.hasTask(task)) { 
            project.configure(project, config)
        }
    }
}

Теперь мы можем написать:

onlyFor(developerBuild) { ... }
onlyFor(ciBuild) { ... } 

Другой, более простой способ решить эту проблему — проверить, содержится ли конкретное имя задачи в gradle.startParameter.taskNames. Однако у этого есть два ограничения: во-первых, он сравнивает имена задач, что может иметь значение при многопроектных сборках. Во-вторых, он найдет только те задачи, которые были указаны напрямую (например, в командной строке), но не их зависимости.

PS.: В вашем коде isDevBuild всегда выполняется, потому что (ненулевое) закрытие - это true в соответствии с истиной Groovy. (В отличие от isDevBuild(), isDevBuild не вызывает замыкание.)

person Peter Niederwieser    schedule 11.05.2012
comment
Возвращаясь к утверждению из книги Building and Testing with Gradle: знание Groovy не является плюсом — для начала работы с Gradle необходимо. Спасибо за вашу помощь. Сегодня проверю позже. - person Artem Oboturov; 11.05.2012
comment
Я бы не сказал, что это обязательно для начала, но необходимо внедрять передовые решения, подобные этому. (Простая альтернатива, которая требует меньше знаний Groovy, — это переключение между различными конфигурациями на основе системного свойства.) Опять же, большая часть этого кода может быть написана в стиле Java (с анонимными внутренними классами и т. д.) или буквально на Java, если вы переместил его в плагин. Настоящая проблема в этом конкретном случае состоит в том, чтобы понять сторону Gradle: API графа задач, этап конфигурации и выполнения и т. д. - person Peter Niederwieser; 11.05.2012
comment
Ваше решение работает хорошо. Большое спасибо. Для примечания, которое вы поместили в P.S. : Я не могу напрямую вызвать isDevBuild(), например, когда я запускаю сборку Gradle с ciBuild jar (и я не могу использовать обе конфигурации одновременно) - хотя вы показали, что я могу вызывать закрытие только в образовательных целях. - person Artem Oboturov; 14.05.2012
comment
Спасибо за рассмотрение вопроса на SO: не все ведущие разработчики уделяют время поддержке сообщества. - person Artem Oboturov; 14.05.2012