# 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')
        }

        artifactSlot('mainCompiled')
    }
}
```

## DESCRIPTION

`VariantsPlugin` задает доменную модель сборки и ее валидацию. Плагин не
регистрирует compile/copy/bundle задачи напрямую.

### layers

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

### variants

Именованные варианты исполнения/пакетирования (`browser`, `node`, и т.д.).
Вариант агрегирует роли, атрибуты и artifact slots.

### roles

Роль описывает набор слоев в пределах варианта (`main`, `test`, `tools`).
Одна роль может ссылаться на несколько слоев.

### attributes

Typed-атрибуты (`Attribute<T> -> Provider<T>`) для передачи параметров в
адаптеры и публикацию артефактов.

### artifact slots

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

## VALIDATION

В `finalizeModel()` выполняется проверка:

- роль не может ссылаться на неизвестный layer;
- пустые имена layer запрещены;
- имена ролей в варианте должны быть уникальны;
- имена artifact slots в варианте должны быть уникальны.

## LIFECYCLE

- `VariantsPlugin` вызывает `variants.finalizeModel()` на `afterEvaluate`.
- после `finalizeModel()` мутации модели запрещены.
- `whenFinalized(...)` replayable.

## API

### BuildVariantsExtension

- `layer(...)` — объявление или конфигурация `BuildLayer`.
- `variant(...)` — объявление или конфигурация `BuildVariant`.
- `layers { layer(...) }`, `variants { ... }` — grouped DSL без публикации container API наружу.
- `all(...)` — callback для всех вариантов.
- `findLayer(name)`, `requireLayer(name)`, `getAllLayers()` — доступ к registry слоев.
- `getAll()`, `find(name)`, `require(name)` — доступ к вариантам.
- `validate()` — явный запуск валидации.
- `finalizeModel()` — валидация + финализация модели.
- `whenFinalized(...)` — callback по завершенной модели (replayable).

### BuildVariant

- `attributes { ... }` — атрибуты варианта (+ sugar `string/bool/integer`).
- `role(...)`, `roles { ... }` — роли варианта.
- `artifactSlot(...)`, `artifactSlots { ... }` — артефактные слоты.

## KEY CLASSES

- `VariantsPlugin` — точка входа плагина.
- `BuildVariantsExtension` — root extension и lifecycle.
- `BuildVariant` — агрегатная модель варианта.
- `BuildLayer` — canonical identity-model слоя.
- `BuildRole` — модель роли.
- `BuildArtifactSlot` — модель артефактного слота.
- `VariantAttributes` — typed wrapper для variant attributes.

## NOTES

- Модель `variants` intentionally agnostic к toolchain.
- Layer registry хранится как явная identity-map, а не как публичный `NamedDomainObjectContainer`.
- Интеграция с задачами выполняется через `variantSources` и адаптеры.
