gradle запуск с параметрами

Сборка Java-проекта с использованием Gradle

Этот урок освещает создание вами простого Java-приложения с использованием Gradle.

Что вы создадите

Вы создадите простое приложение и соберете его с помощью Gradle.

Что вам потребуется

Как проходить этот урок

Как и большинство уроков по Spring, вы можете начать с нуля и выполнять каждый шаг, либо пропустить базовые шаги, которые вам уже знакомы. В любом случае, вы в конечном итоге получите рабочий код.

Чтобы начать с нуля, перейдите в Настройка проекта.

Настройка проекта

Для начала вам необходимо настроить Java-проект перед тем, как собрать его Gradle’ом. Т.к. урок посвящен Gradle, сделаем проект максимально простым, насколько это возможно.

Создание структуры каталогов

Установка Gradle

Теперь, когда у вас есть проект, который вы можете собрать с Gradle, вам нужно установит сам Gradle.

Gradle можно получить, скачав zip-файл с gradle.org/downloads. Необходимы только бинарные файлы, так что ищите ссылку на архив с именем gradle-version-bin.zip. (Вы также можете выбрать gradle-version-all.zip, тем самым получите исходники, документацию и бинарные файлы.)

Распакуйте архив и добавьте путь к каталогу bin в переменную окружения path.

Чтобы протестировать правильность установки Gradle, запустите в командной строке:

Если всё было сделано правильно, то вы увидите сообщение:

Теперь у вас есть установленный Gradle.

Что может делать Gradle

Теперь, когда Gradle установлен, посмотрим, что он может делать. Прежде, чем вы создадите build.gradle для проекта, выможете проверить, какие доступны задачи:

Вы должны увидеть список доступных задач. Если вы запустите Gradle в каталоге, в котором нет ещё файла build.gradle, то увидите несколько самых элементарных задач:

Говоря о добавлении плагинов, в следующей части урока вы добавите плагин, который отвечает за базовую функциональность сборки Java-проектов.

Сборка Java кода

Начнем с простого, создадим очень простой build.gradle в корневой папке проекта(там, где src), который содержит только одну строчку:

Эта единственная строчка в конфигурации сборки приносит значительную пользу. Запустите gradle tasks снова и вы увидите новые задачи в списке, включая задачи для сборки проекта, создания JavaDoc и запуска тестов.

Вы будете изпользовать задачу gradle build достаточно часто. Эта задача компилирует, тестирует и упаковывает код в JAR-файл. Вы можете запустить её таким образом:

Через несколько секунд, «BUILD SUCCESSFUL» будет означать, что сборка прошла успешно.

На данный момент проект не имеет зависимостей от библиотек, поэтому ничего нет в папке dependency_cache.

Каталог отчетов должен содержать отчет о выполнении тестов для проекта. Т.к. проект пока не содержит тестов, данный отчет будет нам неинтересен.

Каталог библиотек должен содержать JAR-файл с названием каталога проекта. В дальнейшем, вы увидите, как указывать имя JAR-файла и его версию.

Объявление зависимостей

Простой «Hello World» пример полностью автономный и не зависит от каких-либо дополнительных библиотек. Однако, большинство приложений зависит от внешних библиотек, с реализацией распостраненного и/или сложного функционала.

К примеру, предположим, что в дополнение к «Hello World!» вы хотите, чтобы приложение печатало текущую дату и время. Вы могли бы использовать функциональность из стандартных(native) Java библиотек, но мы можем сделать это и другими интересными способами, например с помощью Joda Time библиотеки.

Здесь HelloWorld использует Joda Time LocalTime класс для получения и печати текущего времени.

Если бы вы запустили gradle build для сборки проекта сейчас, то получили бы ошибку сборки, потому что вы не объявили Joda Time компилируемую зависимость в сборке.

Во-вторых, вам необходимо добавить источники сторонних библиотек:

Блок repositories означает, что сборка должна разрешать зависимости из Maven Central репозитория. Gradle опирается в основном на многие соглашения и возможности, определенные в инструменте сборки Maven, включая использование Maven Central как источник библиотек зависимостей.

Теперь, когда мы готовы к приему сторонних библиотек, объявим их:

В блоке dependencies вы описываете единственную зависимость Joda Time. В частности, вы запрашиваете(читаем справа на лево) версию 2.2 библиотеки joda-time в joda-time группе.

И наконец, назначим имя для нашего JAR артефакта.

Сборка проекта с Gradle Wrapper

Gradle Wrapper является предпочтительным способом для начала Gradle сборки. Он содержит bat-скрипты для Windows и shell-скрипты для OS X и Linux. Эти скрипты позволяют вам запускать сборку с Gradle без необходимости установки самого Gradle в вашу систему. Чтобы это стало возможным, добавьте следующий блок в конец вашего build.gradle :

Запустите следующую команду для загрузки и инициализации wrapper-скриптов:

Gradle Wrapper теперь доступен вам для сборки проекта. Добавьте его в вашу систему контроля версий и каждый, кто клонирует ваш проект, сможет его собрать точно таким же способом. Gradle Wrapper можно использовать наравне с установленным Gradle. Pfgecnbnt wrapper-скрипт для выполнения задичи сборки точно так же, как вы делали ранее:

Ранее, когда вы запускали wrapper с конкретной версией Gradle, он загружал и кешировал бинарники Gradle для соответствующей версии. Gradle Wrapper спроектирован таким образом, чтобы было возможно сохранить его в репозитории вашей VCS и любой, кто его клонирует, сможет собрать ваш проект без необходимости устанавливать и настраивать Gradle определенной версии.

На данном этапе у вас есть собранный ваш код. В результате вы увидете:

Это содержимое пакета файлов классов. Важно отметить, что даже, если вы и объявили joda-time как зависимость, библиотека не включена в пакет. И JAR-файл будет неспособен к выполнению.

Затем просто запустите ваше приложение!

Остановимся подробнее на упаковке зависимостей. К примеру, если бы мы собирали WAR-файл, общепризнанный формат, ассоциирующийся с упаковкой сторонних зависимостей, мы бы могли использовать WAR плагин. Если вы используете Spring Boot и хотите получить исполняемый JAR-файл, тогда вам пригодится spring-boot-gradle-plugin. На данном этапе, gradle недостаточно знает о выбранной вами системе. Но этого достаточно, чтобы приступить к работе с gradle.

В конечном счете, у вас должен получиться такой build.gradle файл:

Поздравляем! Вы создали простой, но эффективный файл сборки Gradle для сборки Java проектов.

Источник

Крибле Крабле Gradle: магия автоматической сборки

Разработчики облегчают жизнь людям, а Gradle — разработчикам. Если вы пишете на Android, эта статья для вас. Читайте о том, что за зверь этот Gradle (спойлер: он слон), а также — как с ним работать.

Gradle — система автоматической сборки, которую используют для упрощения работы с Java. С помощью (условно) стандартизированных средств она помогает разработчикам собрать нужный продукт без потери его уникальности. Ведь процесс работы с Gradle — не просто выбор шаблона. Но обо всём по порядку.

gradle запуск с параметрами. Смотреть фото gradle запуск с параметрами. Смотреть картинку gradle запуск с параметрами. Картинка про gradle запуск с параметрами. Фото gradle запуск с параметрами

Где скачать Gradle

Скачать Gradle можно на официальном сайте. Рекомендуем качать и устанавливать всё вручную (чтобы жизнь малиной не казалась). Инструкция, а также все необходимые ссылки даны в разделе Installing Gradle > Installing Manually. Кстати, рекомендуем прочитать всё. Вообще всё. Серьёзно.

Иногда выходит так, что во время определения система находит Gradle в неожиданном месте. На Windows это решается следующим образом:
for %i in (gradle.bat) do echo. %

Как работать с Gradle

Gradle не привязан к конкретной платформе. К тому же, в системе используют разные языки программирования. Наиболее популярные — Groovy DSL и Kotlin (но можно писать и на других). В статье будет использован первый вариант, так как это стандартный язык описания задач в Gradle.

Прежде чем начинать работу, обратите внимание на термины: «задача» и «плагин», ещё раз. Ведь именно на них строится вся работа с системой. Плагины предоставляют и создают задачи. Задачи — те действия, которые надо сделать. Всё очень просто.

Подробнее об этом вы можете прочитать в инструкции к плагинам: JavaCompile (добавить новые задачи), SourceSet (добавить новые объекты домена). Также плагины работают с соглашениями и расширяют объекты. Например, с помощью плагина можно добавить новые элементы DSL и (или) настроить их.

Набор «Core Plugins» автоматически создаётся при установке Gradle. На первых этапах рекомендуют использовать категорию «Utility», а именно — плагин «Build Init Plugin». Он предоставляет задачи для инициализации проекта в системе. Выбрать тип проекта можно из списка на сайте.

После этого в папке появятся новые файлы. В их числе:

В последнем файле будет отображена секция плагина. Этот плагин уже имеет прикреплённые к нему задачи. Их список можно посмотреть с помощью команды gradle tasks.

Задачи

Показаны блоками, по своим функциям. К каждой даётся краткое описание. Для понимания требуется знание английского на базовом уровне. Если вы не входите в эту группу — подойдёт любой переводчик. Сложных языковых конструкций в build.gradle нет.

После выбора задачи и её успешного завершения вы увидите внизу зелёную надпись «BUILD SUCCESSFUL». Это значит, что (вам повезло) всё прошло без проблем. Также внизу система выдаст краткий отчёт.

Если статус «executed» — задача действительно выполнена. Если «up-to-date» — нет. Это не значит, что произошёл какой-то сбой. В случае такого статуса задача не требует решения в принципе, т. е. её объект уже в актуальном состоянии.

Это произошло потому, что в Gradle автоматически формируется «Up-to-date checks» — инкрементальный билд, цель которого — оптимизация работы системы. Поэтому задачи, которые уже завершены или не требуют действий, не прорабатываются.

Зависимости

Управление зависимостями — указание библиотек или фреймворков, которые нужны проекту. Gradle должна включить эти зависимости в определённый момент, чтобы в конце собрать приложение корректно (или вообще). Команда gradle init для java-application в build-скрипте автоматически вызывает информацию о 2 конфигурациях.

Implementation отвечает за транзитивность: её зависимости будут невидимыми для пользователей. TestImplementation расширяет предыдущую конфигурацию. Таким образом, они работают в связке.

Чтобы лучше понять зависимости и принцип работы с ними, прочтите главу «Managing Dependency Configurations» в официальной инструкции. Кстати, в «API and implementation separation» подробно объясняется про API и implementation, а также разницу между ними.

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

Далее нужно включить в jar зависимости. Это необходимо для компиляции.
Слишком сложно? Используйте «Gradle Shadow Plugin».

Наиболее частые виды зависимостей:

Что из этого списка использовать, решает разработчик.
Для Java всё хорошо расписано в «Dependency management».

Лайфхаки

Несмотря на то, что Gradle — популярная и актуальная система автоматической сборки, проблемы в работе с ней возникают у многих. Вот несколько рекомендаций, которые могут значительно облегчить жизнь android-разработчику:

Используйте консоль. Найти команды иногда бывает проблематично, а при изменении build.gradle система может заглючить или, вообще, перезагрузить проект. Поэтому специалисты рекомендуют вызывать Gradle прямо из консоли.

Враппер обычно идёт вместе с проектом. На Linux и macOS можно обращаться напрямую. На Windows — вызывать вместо враппера bat-файл.

Gradle хранит кэш 1 сутки. Это можно перенастроить. Необходимо отредактировать код:

– –refresh-dependencies — полезная команда, которая запустит обновление всех зависимостей в Gradle. Может пригодиться, если какие-то данные в кэше повредились, так как верифицирует. Удобно использовать при повреждении данных кэша, так как происходит их верификация и обновление (если отличаются).

Используйте CI (непрерывную интеграцию) в работе с системой автоматической сборки. Пусть модульные тесты выполняются для всех коммитов. Также специалисты рекомендуют подключать и unit-тесты. Это можно сделать в Android Studio.

Такая комбинация позволит обнаружить ошибки раньше. И хотя она замедлит процесс запуска, разработчик сможет отдохнуть в дальнейшем. Так что лайфхак на перспективу.

Try again. Страшно? (Нам тоже) На самом деле синхронизацию не всегда нужно сразу запускать заново. Сначала специалисты рекомендуют проверить систему в целом. Например, с помощью любой простой команды — это поможет понять, каковы шансы на успех следующей синхронизации.

Настройте с Gradle среду разработки IntelliJ IDEA. Это позволит оптимизировать процесс работы, а также воспользоваться волшебным списком.

Совет для тех, кто работает с Gradle из командной строки Android Studio. Проверьтесь на ошибку «Starting a Gradle Daemon, 1 incompatible could not be reused» (#68374709). Это бич системы, который разработчики пока не исправили.

Одна из основных проблем Gradle — «Gradle build failed». Обойдёмся без лишних слов, если вам это уже знакомо. Если же нет — удачи.

gradle запуск с параметрами. Смотреть фото gradle запуск с параметрами. Смотреть картинку gradle запуск с параметрами. Картинка про gradle запуск с параметрами. Фото gradle запуск с параметрами

Впрочем, главная проблема Gradle другая. Время, которое требуется системе на сборку, уже давно стало (очень печальной) легендой в кругах специалистов. Ускорить работу нельзя, по крайней мере — значительно.

Так что придётся ждать в любом случае.

Можете, например, слетать куда-нибудь в космос, как в «Интерстеллар».

gradle запуск с параметрами. Смотреть фото gradle запуск с параметрами. Смотреть картинку gradle запуск с параметрами. Картинка про gradle запуск с параметрами. Фото gradle запуск с параметрами

Вывод

Gradle — это хорошее решение, несмотря на все минусы. Автоматическая сборка позволит вам сэкономить силы и время (как иронично это бы ни звучало после предыдущего абзаца). А также — сделать своё приложение чище. Система заметит любую ошибку и не позволит закончить работу, пока та не будет исправлена (любой ценой).

Источник

Многомодульный Java-проект с Gradle. Шаг за шагом

Очень много статей о Gradle написано. И со своей стороны хотелось бы добавить в копилку такую пошаговую инструкцию, прочтение которой, я надеюсь, позволит тем, кто плохо знаком с Gradle, “распробовать” и продолжить самостоятельно изучать этот инструмент.

Данная статья не будет подробно описывать такие темы, как плагины gradle (plugin), задачи (task), зависимости (dependencies), автоматическое тестирование и прочие прелести этого сборщика проектов. Во-первых, каждая тема заслуживает отдельной статьи или даже серии статей, а во-вторых, на эти темы уже есть статьи на хабре, например: Gradle: Tasks Are Code, Gradle: Better Way To Build. А еще на официальном сайте Gradle есть прекрасно написанный Gradle User Guide. Я же cфокусирую внимание на непосредственном решении поставленной задачи, и все сопутствующие темы будут описаны в рамках этой самой задачи.
Сначала определимся с целью, что же мы хотим получить на выходе? А цель указана в заголовке статьи. Мы хотим получить проект с несколькими модулями, который собирается с помощью Gradle. И так, приступим.

Шаг 1. Установка gradle

Примечение: Если выхотите просто “поиграть” с gradle, скачав файлы для статьи, или вам достались чужие исходники с волшебным файлом gradlew (gradlew.bat) в корне проекта, то устанавливать gradle не обязательно.

Gradle можно поставить, скачав последнюю версию со страницы загрузок Gradle или воспользовавшись менеджером пакетов в вашей любимой ОС (прим. Я ставил на Mac OS через brew и на Debian через apt-get из стандартных источников)

Результат первого шага:

Шаг 2. Пустой проект, плагины (plugin), обертка (wrapper)

Создадим папку проекта и в ее корне сделаем файл build.gradle со следующим содержимым:

Итоги второго шага (вывод сокращен):

Шаг 3. Заполняем пробелы

Для сравнения аналогичный блок в maven:

Итоги третьего шага:

Видно, что скачивается недостающая библиотека, и продемонстрировано ее использование.

Шаг 4. Достижение цели

Дополнение от MiniM: В gradle символ «:» используется вместо «/» и для более ветвистой структуры ссылки на проект могут выглядеть так «:loaders:xml-loader»

/main_project/build.gradle (блок dependencies )

Итог четвертого шага:

Шаг 5 (заключительный). Убираем мусор

Основная цель достигнута, но на данном этапе могли возникнуть вполне закономерные вопросы о дублировании информации в build файлах, более глубокой настройке gradle, а также о том, что изучать дальше. Для самостоятельного изучения, я советую ознакомиться с содержимым ссылок в конце статьи. А пока, давайте приведем в порядок наши build файлы, создав build.gradle в корне проекта и изменив содержимое остальных build файлов

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

Источник

Шпаргалка по Gradle

Как мне кажется, большинство людей начинают разбираться с gradle только тогда, когда в проекте что-то надо добавить или что-то внезапно ломается — и после решения проблемы «нажитый непосильным трудом» опыт благополучно забывается. Причём многие примеры в интернете похожи на ускоспециализированные заклинания, не добавляющие понимания происходящего:

Я не собираюсь подробно описывать, для чего нужна каждая строчка выше — это частные детали реализации андроид-плагина. Есть кое-что более ценное — понимание того, как всё организовано. Информация раскидана по различным сайтам/официальной документации/исходникам градла и плагинов к нему — в общем, это чуть более универсальное знание, которое не хочется забывать.

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

Полезные ссылки

Консоль

Android studio/IDEA старательно прячет команды gradle от разработчика, а ещё при изменении build.gradle файликов начинает тупить или перезагружать проект.

В таких случаях вызывать gradle из консоли оказывается намного проще и быстрее. Враппер для gradle обычно идёт вместе с проектом и прекрасно работает в linux/macos/windows, разве что в последнем надо вызывать bat-файлик вместо враппера.

Вызов задач

пишет доступные задачи.

Можно вызвать любую задачу, при этом будут вызваны все задачи, от которых она зависит.

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

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

Логгинг

Можно и самому писать в лог:

логгер является имплементацией SLF4J.

Groovy

Происходящее в build.gradle файликах — просто код на groovy.

Groovy как язык программирования почему-то не очень популярен, хотя, как мне кажется, он сам по себе достоин хотя бы небольшого изучения. Язык появился на свет ещё в 2003 году и потихоньку развивался. Интересные особенности:

В общем, почему языки типа Python/Javascript взлетели, а Groovy нет — для меня загадка. Для своего времени, когда в java даже лямбд не было, а альтернативы типа kotlin/scala только-только появлялись или ещё не существовали, Groovy должен был выглядеть реально интересным языком.

Именно гибкость синтаксиса groovy и динамическая типизация позволила в gradle создавать лаконичные DSL.

Сейчас в официальной документации Gradle примеры продублированы на Kotlin, и вроде как планируется переходить на него, но код уже не выглядит таким простым и становится больше похожим на обычный код:

Впрочем, переименование в Kradle пока не планируется.

Стадии сборки

Их делят на инициализацию, конфигурацию и выполнение.

Идея состоит в том, что gradle собирает ациклический граф зависимостей и вызывает только необходимый минимум их них. Если я правильно понял, стадия инициализации происходит в тот момент, когда исполняется код из build.gradle.

Возможно, это неочевидно, но вышеуказанное будет тормозить инициализацию. Чтобы не заниматься копированием файлов при каждой инициализации, нужно в задаче использоваль блок doLast <. >или doFirst <. >— тогда код завернётся в замыкание и его позовут в момент выполнения задачи.

tasks.all

Что забавно, с помощью doLast и doFirst можно навешивать какие-то действия на любые задачи:

Создадим задачу, которая распечатает зависимости всех задач:

Если tasks.all<> вызвать во время выполнения (в блоке doLast ), то мы увидим все задачи и зависимости.
Если сделать то же самое без doLast (т.е., во время инициализации), то у распечатанных задач может не хватать зависимостей, так как они ещё не были добавлены.

Ах да, зависимости! Если другая задача должна зависеть от результатов выполнения нашей, то стоит добавить зависимость:

inputs, outputs и инкрементальная сборка

Обычная задача будет вызываться каждый раз. Если указать, что задача на основе файла А генерирует файл Б, то gradle будет пропускать задачу, если эти файлы не изменились. Причём gradle проверяет не дату изменения файла, а именно его содержимое.

task description

task.enabled

можно «выключить» задачу — тогда её зависимости будут всё равно вызваны, а она сама — нет.

несколько проектов (модулей)

В основном проекте можно расположить ещё несколько модулей. Например, такое используется в андроид проектах — в рутовом проекте почти ничего нет, в подпроекте включается android плагин. Если захочется добавить новый модуль — можно добавить ещё один, и там, например, тоже подключить android плагин, но использовать другие настройки для него.

Ещё пример: при публикации проекта с помощью jitpack в рутовом проекте описывается, с какими настройками публиковать дочерний модуль, который про факт публикации может даже не подозревать.

Дочерние модули указываются в settings.gradle:

Подробнее про зависимости между проектами можно почитать здесь

buildSrc

К сожалению, с проектом в buildSrc IDE может тупить c подсказками, там придётся писать импорты и классы/задачи оттуда в обычный build.gradle тоже придётся импортировать. Написать import com.smth.Taskname — не сложно, просто надо это помнить и не ломать голову, почему задача из buildSrc не найдена).

Свой тип задачи

Когда для нашей задачи кто-то в build.gradle пишет

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

Причём даже если написать

то метод configure всё равно будет вызван.

Свой плагин

Подобно задаче, можно написать свой плагин, который будет что-то настраивать или создавать задачи. Например, происходящее в android <. >— полностью заслуга тёмной магии андроид плагина, который вдобавок создаёт целую кучу задач типа app:assembleDevelopDebug на все возможные сочетания flavor/build type/dimenstion. Ничего сложного в написании своего плагина нет, для лучшего понимания можно посмотреть код других плагинов.

The end

В примерах выше могут быть опечатки и неточности. Пишите в личку или отмечайте с ctrl+enter — исправлю. Конкретные примеры лучше брать из документации, а на эту статью смотреть как на списочек того «как можно делать».

Источник

Советы по работе с Gradle для Android-разработчиков

Всем привет! Я пишу приложения под Android, в мире которого система сборки Gradle является стандартом де-факто. Я решил поделиться некоторыми советами по работе с системой с теми, у кого нет чёткого понимания, как правильно структурировать свои проекты и писать build-скрипты.

gradle запуск с параметрами. Смотреть фото gradle запуск с параметрами. Смотреть картинку gradle запуск с параметрами. Картинка про gradle запуск с параметрами. Фото gradle запуск с параметрами

Часто разработчики используют Gradle по наитию и не изучают целенаправленно, потому что не всегда хватает ресурсов на инфраструктурные задачи. А если возникают какие-либо проблемы, то просто копируют готовые куски build-скриптов из ответов на Stack Overflow. Во многом проблема кроется в сложности и чрезмерной гибкости Gradle, а также в отсутствии описания лучших практик в официальной документации.

Поработав больше пяти лет на аутсорсе, я видел много проектов разной сложности. И на всех этих проектах build-скрипты писались по-разному, где-то встречались не очень удачные решения. Я провел небольшую ретроспективу и резюмировал свой опыт в виде разных советов по использованию Gradle и рассказал их на одном из наших внутренних митапов. В статье я перевел эти советы в текст.

Небольшой оффтоп для тех, кому совсем ничего не понятно в Gradle-скриптах

Я заметил, что в Android-сообществе встречаются люди, которые могут годами разрабатывать приложения, но при этом не понимать, как работает Gradle. И достаточно продолжительное время и я был одним из них. Но однажды всё же решил, что гораздо проще потратить время на системное изучение Gradle, чем постоянно натыкаться на непонятные проблемы.

А так как лучший способ изучить что-то — это попытаться рассказать об этом другим людям, то я подготовил рассказ об основах использования Gradle в контексте Android-разработки специально для тех, кто совсем не разбирается в теме. Так что, возможно, этот митап вам поможет.

#1 Не редактируйте Gradle-скрипты через IDE

gradle запуск с параметрами. Смотреть фото gradle запуск с параметрами. Смотреть картинку gradle запуск с параметрами. Картинка про gradle запуск с параметрами. Фото gradle запуск с параметрами

Мой совет: лучше не редактировать скрипты через IDE, а использовать редактор кода.

#2 Обращайте внимание на соглашение по именованию модулей

#3 Что выбрать: Kotlin vs Groovy

Изначально в Gradle для DSL использовался язык Groovy, но впоследствии была добавлена возможность писать build-скрипты на Kotlin. Возникает вопрос: что же сейчас использовать? И однозначного ответа на него пока что нет.

Лично я за использование Kotlin, так как не очень хочу только лишь ради build-системы изучать ещё один язык — Groovy. Наверно, для всего Android сообщества DSL на Kotlin существенно понижает порог вхождения в Gradle. Кроме того, у build-скриптов на Kotlin лучше поддержка в IDE с автокомплитом, но, тем не менее, она все еще далека от идеала.

В качестве минуса Kotlin я бы выделил то, что могут встретиться какие-то старые плагины, которые изначально были заточены только под Groovy, и для их подключения придется потратить больше времени.

Если у вас старый большой проект с build-скриптами на Groovy, то могу посоветовать частично попробовать какие-то скрипты перевести на Kotlin, если вам понравится, то можно будет постепенно делать рефакторинг и переписывать все скрипты на Kotlin, не обязательно делать это единовременно.

#4 Как прописывать зависимости в многомодульных проектах

Возьмем небольшой пример проекта со следующей структурой:
gradle запуск с параметрами. Смотреть фото gradle запуск с параметрами. Смотреть картинку gradle запуск с параметрами. Картинка про gradle запуск с параметрами. Фото gradle запуск с параметрами

Основной модуль, из которого собирается apk, зависит от feature-модулей, а также в нём прописаны какие-то внешние зависимости. feature-модули, в свою очередь, содержат транзитивные зависимости, которые могут пересекаться с зависимостями в других модулях.

В чем проблема такого проекта? Здесь будет тяжело глобально обновлять зависимости в каждом из файлов. Очень легко забыть поднять версию в одном из скриптов, и тогда возникнут конфликты. По умолчанию Gradle умеет разрешать такие конфликты, выбирая максимальную версию, так что, скорее всего, сборка будет успешной (поведение можно менять через resolution strategy).

Но, конечно же, сознательно допускать конфликты версий не стоит, и для решения этой проблемы есть официальный способ, описанный в документации Gradle, использование которого я никогда не встречал на практике. Вместо него сообщество придумало достаточно простой трюк: прописывать строки с зависимостями где-то глобально и обращаться к ним из build-скриптов. Тут я хочу рассмотреть эти способы чуть подробнее.

Java platform plugin

Разработчики Gradle предлагают для описания зависимостей создать отдельный специальный модуль, где будут описаны только зависимости с конкретными версиями. К этому модулю надо применить java platform plugin. Далее подключаем этот модуль в остальные модули и при указании каких-то внешних зависимостей не пишем конкретную версию:

gradle запуск с параметрами. Смотреть фото gradle запуск с параметрами. Смотреть картинку gradle запуск с параметрами. Картинка про gradle запуск с параметрами. Фото gradle запуск с параметрами

Такие platform-проекты можно даже публиковать на внешние maven репозитории и переиспользовать. В качестве минуса подхода можно назвать то, что при мажорных обновлениях библиотек часто меняются не только версии, но и названия модулей, и тогда все равно придется вносить изменения сразу в нескольких скриптах.

Перейду к общепринятым в сообществе способам описания зависимостей.

Описание зависимостей в extra properties

Достаточно часто можно увидеть практику, когда строки с зависимостями хранят в extra properties корневого проекта, по сути это словарь, доступный всем дочерним модулям. Пример использования можно встретить в некоторых библиотеках от Google.

В корневом проекте описываем зависимости. Вот кусок build-скрипта из библиотеки Google, где зависимость возвращается функцией compatibility :

И обращаемся к ним из дочерних модулей:

Описание зависимостей в скриптовом плагине

Описанный способ с extra properties можно немного модифицировать и вынести описание зависимостей в скриптовый плагин, чтобы не засорять корневой проект. А уже скриптовый плагин можно применить или к корневому, или ко всем дочерним проектам сразу (через allprojects <> ), или к отдельным. Такой способ я тоже встречал.

Описание зависимостей в buildSrc

В buildSrc можно писать любой код, который будет компилироваться и добавляться в classpath build-скриптов. В последнее время стало популярно использовать buildSrc для описания там зависимостей. Например, в библиотеке Insetter Chris Banes так и делает.

Все, что нужно, — это добавить синглтон со строками в buildSrc, и он станет виден всем модулям в проекте:

Использовать buildSrc для зависимостей очень удобно, так как будут статические проверки и автокомплит в IDE:

gradle запуск с параметрами. Смотреть фото gradle запуск с параметрами. Смотреть картинку gradle запуск с параметрами. Картинка про gradle запуск с параметрами. Фото gradle запуск с параметрами

Но у этого решения есть один недостаток: любое изменение в buildSrc будет инвалидировать весь кэш сборки, что может быть несущественно для средних и маленьких проектов, но выливаться в серьезные проблемы для больших команд.

Композитные сборки

Можно достичь похожего результата со статическими проверками и автокомплитом, используя композитные сборки, при этом избавившись от проблемы инвалидации всего кэша. Я расскажу про него лишь кратко, а подробный гайд по миграции с buildSrc можно прочитать в статье из блога Badoo или статье от Josef Raska.

gradle запуск с параметрами. Смотреть фото gradle запуск с параметрами. Смотреть картинку gradle запуск с параметрами. Картинка про gradle запуск с параметрами. Фото gradle запуск с параметрами

Если мы хотим всего лишь подсунуть в classpath build-скриптов строки с зависимостями, то достаточно создать пустой плагин, а рядом с ним положить тот же файл с зависимостями, который мы использовали раньше в buildSrc:

Все, что осталось сделать, — применить плагин к корневому проекту:

И мы получим практически тот же результат, как и с использованием buildSrc.

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

#5 Как обновлять зависимости

gradle запуск с параметрами. Смотреть фото gradle запуск с параметрами. Смотреть картинку gradle запуск с параметрами. Картинка про gradle запуск с параметрами. Фото gradle запуск с параметрами

Но этот инструмент работает только для зависимостей, описанных строковыми литералами в build-скриптах, а если мы попытаемся использовать способ с композитными сборками, buildSrc или extra properties, то IDE перестанет нам помогать. Кроме того, визуально просматривать build-скрипты в модулях, для того чтобы сделать обновление библиотек, на мой взгляд, не очень удобно.

Но есть решение — использовать gradle-versions-plugin. Для этого просто применяем плагин к корневому проекту и регистрируем task для проверки новых версий зависимостей. Этот task надо настроить, передав ему лямбду для определения нестабильных версий:

#6 Старайтесь не использовать feature-флаги в build config

Во многих проектах release, debug и другие сборки отличаются по функциональности. Например, в отладочных сборках могут быть включены какие-то логи, мониторинг сетевого трафика через прокси, debug menu для смены окружений и т.д. И часто для реализации такого используют флаги, прописанные в build config, например:

А дальше такие флаги используются в коде приложения:

Например, мы можем выделить debug menu в отдельный модуль и подключать его только для debug и QA-сборок:

А stub реализацию для релизной сборки можно реализовать через source set.

#7 Несколько слов про базовую структуру проекта

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

Если для крупных проектов модуляризация кажется вполне очевидным решением, то не совсем понятно, как стоит поступать при старте небольших проектов или когда невозможно предсказать дальнейшее развитие кодовой базы продукта. Нужно ли выделять какие-то модули или достаточно начать с монолита? Я бы, помимо app модуля с основным приложением, всегда выделял как минимум два отдельных модуля:

#8 Не забывайте про matchingFallbacks

#9 Убирайте ненужные build variant

Build variant формируются из всех возможных сочетаний product flavor и build type. Возьмем небольшой синтетический пример: создадим три build type – debug (отладочная сборка), release (сборка в маркет) и qa (сборка для тестирования), а во flavor вынесем разные сервера, на которые может смотреть сборка, – production и staging (тестовое окружение). Возможные build variant будут выглядеть так:
gradle запуск с параметрами. Смотреть фото gradle запуск с параметрами. Смотреть картинку gradle запуск с параметрами. Картинка про gradle запуск с параметрами. Фото gradle запуск с параметрами

Очевидно, что сборка в маркет, которая будет смотреть на тестовое окружение, совершенно бессмысленна и не нужна ( stagingRelease ). И чтобы исключить ее, можно добавить variant filter:

#10 В некоторых модулях, завязанных на Android Framework, можно не использовать Android Gradle Plugin

#11 Как написать Gradle-плагин для CI на примере gitlab

Настройка CI — отдельная большая тема, которая потянет на целую увесистую статью. Но я решил немного коснуться её и рассказать, как при помощи написания Gradle-плагина настроить версионирование сборок. Возможно, этот совет поможет тем, кто только поднимает CI, но не знает, как лучше это сделать.

Задача — сделать так, чтобы в сборках на CI versionCode ставился автоматически и представлял из себя последовательные номера 1, 2, 3 и т.д. Я встречал в своей практике, когда в качестве versionCode брался CI job id или каким-то образом использовался timestamp. В таких случаях versionCode с каждой новой версией повышался и был уникальным, но семантически такие версии выглядели достаточно странно.

Основная идея проста — нужно хранить номер будущего релиза где-то во внешнем источнике, куда имеет доступ только сборка, выполняемая на CI. А после каждой успешной публикации нужно инкрементировать этот номер и перезаписывать (нам важно, чтобы сборка не просто успешно выполнилась, но и полученные артефакты распространились для тестировщиков). Стоит оговориться, что такое решение не позволит корректно делать одновременно несколько сборок. Всю эту логику достаточно просто оформить в Gradle-плагин. Как мы уже выяснили, плагины лучше писать, используя композитные сборки.

Расписал добавление такого плагина по шагам, чтобы показать, насколько это просто.

Шаг 1: в настройках проекта на gitlab создать переменные окружения

Нам понадобятся переменные VERSION_CODE_NEXT для хранения номера версии и токен для доступа к API gitlab:

gradle запуск с параметрами. Смотреть фото gradle запуск с параметрами. Смотреть картинку gradle запуск с параметрами. Картинка про gradle запуск с параметрами. Фото gradle запуск с параметрами

Шаг 2: создать композитную сборку

Шаг 3: написать плагин

Примерно так можно написать метод для обновления переменной на gitlab:

Далее пишем task, который при выполнении будет инкрементировать версию:

И напишем плагин, который добавит task в проект:

Шаг 4: подключить плагин

В build-скрипте проекта, из которого собирается apk, добавим следующие строки:

В заключение

Думаю, что у многих есть свои best practices по работе с Gradle, которыми вы бы могли поделиться с сообществом. Или что-то описанное в этой статье можно сделать лучше. Так что буду рад увидеть ваши советы в комментариях.

Что ещё посмотреть

Мне очень помогли доклады про работу с Gradle, которые делал Степан Гончаров в разные годы. Ссылки на них, если кому-то интересна эта тема:

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *