Глава 44. Скрипты инициализации.

Gradle предоставляет мощный механизм, который позволяет настроить сборки, основываясь на текущем окружении. Этот механизм также поддерживает инструменты, которые хотят интегрироваться с Gradle.

Обратите внимание, что этот механизм совсем не похож на задачу 'init', предоставляемую инкубационным плагином 'build-init' (смотрите Главу 17 Плагин инициализации сборки).

44.1. Основное использование.

Инициализационные скрипты похожи на остальные скрипты Gradle. Однако, эти скрипты запускаются до старта сборки. Вот несколько вариантов использования:

  • Установка конфигурации на всю организацию, например, где искать пользовательские плагины.
  • Установка свойств, основываясь на текущем окружении, например, машине разработчика или сервере непрерывной интеграции.
  • Предоставление персональной информации о пользователе, которая необходима сборке, такой как учетные данные для проверки подлинности при подключении к хранилищу или базе данных.
  • Задание присущих машине деталей, таких как расположение JDK.
  • Регистрация слушателей сборки. Это может быть полезно для внешних инструментов, которым необходимо слушать события Gradle.
  • Регистрация логгеров сборки. Вам может понадобиться настроить то, как Gradle логгирует сгенерированные события.

Одно главное ограничение заключается в том, что инициализационные скрипты не могут обращаться к классам, находящимся в проекте buildSrc (чтобы узнать больше об этом проекте, смотрите Секцию 43.4 Исходные коды сборки в проекте buildSrc).

44.2. Использование инициализационного скрипта.

Есть несколько способов, которыми можно использовать инициализационный скрипт:

  • Указать файл в командной строке. Для этого используется опция командной строки -I или --init-script за которой следует путь к скрипту. Можно указать больше одной опции, каждая следующая добавляет еще один инициализационный скрипт.
  • Положить файл init.gradle в папку USER_HOME/.gradle/
  • Положить файл, который оканчивается .gradle в папку USER_HOME/.gradle/init.d/
  • Положить файл, который оканчивается .gradle в папку GRADLE_HOME/init.d/ в дистрибутиве Gradle. Это позволяет создавать пользовательские дистрибутивы Gradle, который содержат какую-либо пользовательскую логику сборки и плагины. Вы можете это совместить с Gradle wrapper, чтобы сделать доступной вашу логику во всех сборка в организации.

Если найден более одного инициализационного скрипта, все они будут выполнены в порядке указанном выше. Скрипты в данной папке выполняются в алфавитном порядке. Это дает возможность, например, инструменту указать инициализационный скрипт в командной строке, а пользователю положить еще один в домашнюю папку для задания окружения и оба скрипта, будут запущены, когда выполнится Gradle.

44.3. Написание инициализационного скрипта.

Также как и сборочный скрипт Gradle, инициализационный использует Groovy. У каждого инициализационного скрипта есть экземпляр Gradle, ассоциированный с ним. Любая ссылка на свойство и вызов метода в инициализационном скрипте, будут переданы экземпляру Gradle.

Также каждый инициализационный скрипт реализует интерфейс Script.

43.3.1. Настройка проектов из инициализационного скрипта.

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

Пример 44.1. Использование инициализационного скрипта для выполнения дополнительной настройки до вычисления проектов

build.gradle

repositories {
    mavenCentral()
}

task showRepos {
    doLast {
        println "All repos:"
        println repositories.collect { it.name }
    }
}
	  

init.gradle

allprojects {
    repositories {
        mavenLocal()
    }
}
	  

Вывод команды gradle --init-script init.gradle -q showRepos

> gradle --init-script init.gradle -q showRepos
All repos:
[MavenLocal, MavenRepo]
	  

44.4. Внешние зависимости инициализационного скрипта.

В Секции 43.6 Внешние зависимости сборочного скрипта объяснялось как добавить внешние зависимости к сборочному скрипту. Инициализационные скрипты тоже могут объявлять зависимости. Вы может это сделать с помощью метода initscript(), передавая замыкание, которое объявляет путь к классам инициализационного скрипта.

Пример 44.2. Объявление внешних зависимостей инициализационного скрипта

init.gradle

initscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath group: 'org.apache.commons', name: 'commons-math', version: '2.0'
    }
}
	  

Замыкание, переданное в метод initscript(), настраивает экземпляр ScriptHandler. Вы объявляете путь к классам инициализационного скрипта, добавляя зависимости к конфигурации classpath. Такие же образом вы, например, объявляете путь к классам для компиляции Java. Вы можете использовать любой тип зависимости, описанный в Секции 25.4 Как объявить ваши зависимости, кроме зависимостей проекта.

Задав путь к класса инициализационного скрипта, вы можете использовать классы в скрипте, как и любые другие классы в пути к классам. Следующий пример основан на предыдущем, в нем используются классы из пути к классам инициализационного скрипта.

Пример 44.3. Инициализационный скрипт с внешними зависимостями

init.gradle

import org.apache.commons.math.fraction.Fraction

initscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath group: 'org.apache.commons', name: 'commons-math', version: '2.0'
    }
}

println Fraction.ONE_FIFTH.multiply(2)
	  

Вывод команды gradle --init-script init.gradle -q doNothing

> gradle --init-script init.gradle -q doNothing
2 / 5
	  

44.5. Плагины инициализационных скриптов.

К инициализационному скрипту могут применены плагины, так же как и к сборочному скрипту или файлу настроек.

Пример 44.4. Использование плагинов в инициализационных скриптах

init.gradle

apply plugin:EnterpriseRepositoryPlugin

class EnterpriseRepositoryPlugin implements Plugin<Gradle> {

    private static String ENTERPRISE_REPOSITORY_URL = "https://repo.gradle.org/gradle/repo"

    void apply(Gradle gradle) {
        // ONLY USE ENTERPRISE REPO FOR DEPENDENCIES
        gradle.allprojects{ project ->
            project.repositories {

                // Remove all repositories not pointing to the enterprise repository url
                all { ArtifactRepository repo ->
                    if (!(repo instanceof MavenArtifactRepository) ||
                          repo.url.toString() != ENTERPRISE_REPOSITORY_URL) {
                        project.logger.lifecycle "Repository ${repo.url} removed. Only $ENTERPRISE_REPOSITORY_URL is allowed"
                        remove repo
                    }
                }

                // add the enterprise repository
                maven {
                    name "STANDARD_ENTERPRISE_REPO"
                    url ENTERPRISE_REPOSITORY_URL
                }
            }
        }
    }
}
	  

build.gradle

repositories{
    mavenCentral()
}

 task showRepositories {
     doLast {
         repositories.each {
             println "repository: ${it.name} ('${it.url}')"
         }
     }
}
	  

Вывод команды gradle -q -I init.gradle showRepositories

> gradle -q -I init.gradle showRepositories
repository: STANDARD_ENTERPRISE_REPO ('https://repo.gradle.org/gradle/repo')
	  

Плагин в инициализационном скрипте обеспечивает использование только указанного хранилища, когда сборка запущена.

Когда плагины применяются в инициализационному скрипте, Gradle создает экземпляр плагина и вызывает его метод Plugin.apply(T). Объект gradle передается в качестве параметра и его можно использовать для настройки любых аспектов сборки. Само собой, примененный плагин может быть разрешен как внешняя зависимость, как было описано в Секции 44.4 Внешние зависимости инициализационного скрипта.