Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Gradle to the rescue

Gradle to the rescue

Как начать использовать Gradle и как CUBA Platform использует его для организации сборки многомодульных проектов

Yuriy Artamonov

June 01, 2015
Tweet

More Decks by Yuriy Artamonov

Other Decks in Programming

Transcript

  1. Файлы сборки Gradle  Сборка описывается файлом “build.gradle” (+ опционально

    settings.gradle)  Язык файлов сборки - специальный Groovy DSL (Domain specific Language) Gradle DSL = Groovy + Gradle Build Features  Файл сборки может использовать декларативные конструкции для настройки типовых проектов и действий  Файл сборки – это код на Groovy (См. groovy-all)  Файл сборки может использовать другие файлы посредством включений “include”  Файл сборки может использовать специальным образом оформленные плагины для автоматизации типовых действий (сборка java-приложения, запуск сервера Jetty, упаковка веб-приложения в war)
  2. Задачи в Gradle  Единица исполнения – задача  Каждая

    задача – это объект  Задачи связаны между собой особым порядком исполнения и зависимостями  Задачи включают в себя несколько действий
  3. Блоки конфигурации  Задача может быть сконфигурирована при создании 

    Блок конфигурации следует за именем задачи без! каких либо обозначений и операторов  Задача может иметь несколько блоков конфигурации  Никогда не путайте блоки конфигурации с действиями задач!
  4. Фазы исполнения Gradle  initialization – выбрать проекты, участвующие в

    сборке, исполнить settings.gradle  configuration – собрать объекты задач и связать их между собой  execution – исполнить граф задач (DAG – directed acyclic graph)
  5. Методы класса DefaultTask  Все классы задачи наследуют класс DefaultTask

     DefaultTask не содержит никаких действий  В классе DefaultTask определены методы, позволяющие связывать задачи: • dependsOn(task) – добавить задачу в зависимости • doFirst(closure) – добавить действие в начало списка действий • doLast(closure) – добавить действие в конец списка действий • onlyIf(closure) – исполнять задачу, только если выполнено условие  Задачи, от которых зависит задача, всегда исполняются до зависимой  Вы можете добавлять действия даже для задач, которые созданы плагинами или объявлены в других файлах  Методы doFirst и doLast принимают Groovy замыкание (Closure)  Если задача отключена, то её действия будут проигнорированы (но её задачи-зависимости будут исполнены)
  6. Другие связи задач (INCUBATING)  mustRunAfter – упорядочивает задачи в

    DAG, позволяя сортировать задачи, не зависящие друг от друга. Например, если они не должны запускаться одновременно в параллельном режиме Gradle.  shouldRunAfter – более мягкий вариант mustRunAfter, такая связь может быть проигнорирована в некоторых случаях, например при появлении цикла в DAG или в параллельном режиме, если все зависимости кроме shouldRunAfter уже исполнены.  finalizedBy – позволяет всегда запуска задачу после некоторой (даже если не просили), независимо от её результата. Например, для управления ресурсами: файлами, соединениями, и т.д.
  7. Свойства класса DefaultTask  didWork (boolean ) – выполняла ли

    задача хоть какую-то работу  enabled (boolean) – свойство, позволяющие отключать задачи, как это делает условие onlyIf  path (String ) – путь к задаче в дереве проектов • :createDb – задача в корневом проекте • :cuba-web:compileJava – задача в проекте cuba-web  logger (org.slf4j.Logger) – интерфейс логгирования Gradle  logging.level – уровень логгирования, можно изменять  description (String) – описание задачи  temporaryDir (File) – указатель на temp директорию для сборки, задачи могут сохранять там промежуточные результаты работы
  8. Как создать свой класс задачи  В файле сборки build.gradle

     В проекте, в каталоге buildSrc  В плагине
  9. Входы и выходы задач  Задачи могут определять входные и

    выходные файлы  Если с прошлого запуска сборки ни входные, ни выходные файлы не изменились, то задача получает статус UP-TO-DATE, и её действия не исполняются См. @InputDirectory @OutputDirectory @Input
  10. Gradle – это Maven, только лучше  Gradle может использовать

    зависимости из Maven репозиториев  Gradle может генерировать pom.xml для собранных артефактов  Gradle расширяет модель зависимостей Maven, добавляя концепцию конфигураций  См. https://gradle.org/maven_vs_gradle/, - Gradle лучше чем Maven. - Чем? - Чем Maven.  Но! Gradle не использует Maven для разрешения зависимостей, он использует Apache Ivy
  11. Зависимости  Зависимости – артефакты (jar, zip, etc) или проекты

     Для каждой зависимости указывается group, name, version, [classifier], [ext]  Версия зависимости может быть фиксированной (релиз) или -SNAPSHOT  Зависимость входит в некоторую конфигурацию  Конфигурация – набор зависимостей, с особым назначением. Например: compile, runtime, provided  Зависимости бывают транзитивными (compile)  Зависимости в кастомных конфигурациях не могут быть транзитивными (ограничение Maven)
  12. Репозитории  Зависимости загружаются из репозиториев или могут использоваться напрямую

    из каталога проекта  Проект может иметь множество репозиториев  Репозитории могут быть удалённые и локальные (mavenLocal() ~/.m2)  Мы стараемся использовать свой Maven репозиторий, который кэширует сторонние библиотеки
  13. Публичные репозитории Maven Central http://mvnrepository.com/ http://search.maven.org/  Ищем зависимость 

    Проверяем лицензию! (Apache 2.0, LGPL, BSD, MIT)  Пробуем  Подключаем репозиторий в наш прокси репозиторий
  14. Кэширование зависимостей  Зависимости кэшируются в каталоге ~/.gradle  Gradle

    позволяет работать без обращения к репозиториям с ключом --offline  Чтобы принудительно перечитать –SNAPSHOT зависимости из репозиториев, запустите с ключом –-refresh-dependencies. Не нужно удалять кэш библиотек! Nexus Local Gradle Cache ~/.gradle Local M2 Cache ~/.m2 Working directory install assemble upload assemble assemble
  15. Многомодульные проекты  Gradle поддерживает сборку многомодульных проектов, в том

    числе можно использовать всего один файл сборки  Задачи получают уникальное имя по своему path -> :project:task  При запуске задачи без указания проекта, будут запущены задачи с таким именем из всех проектов
  16. Запуск модульных тестов  В модулях с плагином java уже

    есть задача test, можно просто настроить её  Тесты можно включать и исключать используя wildcard выражения  Для специальных тестов можно завести задачи типа Test, включив в них нужный набор тестов  Используйте опцию –-tests для указания конкретных тестов, если нужно запустить не все из набора: > gradle testUi –-tests com.Haulmont.cuba.web.test.UserUiTest.someTestMethod
  17. Пользуемся консолью правильно  Чтобы посмотреть все доступные задачи, выполните:

    > gradle tasks  Если вы изменяете код только одного модуля большого проекта, то есть смысл и собирать, и деплоить только его, экономя время: > gradle :cuba-web:deploy start  Если мы хотим очистить результаты сборки проекта или задачи, то не нужно очищать весь проект! > gradle :cuba-web:clean > gradle :cuba-web:cleanCompileJava // clean<capitalized(taskName)>  Используем gradle –-daemon  Заведите короткий вариант команды gradle –-daemon: gd.bat gradle --daemon %*  Используем аббревиатуры для запуска задач: > gradle clCo ass // cleanConf assemble  Используем gradle –-parallel (если это позволяет проект)
  18. Пишем плагин для Gradle  Плагины могут делать тоже самое,

    что и сами скрипты сборки: создавать задачи, конфигурации, добавлять зависимости, и т.д.  Плагин собирается в артефакт и публикуется в репозитории  Плагины можно отлаживать, как Java приложение
  19. Отладка плагина  Добавить переменную окружения GRADLE_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005 

    При запуске сборки gradle остановиться и будет ожидать подключения отладчика  Открыть проект в Idea, создать debug конфигурацию типа Remote  Подключиться, можно отлаживать  Не забыть подключить исходники Gradle в проект, чтобы можно было смотреть документацию по модели задач и проектов
  20. Что там такого в cuba-plugin понаписано?  Добавляем задачи в

    проект: setupTomcat, start, stop, dropTomcat, assembleDbScripts (core)  Указываем в какой репозиторий делать upload сборок  Берём все репозитории из секции buildscript и добавляем в репозитории проекта  Настраиваем типовые директории исходников и тестов: src и test  Настраиваем файлы проектов для IntelliJ Idea: File Encoding, Show Excluded files: false, VCS type, Copyright, Default Debug configuration, Exclude *.ipr *.iml *.iws files, Select JDK version, Add enhanced OpenJPA classes as library dependency  Разрешение конфликтов зависимостей между core, web и portal при общем развёртывании в один Tomcat  Куча разных типов задач
  21. Типовые файлы сборки проекта на CUBA  В файле settings.gradle

    указываем набор модулей и их расположение  В файле build.gradle в секции buildscript: 1) подключаем репозиторий 2) указываем версию платформы как переменную 3) подключаем cuba-plugin  В секции allprojects объявляем группу и версию артефактов, а также параметры для IDE  В секциях configure настраиваем зависимости и задачи модулей См. https://github.com/Haulmont/platform-sample-sales
  22. Разные трюки  Чтобы остановить дальнейшее исполнение всех действий задачи,

    выбросьте исключение StopExecutionException  Чтобы посмотреть все зависимости модуля, выполните: > gradle :project:dependencies > deps.log  Чтобы собрать два jar артефакта (без classifier) из одного проекта заведите один проект в другом и укажите для него отдельный каталог сборки buildDir.  Чтобы осмотреться в новом проекте попробуйте Gradle GUI: gradle –-gui  Попробуйте –-continuous режим, например для сборки тем приложения (INCUBATING)  В Linux очень удобно пользоваться gvm.  В Gradle есть API инкрементальной сборки, если ваша задача работает по независимым файлам, то вы можете его применить и получить выигрыш при постоянной пересборке проекта. См. IncrementalTaskInputs (INCUBATING)  На сервере CI старайтесь запускать все задачи в Gradle разом: > gradle assemble test upload возможности использовать daemon режим там нет, а это экономит время на запуск gradle  Если вы хотите отправить кому-то проект в ZIP архиве, то не забудьте: 1) > gradle clean 2) удалить директории .gradle и .svn/.git в каталоге проекта