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

Gradle to the rescue

Gradle to the rescue

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

Avatar for Yuriy Artamonov

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 в каталоге проекта