Variant Artifacts Plugin
NAME
VariantsArtifactsPlugin и extension variantArtifacts.
SYNOPSIS
import org.gradle.api.attributes.Attribute plugins { id 'org.implab.gradle-variants-artifacts' } def variantAttr = Attribute.of('test.variant', String) def slotAttr = Attribute.of('test.slot', String) variants { layer('main') variant('browser') { role('main') { layers('main') } } } variantSources { bind('main') { configureSourceSet { declareOutputs('types', 'js', 'resources') } } } variantArtifacts { variant('browser') { primarySlot('typesPackage') { fromVariant { output('types') } } slot('js') { fromVariant { output('js') } } slot('resources') { fromVariant { output('resources') } } } whenOutgoingVariant { publication -> publication.configureConfiguration { attributes.attribute(variantAttr, publication.variantName()) } publication.primarySlot().configureArtifactAttributes { attribute(slotAttr, publication.primarySlot().slotName()) } publication.requireSlot('js').configureArtifactAttributes { attribute(slotAttr, 'js') } publication.requireSlot('resources').configureArtifactAttributes { attribute(slotAttr, 'resources') } } }
DESCRIPTION
VariantsArtifactsPlugin применяет VariantsSourcesPlugin, затем строит
outgoing publication model поверх variantSources.
publication model
Для каждого variantArtifacts.variant('<name>') публикуется один outgoing
build variant:
- primary configuration
<variant>Elements; - primary artifact slot на самой configuration;
- secondary variants внутри
configuration.outgoing.variantsдля остальных slots.
Пример:
browserElements- primary slot:
typesPackage - secondary variants:
js,resources
Это разделяет:
- graph selection build variant-а;
- artifact selection внутри уже выбранного variant-а.
slot bindings
slot('<name>') описывает, какие outputs из variantSources войдут в artifact
representation этого slot-а.
Binding rules:
fromVariant { output(...) }fromRole('<role>') { output(...) }fromLayer('<layer>') { output(...) }
Каждый slot materialize-ится в отдельный ArtifactAssembly:
- task:
process<Variant><Slot>; - output dir:
build/variant-artifacts/<variant>/<slot>.
primary slot
Primary slot задает artifact, который публикуется как основной artifact
configuration <variant>Elements.
Формы DSL:
variant('browser') { primarySlot('typesPackage') slot('typesPackage') { fromVariant { output('types') } } }
или sugar:
variant('browser') { primarySlot('typesPackage') { fromVariant { output('types') } } }
Правила:
- если slot один, он считается primary неявно;
- если slots несколько,
primarySlot(...)обязателен; primarySlotдолжен ссылаться на существующий slot.
LIFECYCLE
VariantsArtifactsPluginждетvariants.whenFinalized(...);- после этого валидирует
variantArtifacts; - регистрирует
ArtifactAssemblyпо каждому slot; - materialize-ит outgoing publications;
- вызывает
whenOutgoingVariant(...); - callbacks replayable.
После finalize мутации variantArtifacts запрещены.
EVENTS
whenOutgoingVariant
Replayable callback на готовую outgoing publication variant-а.
Подходит для:
- настройки общих attributes build variant-а один раз;
- настройки per-slot artifact attributes;
- доконфигурации
ArtifactAssembly.
PAYLOAD TYPES
OutgoingVariantPublication
Содержит:
variantName();topologyVariant();variantArtifact();configuration()— primary<variant>Elements;primarySlot();slots()— все slot publications;secondarySlots();findSlot(name),requireSlot(name).
Sugar:
configureConfiguration(Action|Closure).
OutgoingArtifactSlotPublication
Содержит:
slotName();primary();slot()— модельVariantArtifactSlot;assembly().
Sugar:
configureAssembly(Action|Closure);configureArtifactAttributes(Action|Closure).
configureArtifactAttributes(...) пишет attributes:
- в
Configuration.attributesдля primary slot; - в
ConfigurationVariant.attributesдля secondary slot.
CONSUMER SIDE
primary resolution
Обычное inter-project resolution выбирает primary artifact <variant>Elements.
Пример:
configurations { compileView { canBeResolved = true canBeConsumed = false canBeDeclared = true attributes { attribute(variantAttr, 'browser') attribute(slotAttr, 'typesPackage') } } } dependencies { compileView project(':producer') }
artifact selection for secondary slots
Secondary artifacts выбираются через artifactView.
def jsFiles = configurations.compileView.incoming.artifactView { attributes { attribute(slotAttr, 'js') } }.files
Здесь graph variant уже выбран, а artifactView выбирает нужный secondary
artifact representation.
VALIDATION
Проверяется:
- variant существует в topology model;
- slot bindings не ссылаются на неизвестные role/layer;
- при нескольких slots указан
primarySlot; primarySlotссылается на существующий slot.
API
VariantArtifactsExtension
variant(String)— получить/создать variant artifact model;variant(String, Action|Closure)— сконфигурировать variant artifact;getVariants()— контейнер variant artifacts;findVariant(name),requireVariant(name);whenOutgoingVariant(...).
VariantArtifact
slot(String)— получить/создать slot;slot(String, Action|Closure)— сконфигурировать slot;primarySlot(String)— назначить primary slot;primarySlot(String, Action|Closure)— sugar: configure slot + mark as primary;getSlots();findSlot(name),requireSlot(name);findPrimarySlotName(),requirePrimarySlotName();findPrimarySlot(),requirePrimarySlot().
VariantArtifactSlot
fromVariant(...);fromRole(String, ...);fromLayer(String, ...).
OutputSelectionSpec
output(name);output(name, extra...).
KEY CLASSES
VariantsArtifactsPlugin— plugin adapter и materialization outgoing variants.VariantArtifactsExtension— root DSL и lifecycle.VariantArtifact— outgoing build variant model.VariantArtifactSlot— artifact representation slot.OutgoingVariantPublication— payload variant-level publication callback.OutgoingArtifactSlotPublication— payload per-slot publication callback.ArtifactAssembly— assembled files for a slot.
NOTES
commonне навязывает доменную логику выбора primary slot.commonне фиксирует значенияusage,libraryelementsи прочих slot-specific attributes.commonне смешивает эту модель с отдельными publish осями вроде package metadata.- Closure callbacks используют delegate-first; для вложенных closure удобнее
явный параметр (
publication -> ...,slotPublication -> ...).
