Как стать автором
Обновить

Комментарии 13

Иду тем же путем, только у меня все эти настройки и инжекции выполняются в Gradle-init плагине, который применяется для проектов в рамках некоторой производственной (корпоративной) среды. Этот плагин является артефактом и забирается из Maven-репозитория добавлением init-скрипта в gradle/wrapper или на локальной машине в ~/.gradle/init.d. Сам плагин — универсальный, в нем нет хардкодинга корпоративных конфигураций. Производственная конфигурация скачивается (кешируются локально) из некоторого места внутри производственной среды (LDAP, Git-репозиторий, HTTP), которое является SSoT. Адрес и способ получения прописываются в Gradle init-скрипте. Плюс плагин занимается необходимой кодогенерацией, т.к. проекты имеют единую структуру по чистой архитектуре. И большая часть — это библиотеки, фичи, с разделением на артефакты api/impl и соответствующим подключением зависимостей compileOnly/runtimeOnly.

Производственная конфигурация в простом варианте — json-файл (или любой другой формат), где описывается производственное окружение: адреса репозиториев, мета-информация, список проектов, version catalog, общая конфигурация Android, Kotlin и т.п. вещи, общие для проектов внутри среды.

Цель — разделить кодовую базу и конфигурации. Вынести конфигурации под отдельное управление специальной роли (тим-лид, devOps, инженер по сборке). Избавить линейного разработчика от необходимости самому все это настраивать из проекта в проект, занимаясь copy-paste. К тому же это небезопастно давать возможность разработчику управлять конфигурацией. Мультимодульный подход в разработке влечет появление большого количества микро-проектов (фичей, артефактов) и управлять этим хозяйством, особенно зависимостями между ними, без автоматизации становится адом.

А почему нельзя в каждом модуле прописать apply from с описанием базовой конфигурации?

Основная проблема с `apply from` с точки зрения Gradle в том, что с ним невозможно обеспечить типобезопасность. Kotlin DSL сильно полагается на кодогенерацию т.н. accessors - например, когда вы пишете `dependencies { implementation("foo:bar:1.0") }`, то implementation (имя конфигурации) - это на самом деле сгенерированная extension-функция. Для того чтобы узнать, какие accessors сгенерировать, Gradle применяет плагины из блока `plugins {}` (который парсится отдельно, поэтому накладывается столько ограничений на его синтаксис), смотрит на созданные плагинами конфигурации, таски и, ЕМНИП, extensions, генерирует accessors, а потом компилирует весь остальной билд-скрипт. Без этого приходится использовать костыли с поиском тасок по имени, extensions по типу и писать странное типа `dependencies { "implementation"(...) }`.

Поскольку `apply from` может быть вызван в произвольном месте билдскрипта, Gradle не может сгенерировать accessors для плагинов, примененных в нем, заранее. Это сильно бьет по удобству Kotlin DSL. С Groovy DSL проще, поскольку там сравнимого удобства и не было никогда.

Жду продолжение )

Как раз вчера вышло - welcome :)

К сожалению ещё на этапе синхронизации проекта я получаю ошибку

:plugins:base:test: Could not resolve com.android.tools.build:gradle:8.2.2.
Required by:
    project :plugins:base

И не могу продвинуться дальше. В чём может быть дело?

Судя по логу ошибки, в модуле :plugins:base есть sourceSet test (папка test), для которого не задан android-плагин... Удалите и попробуйте синхронизировать проект. Если проект выложен в публичный репозиторий, было бы проще разобраться

Не указаны репозитории для проекта plugins:base. Например, пропущен блок dependencyResolutionManagement в plugins/settings.gradle.kts.

А как быть если у меня мой кастомный плагин, подключённій в основной проект, содержит файл app-common.gradle.kts в котором прописаны общие элементы конфигурации (например, общие зависимости, версия SDK и т.д.) и который, в совю чоередь, подключается в подпроекты основного проекта как плагин. Что делать если в этом app-common.gradle.kts я хочу тоже использовать libs.versions.toml ?

Пока "радует" меня такой ошибкой:

Unresolved reference: libs

А как быть если у меня мой кастомный плагин, подключённый в основной проект, содержит файл app-common.gradle.kts в котором прописаны общие элементы конфигурации (например, общие зависимости, версия SDK и т.д.) и который, в свою очередь, подключается в подпроекты основного проекта как плагин. Что делать если в этом app-common.gradle.kts я хочу тоже использовать libs.versions.toml ?

Т.е. структура такая:



Пока "радует" меня такой ошибкой:

Unresolved reference: libs

Всё, простите, вопрос снимается, вторая часть статьи помогла решить его

Как понимаю, этот extension помог решить проблему? :)

Совершенно верно

Зарегистрируйтесь на Хабре, чтобы оставить комментарий