# Variants Plugin ## NAME `VariantsPlugin` и extension `variants`. ## SYNOPSIS ```groovy plugins { id 'org.implab.gradle-variants' } variants { layer('mainBase') layer('mainAmd') variant('browser') { attributes { string('jsRuntime', 'browser') string('jsModule', 'amd') } role('main') { layers('mainBase', 'mainAmd') } link('mainBase', 'mainAmd', 'ts:api') artifactSlot('mainCompiled') } } ``` ## DESCRIPTION `VariantsPlugin` задает доменную модель сборки и ее валидацию. Плагин не регистрирует compile/copy/bundle задачи напрямую. ### layers Глобальные логические слои. Служат единым словарем имен, на которые затем ссылаются роли и связи. ### variants Именованные варианты исполнения/пакетирования (`browser`, `node`, и т.д.). Вариант агрегирует роли, связи, атрибуты и artifact slots. ### roles Роль описывает набор слоев в пределах варианта (`main`, `test`, `tools`). Одна роль может ссылаться на несколько слоев. ### links `link(from, to, kind)` — ориентированная связь между слоями внутри варианта. `kind` задает независимый тип графа (например `ts:api`, `bundle:runtime`). Это позволяет вести несколько параллельных графов зависимостей над теми же слоями. Практические сценарии использования `link` в адаптерах: - расчет topological order по выбранному `kind`; - wiring task inputs/outputs между слоями; - проверка допустимости дополнительных pipeline-зависимостей. ### attributes Typed-атрибуты (`Attribute -> Provider`) для передачи параметров в адаптеры и публикацию артефактов. ### artifact slots Именованные слоты ожидаемых артефактов варианта. Используются как контракт между моделью варианта и плагинами, создающими/публикующими результаты. ## VALIDATION В `finalizeModel()` выполняется проверка: - роль не может ссылаться на неизвестный layer; - пустые имена layer запрещены; - у link обязательны `from`, `to`, `kind`; - `from`/`to` должны входить в слойную область варианта; - tuple `(from, to, kind)` должен быть уникален; - циклы в графе одного `kind` запрещены. ## LIFECYCLE - `VariantsPlugin` вызывает `variants.finalizeModel()` на `afterEvaluate`. - `whenFinalized(...)` replayable. ## API ### BuildVariantsExtension - `layer(...)` — объявление или конфигурация `BuildLayer`. - `variant(...)` — объявление или конфигурация `BuildVariant`. - `layers { ... }`, `variants { ... }` — контейнерный DSL. - `all(...)` — callback для всех вариантов. - `getAll()`, `getByName(name)` — доступ к вариантам. - `validate()` — явный запуск валидации. - `finalizeModel()` — валидация + финализация модели. - `whenFinalized(...)` — callback по завершенной модели (replayable). ### BuildVariant - `attributes { ... }` — атрибуты варианта (+ sugar `string/bool/integer`). - `role(...)`, `roles { ... }` — роли варианта. - `link(...)`, `links { ... }` — связи слоев внутри варианта. - `artifactSlot(...)`, `artifactSlots { ... }` — артефактные слоты. ## KEY CLASSES - `VariantsPlugin` — точка входа плагина. - `BuildVariantsExtension` — root extension и lifecycle. - `BuildVariant` — агрегатная модель варианта. - `BuildLayer` — модель слоя. - `BuildRole` — модель роли. - `BuildLink` — модель направленной связи. - `BuildArtifactSlot` — модель артефактного слота. - `VariantAttributes` — typed wrapper для variant attributes. ## NOTES - Модель `variants` intentionally agnostic к toolchain. - Интеграция с задачами выполняется через `variantSources` и адаптеры.