##// END OF EJS Templates
Set the project version to 0.1.0, add publication descriptions/license metadata, and keep module-level docs as compatibility pointers to the root documentation.
cin -
r60:e376d0cab00e default
parent child
Show More
@@ -0,0 +1,24
1 BSD 2-Clause License
2
3 Copyright (c) 2026 gradle-common contributors.
4
5 Redistribution and use in source and binary forms, with or without modification,
6 are permitted provided that the following conditions are met:
7
8 1. Redistributions of source code must retain the above copyright notice, this
9 list of conditions and the following disclaimer.
10
11 2. Redistributions in binary form must reproduce the above copyright notice,
12 this list of conditions and the following disclaimer in the documentation
13 and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
19 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
22 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,99
1 # Local Ivy Publishing
2
3 This project currently publishes only to a local Ivy repository. Maven Central,
4 signing, and Gradle Plugin Portal publication are intentionally out of scope for
5 the current preparation step.
6
7 Published Ivy descriptors include the BSD-2-Clause license metadata.
8
9 ## Repository
10
11 The configured Ivy repository is:
12
13 ```text
14 ${user.home}/ivy-repo
15 ```
16
17 This is defined in:
18
19 - `common/build.gradle`
20 - `variants/build.gradle`
21
22 ## Verify Before Publishing
23
24 Run a full clean verification:
25
26 ```bash
27 ./gradlew clean check javadoc jar sourcesJar javadocJar --rerun-tasks
28 ```
29
30 Optional configuration-cache smoke check:
31
32 ```bash
33 ./gradlew check --configuration-cache
34 ```
35
36 ## Publish
37
38 Publish all modules:
39
40 ```bash
41 ./gradlew publish
42 ```
43
44 Publish modules explicitly:
45
46 ```bash
47 ./gradlew :common:publishIvyPublicationToIvyRepository \
48 :variants:publishIvyPublicationToIvyRepository
49 ```
50
51 Safe smoke publish into a temporary repository:
52
53 ```bash
54 ./gradlew -Duser.home=/tmp/gradle-common-ivy-smoke \
55 :common:publishIvyPublicationToIvyRepository \
56 :variants:publishIvyPublicationToIvyRepository \
57 --rerun-tasks
58 ```
59
60 ## Consume Locally
61
62 Use `buildscript` classpath for now:
63
64 ```groovy
65 buildscript {
66 repositories {
67 ivy {
68 url "${System.properties['user.home']}/ivy-repo"
69 }
70 mavenCentral()
71 }
72 dependencies {
73 classpath 'org.implab.gradle:variants:0.1.0'
74 }
75 }
76
77 apply plugin: 'org.implab.gradle-variants'
78 apply plugin: 'org.implab.gradle-variants-sources'
79 ```
80
81 The `plugins {}` DSL needs generated plugin marker artifacts and is not part of
82 the current local Ivy contract.
83
84 ## Published Artifacts
85
86 Each module publishes:
87
88 - `<module>-<version>.jar`
89 - `<module>-<version>-sources.jar`
90 - `<module>-<version>-javadoc.jar`
91 - `ivy.xml`
92 - Gradle module metadata
93
94 ## Current Coordinates
95
96 ```text
97 org.implab.gradle:common:0.1.0
98 org.implab.gradle:variants:0.1.0
99 ```
@@ -0,0 +1,296
1 # gradle-common
2
3 Java 21 multi-project build with shared Gradle utilities and experimental
4 variant-oriented Gradle plugins.
5
6 The repository currently publishes to a local Ivy repository only. Maven Central
7 and Gradle Plugin Portal publication are intentionally not configured yet.
8
9 ## Modules
10
11 - `common` - shared Gradle utilities, JSON helpers, shell execution helpers, and
12 small core value/util classes.
13 - `variants` - Gradle plugins for variant topology, source-set materialization,
14 and outgoing artifact slots.
15
16 ## Requirements
17
18 - JDK 21.
19 - Gradle Wrapper from this repository, currently Gradle 8.10.2.
20
21 The produced bytecode targets Java 21.
22
23 ## License
24
25 This project is licensed under the BSD 2-Clause "Simplified" License
26 (`BSD-2-Clause`). See [LICENSE](LICENSE).
27
28 ## Local Build
29
30 ```bash
31 ./gradlew clean check javadoc jar sourcesJar javadocJar --rerun-tasks
32 ```
33
34 Configuration cache smoke check:
35
36 ```bash
37 ./gradlew check --configuration-cache
38 ```
39
40 ## Local Ivy Publication
41
42 The current publication target is:
43
44 ```text
45 ${user.home}/ivy-repo
46 ```
47
48 Publish both modules locally:
49
50 ```bash
51 ./gradlew :common:publishIvyPublicationToIvyRepository \
52 :variants:publishIvyPublicationToIvyRepository
53 ```
54
55 or:
56
57 ```bash
58 ./gradlew publish
59 ```
60
61 The publication includes:
62
63 - main jar
64 - sources jar
65 - javadoc jar
66 - Ivy descriptor
67 - Gradle module metadata
68
69 ## Local Consumption
70
71 Current plugin ids are packaged as classic Gradle plugin marker resources inside
72 the `variants` jar:
73
74 - `org.implab.gradle-variants`
75 - `org.implab.gradle-sources`
76 - `org.implab.gradle-variants-sources`
77 - `org.implab.gradle-variants-artifacts`
78
79 Until Gradle Plugin Portal marker artifacts are configured, consume the plugin
80 through `buildscript` classpath:
81
82 ```groovy
83 buildscript {
84 repositories {
85 ivy {
86 url "${System.properties['user.home']}/ivy-repo"
87 }
88 mavenCentral()
89 }
90 dependencies {
91 classpath 'org.implab.gradle:variants:0.1.0'
92 }
93 }
94
95 apply plugin: 'org.implab.gradle-variants'
96 apply plugin: 'org.implab.gradle-variants-sources'
97 ```
98
99 The `plugins { id(...) version(...) }` DSL is not part of the current local Ivy
100 contract.
101
102 ## Variants DSL
103
104 `variants` defines the finalized build topology. It does not create compile
105 tasks, source directories, or outgoing publications by itself.
106
107 ```groovy
108 apply plugin: 'org.implab.gradle-variants'
109
110 variants.layers.create('main')
111 variants.layers.create('test')
112 variants.roles.create('main')
113 variants.roles.create('test')
114
115 variants.variant('browser') {
116 role('main') {
117 layers('main')
118 }
119 role('test') {
120 layers('main', 'test')
121 }
122 }
123
124 variants.whenFinalized { view ->
125 println view.entries.collect {
126 "${it.variant().name}:${it.role().name}:${it.layer().name}"
127 }.sort()
128 }
129 ```
130
131 The finalized model exposes cheap identity objects: `Variant`, `Role`, `Layer`,
132 and the normalized relation `(variant, role, layer)`.
133
134 ## Sources DSL
135
136 `sources` creates standalone `GenericSourceSet` objects. This is useful for
137 fallback workflows that do not need variant topology.
138
139 ```groovy
140 apply plugin: 'org.implab.gradle-sources'
141
142 sources.create('main') {
143 declareOutputs('js')
144 registerOutput('js', layout.projectDirectory.file('inputs/main.js'))
145
146 sets.create('ts') {
147 srcDir 'src/main/ts'
148 }
149 }
150 ```
151
152 `SourcesPlugin` applies layout conventions:
153
154 - `sourceSetDir = src/<sourceSet>`
155 - `outputsDir = build/out/<sourceSet>`
156
157 The base `GenericSourceSet` model itself is convention-free.
158
159 ## Variant Sources DSL
160
161 `variantSources` derives compile units from finalized `variants`.
162
163 A compile unit is:
164
165 ```text
166 (variant, layer)
167 ```
168
169 Selectors configure materialized compile-unit source sets:
170
171 ```groovy
172 apply plugin: 'org.implab.gradle-variants-sources'
173
174 variants.layers.create('main')
175 variants.roles.create('main')
176 variants.variant('browser') {
177 role('main') {
178 layers('main')
179 }
180 }
181
182 variantSources {
183 layer('main') {
184 sourceSet {
185 declareOutputs('js')
186 registerOutput('js', layout.projectDirectory.file('inputs/browser.js'))
187 }
188 }
189
190 configureEach {
191 println "sourceSet=${sourceSet.name}, variant=${variant.name}, layer=${layer.name}"
192 }
193 }
194 ```
195
196 Selector order for future materialization is:
197
198 ```text
199 configureEach -> variant -> layer -> unit
200 ```
201
202 Late selector registration is controlled by:
203
204 ```groovy
205 variantSources {
206 lateConfigurationPolicy {
207 failOnLateConfiguration()
208 }
209 }
210 ```
211
212 Compile-unit source set names are generated by default as:
213
214 ```text
215 <variant> + capitalize(<layer>)
216 ```
217
218 Name collisions fail by default and may be resolved deterministically:
219
220 ```groovy
221 variantSources {
222 namingPolicy {
223 resolveNameCollision()
224 }
225 }
226 ```
227
228 ## Variant Artifacts DSL
229
230 `variantArtifacts` is an experimental outgoing artifact layer over `variants`
231 and `variantSources`.
232
233 The current model maps:
234
235 - `Variant` to a variant-level consumable outgoing configuration.
236 - `Slot` to a Gradle outgoing artifact variant inside that configuration.
237 - `primarySlot` to the primary artifact set of the outgoing configuration.
238
239 ```groovy
240 apply plugin: 'org.implab.gradle-variants-artifacts'
241
242 variants.layers.create('main')
243 variants.roles.create('main')
244 variants.variant('browser') {
245 role('main') {
246 layers('main')
247 }
248 }
249
250 variantSources.layer('main') {
251 sourceSet {
252 declareOutputs('types', 'js')
253 registerOutput('types', layout.projectDirectory.file('inputs/index.d.ts'))
254 registerOutput('js', layout.projectDirectory.file('inputs/index.js'))
255 }
256 }
257
258 variantArtifacts {
259 variant('browser') {
260 primarySlot('typesPackage') {
261 fromVariant {
262 output('types')
263 }
264 }
265 slot('js') {
266 fromVariant {
267 output('js')
268 }
269 }
270 }
271
272 whenOutgoingConfiguration { publication ->
273 publication.configuration {
274 description = "Outgoing contract for ${publication.variant.name}"
275 }
276 }
277
278 whenOutgoingSlot { publication ->
279 println "slot=${publication.artifactSlot.slot.name}, primary=${publication.primary}"
280 }
281 }
282 ```
283
284 The artifact API is still considered pre-1.0 and may change.
285
286 ## Publication Status
287
288 Current status:
289
290 - local Ivy publication only
291 - no Maven Central publication metadata
292 - no signing
293 - no Gradle Plugin Portal marker artifacts
294 - BSD-2-Clause license committed
295
296 Before external publication, see [RELEASE_CHECKLIST.md](RELEASE_CHECKLIST.md).
@@ -0,0 +1,63
1 # Release Checklist
2
3 This checklist tracks what should be true before publishing outside the local
4 Ivy repository.
5
6 ## Current Scope
7
8 For now the project is prepared for local Ivy publication only.
9
10 ## Required Before External Publication
11
12 - Add Maven publication (`maven-publish`) if publishing to Maven repositories.
13 - Add signing for Maven Central or any repository that requires signed
14 artifacts.
15 - Add complete POM metadata: project name, description, URL, license,
16 developers, and SCM coordinates.
17 - Keep Java 21 as the public baseline and document it for consumers.
18 - Decide whether `variants` artifact APIs are published as experimental or
19 split into a later module.
20 - Add Gradle plugin marker artifact generation if `plugins { id(...) version(...) }`
21 must work.
22 - Add a published-consumption smoke test that resolves artifacts from a
23 temporary local repository.
24
25 ## Local Ivy Release Steps
26
27 1. Ensure the Mercurial working tree is clean.
28 2. Run:
29
30 ```bash
31 ./gradlew clean check javadoc jar sourcesJar javadocJar --rerun-tasks
32 ```
33
34 3. Optionally run:
35
36 ```bash
37 ./gradlew check --configuration-cache
38 ```
39
40 4. Publish locally:
41
42 ```bash
43 ./gradlew publish
44 ```
45
46 5. Optionally smoke-publish into `/tmp` first:
47
48 ```bash
49 ./gradlew -Duser.home=/tmp/gradle-common-ivy-smoke \
50 :common:publishIvyPublicationToIvyRepository \
51 :variants:publishIvyPublicationToIvyRepository \
52 --rerun-tasks
53 ```
54
55 6. Verify `${user.home}/ivy-repo/org.implab.gradle` contains `common` and
56 `variants` for the expected version.
57
58 ## API Status
59
60 - `common` is intended to be a shared utility library.
61 - `variants` core and source APIs are pre-1.0 and should be treated as
62 evolving.
63 - `variantArtifacts` is experimental and may change more aggressively.
@@ -1,6 +1,7
1 syntax: glob
1 syntax: glob
2 .gradle/
2 .gradle/
3 .codex/
3 .codex/
4 build/
4 common/build/
5 common/build/
5 common/bin/
6 common/bin/
6 variants/build/
7 variants/build/
@@ -3,6 +3,8 plugins {
3 id "ivy-publish"
3 id "ivy-publish"
4 }
4 }
5
5
6 description = "Shared Gradle build utilities used by Implab plugins"
7
6 java {
8 java {
7 withJavadocJar()
9 withJavadocJar()
8 withSourcesJar()
10 withSourcesJar()
@@ -46,6 +48,10 publishing {
46 descriptor.description {
48 descriptor.description {
47 text = providers.provider({ description })
49 text = providers.provider({ description })
48 }
50 }
51 descriptor.license {
52 name = "BSD-2-Clause"
53 url = "https://spdx.org/licenses/BSD-2-Clause.html"
49 }
54 }
50 }
55 }
51 }
56 }
57 }
@@ -1,134 +1,18
1 # Gradle Common Sources Model
1 # Gradle Common
2
3 ## NAME
4
5 `gradle-common/common` — набор плагинов для моделирования вариантов сборки,
6 регистрации source sets и интеграции этой модели с toolchain-адаптерами.
7
8 ## SYNOPSIS
9
10 ```groovy
11 plugins {
12 id 'org.implab.gradle-variants-sources'
13 }
14
15 variants {
16 layer('mainBase')
17 layer('mainAmd')
18
19 variant('browser') {
20 role('main') { layers('mainBase', 'mainAmd') }
21 }
22 }
23
24 variantSources {
25 bind('mainBase') {
26 configureSourceSet {
27 declareOutputs('compiled')
28 }
29 }
30
31 bind('mainAmd').sourceSetNamePattern = '{variant}{layerCap}'
32
2
33 whenRegistered { sourceSetName() }
3 `common` is the shared utility module used by the Gradle plugins in this
34
4 repository.
35 whenBound { ctx ->
36 ctx.configureSourceSet {
37 declareOutputs('typings')
38 }
39 }
40 }
41 ```
42
43 ## DESCRIPTION
44
45 Модуль состоит из трех логических частей:
46
5
47 - `variants` — декларативная доменная модель сборки;
6 It contains:
48 - `sources` — модель физически регистрируемых source sets;
49 - `variantSources` — адаптер, который связывает первые две модели.
50
51 Ниже раскрытие каждой части.
52
53 ### variants
54
55 `variants` задает структуру пространства сборки: какие есть слои, какие роли
56 используют эти слои в каждом варианте, какие есть атрибуты и artifact slots.
57 Модель не создает задачи и не привязана к TS/JS.
58
59 Практический смысл:
60
61 - формализовать архитектуру сборки;
62 - дать адаптерам единый источник правды.
63
64 ### sources
65
7
66 `sources` описывает независимые source sets (`GenericSourceSet`) с именованными
8 - core Gradle helper utilities
67 outputs. Это уже "физический" уровень, к которому удобно привязывать задачи,
9 - small language/value helpers
68 артефакты и task inputs/outputs.
10 - shell execution helpers
69
11 - JSON DSL and JSON-writing task support
70 Практический смысл:
71
72 - создать единый контракт по входам/выходам;
73 - регистрировать результаты задач как outputs source set;
74 - минимизировать ручные `dependsOn` за счет модели outputs.
75
76 ### variantSources
77
78 `variantSources` регистрирует source sets на основе `variants`, применяет
79 конфигурацию layer-bindings и отдает события (`whenRegistered`, `whenBound`) для
80 адаптеров других плагинов.
81
82 Практический смысл:
83
84 - переводить логическую модель `variants` в executable-модель `sources`;
85 - навешивать политики toolchain на зарегистрированные source sets;
86 - синхронизировать плагины через replayable callback-контракт.
87
88 ## DOMAIN MODEL
89
90 - `BuildLayer` — canonical identity-model объявленного слоя.
91 - `BuildVariant` — агрегат ролей, атрибутов, артефактных слотов.
92 - `BuildRole` — роль внутри варианта, содержит ссылки на declared layer names.
93 - `GenericSourceSet` — зарегистрированный набор исходников и outputs.
94 - `LayerBindingSpec` — публичный DSL-contract adapter policy/callbacks для слоя.
95 - `SourceSetRegistration` — payload события регистрации source set.
96 - `SourceSetUsageBinding` — payload события usage-binding.
97
98 ## EVENT CONTRACT
99
12
100 - `whenRegistered`:
13 It no longer contains the variant/source/artifact plugin model. Those plugins
101 - событие нового уникального source set name;
14 live in the `variants` module.
102 - replayable.
103 - `whenBound`:
104 - событие каждой usage-связки `variant/role/layer`;
105 - replayable.
106
107 Closure callbacks работают в delegate-first режиме (`@DelegatesTo`). Для
108 вложенных closure рекомендуется явный параметр (`ctx -> ...`).
109
110 ## KEY CLASSES
111
15
112 - `SourcesPlugin` — регистрирует extension `sources`.
16 See the root [README.md](../README.md) and [PUBLISHING.md](../PUBLISHING.md) for
113 - `GenericSourceSet` — модель источников/outputs для конкретного имени.
17 current build and local Ivy publication instructions.
114 - `VariantsPlugin` — регистрирует extension `variants` и lifecycle finalize.
115 - `BuildVariantsExtension` — корневой API модели вариантов.
116 - `BuildVariant` — API ролей, attributes и artifact slots варианта.
117 - `VariantsSourcesPlugin` — применяет `variants` + `sources` и запускает адаптер.
118 - `VariantSourcesExtension` — API bind/events registration.
119 - `LayerBindingSpec` — слой-конкретный DSL для policy/configuration source set.
120 - `SourceSetRegistration` — payload `whenRegistered(...)`.
121 - `SourceSetUsageBinding` — payload `whenBound(...)`.
122
18
123 ## NOTES
124
125 - Marker ids:
126 - `org.implab.gradle-variants`
127 - `org.implab.gradle-variants-sources`
128 - `SourcesPlugin` пока class-only (без marker id).
129
130 ## SEE ALSO
131
132 - `sources-plugin.md`
133 - `variants-plugin.md`
134 - `variant-sources-plugin.md`
@@ -1,83 +1,7
1 # Sources Plugin
1 # Moved: Sources Plugin
2
3 ## NAME
4
5 `SourcesPlugin` и extension `sources`.
6
7 ## SYNOPSIS
8
9 ```groovy
10 // Обычно подключается транзитивно через org.implab.gradle-variants-sources
11
12 sources {
13 register('main') {
14 declareOutputs('compiled', 'typings')
15
16 sets {
17 ts { srcDir 'src/main/ts' }
18 js { srcDir 'src/main/js' }
19 }
20 }
21 }
22 ```
23
24 ## DESCRIPTION
25
26 `SourcesPlugin` регистрирует extension `sources` типа
27 `NamedDomainObjectContainer<GenericSourceSet>`.
28
29 `GenericSourceSet` — это автономный source bundle с четким контрактом outputs.
30
31 ### sourceSetDir
32
33 Базовый каталог набора. Конвенция по умолчанию: `src/<name>`.
34
35 ### outputsDir
36
37 Базовый каталог результатов набора. Конвенция по умолчанию: `build/<name>`.
38
39 ### sets
40
2
41 Контейнер `SourceDirectorySet` внутри `GenericSourceSet`. Используется для
3 The `SourcesPlugin` implementation is now part of the `variants` module, not
42 логического разделения подпапок (например `ts`, `js`, `typings`).
4 the `common` module.
43
44 ### outputs contract
45
46 Outputs именованные и должны быть объявлены заранее:
47
48 - `declareOutputs(...)` — декларация доступных output keys;
49 - `output(name)` — доступ к `ConfigurableFileCollection` для output key;
50 - `registerOutput(...)` — регистрация output из файлов или task provider.
51
52 Такой контракт упрощает wiring задач через inputs/outputs без ручного
53 `dependsOn`.
54
55 ## API
56
57 ### SourcesPlugin
58
59 - `apply(Project)` — добавляет extension `sources` в проект.
60 - `getSourcesExtension(Project)` — возвращает контейнер `GenericSourceSet`.
61
5
62 ### GenericSourceSet
6 Current documentation is maintained in the root [README.md](../README.md).
63
7
64 - `getSourceSetDir()` — root directory источников набора.
65 - `getOutputsDir()` — root directory результатов набора.
66 - `getSets()` — контейнер поднаборов `SourceDirectorySet`.
67 - `declareOutputs(...)` — объявляет разрешенные output names.
68 - `output(name)` — возвращает `FileCollection` для конкретного output.
69 - `registerOutput(name, files...)` — добавляет файлы в output.
70 - `registerOutput(name, task, mapper)` — связывает output с task provider.
71 - `getAllOutputs()` — агрегированный `FileCollection` всех outputs.
72 - `getAllSourceDirectories()` — агрегированный `FileCollection` всех source dirs.
73
74 ## KEY CLASSES
75
76 - `SourcesPlugin` — регистрация extension `sources`.
77 - `GenericSourceSet` — модель источников и outputs.
78
79 ## NOTES
80
81 - Обращение к `output(name)` без предварительного `declareOutputs(name)`
82 приводит к ошибке валидации.
83 - Плагин `sources` сейчас без marker id.
@@ -1,354 +1,8
1 # Variant Artifacts Plugin
1 # Moved: Variant Artifacts Plugin
2
3 ## NAME
4
5 `VariantsArtifactsPlugin` и extension `variantArtifacts`.
6
7 ## SYNOPSIS
8
9 ```groovy
10 import org.gradle.api.attributes.Attribute
11
12 plugins {
13 id 'org.implab.gradle-variants-artifacts'
14 }
15
16 def variantAttr = Attribute.of('test.variant', String)
17 def slotAttr = Attribute.of('test.slot', String)
18
19 variants {
20 layer('main')
21
22 variant('browser') {
23 role('main') { layers('main') }
24 }
25 }
26
27 variantSources {
28 bind('main') {
29 configureSourceSet {
30 declareOutputs('types', 'js', 'resources')
31 }
32 }
33 }
34
35 variantArtifacts {
36 variant('browser') {
37 primarySlot('typesPackage') {
38 fromVariant {
39 output('types')
40 }
41 }
42
43 slot('js') {
44 fromVariant {
45 output('js')
46 }
47 }
48
49 slot('resources') {
50 fromVariant {
51 output('resources')
52 }
53 }
54 }
55
56 whenOutgoingVariant { publication ->
57 publication.configureConfiguration {
58 attributes.attribute(variantAttr, publication.variantName())
59 }
60
61 publication.primarySlot().configureArtifactAttributes {
62 attribute(slotAttr, publication.primarySlot().slotName())
63 }
64
65 publication.requireSlot('js').configureArtifactAttributes {
66 attribute(slotAttr, 'js')
67 }
68
69 publication.requireSlot('resources').configureArtifactAttributes {
70 attribute(slotAttr, 'resources')
71 }
72 }
73 }
74 ```
75
76 ## DESCRIPTION
77
78 `VariantsArtifactsPlugin` применяет `VariantsSourcesPlugin`, затем строит
79 outgoing publication model поверх `variantSources`.
80
81 ### publication model
82
83 Для каждого `variantArtifacts.variant('<name>')` публикуется один outgoing
84 build variant:
85
86 - primary configuration `<variant>Elements`;
87 - primary artifact slot на самой configuration;
88 - secondary variants внутри `configuration.outgoing.variants` для остальных slots.
89
90 Пример:
91
92 - `browserElements`
93 - primary slot: `typesPackage`
94 - secondary variants: `js`, `resources`
95
96 Это разделяет:
97
98 - graph selection build variant-а;
99 - artifact selection внутри уже выбранного variant-а.
100
101 ### slot contributions и DSL
102
103 `slot('<name>')` описывает artifact representation не как один файл или одну
104 задачу, а как набор contributions, которые потом materialize-ятся в отдельный
105 `ArtifactAssembly`.
106
107 Текущий DSL поддерживает два вида contributions:
108
109 - topology-aware:
110 - `fromVariant { output(...) }`
111 - `fromRole('<role>') { output(...) }`
112 - `fromLayer('<layer>') { output(...) }`
113 - direct:
114 - `from(someFileOrProviderOrTaskOutput)`
115
116 Смысл DSL по слоям:
117
118 - `fromVariant/fromRole/fromLayer` выбирают область topology model, в которой
119 contribution активен;
120 - `output(...)` выбирает named output соответствующего `GenericSourceSet`;
121 - `from(Object)` добавляет direct contribution, не зависящий от
122 `variantSources` bindings;
123 - итоговый contribution при materialization:
124 - проверяет, подходит ли текущий `SourceSetUsageBinding`;
125 - выдает object для `files.from(...)`;
126 - при необходимости выдает `BindingKey`, если такой contribution должен
127 схлопываться по logical identity.
128
129 Связь slot-а с остальной моделью:
130
131 - `variants` задает topology variant/role/layer;
132 - `variantSources` превращает topology в concrete `SourceSetUsageBinding`;
133 - `variantArtifacts.slot(...)` описывает, какие bindings надо включить в slot;
134 - `VariantArtifactsResolver` превращает contributions slot-а в `FileCollection`;
135 - `VariantArtifactsPlugin` регистрирует для slot-а отдельный `ArtifactAssembly`;
136 - `OutgoingVariantPublication` и `OutgoingArtifactSlotPublication` публикуют
137 уже собранные slot artifacts наружу.
138
139 Каждый slot materialize-ится в отдельный `ArtifactAssembly`:
140
141 - task: `process<Variant><Slot>`;
142 - output dir: `build/variant-artifacts/<variant>/<slot>`.
143
144 ### primary slot
145
146 Primary slot задает artifact, который публикуется как основной artifact
147 configuration `<variant>Elements`.
148
149 Формы DSL:
150
151 ```groovy
152 variant('browser') {
153 primarySlot('typesPackage')
154
155 slot('typesPackage') {
156 fromVariant { output('types') }
157 }
158 }
159 ```
160
161 или sugar:
162
163 ```groovy
164 variant('browser') {
165 primarySlot('typesPackage') {
166 fromVariant { output('types') }
167 }
168 }
169 ```
170
171 Правила:
172
173 - если slot один, он считается primary неявно;
174 - если slots несколько, `primarySlot(...)` обязателен;
175 - `primarySlot` должен ссылаться на существующий slot.
176
2
177 ## LIFECYCLE
3 The `VariantArtifactsPlugin` implementation is now part of the `variants`
178
4 module, not the `common` module.
179 - `VariantsArtifactsPlugin` ждет `variants.whenFinalized(...)`;
180 - после этого валидирует `variantArtifacts`;
181 - регистрирует `ArtifactAssembly` по каждому slot;
182 - materialize-ит outgoing publications;
183 - вызывает `whenOutgoingVariant(...)`;
184 - callbacks replayable.
185
186 После finalize мутации `variantArtifacts` запрещены.
187
188 ## EVENTS
189
190 ### whenOutgoingVariant
191
192 Replayable callback на готовую outgoing publication variant-а.
193
194 Подходит для:
195
196 - настройки общих attributes build variant-а один раз;
197 - настройки per-slot artifact attributes;
198 - доконфигурации `ArtifactAssembly`.
199
200 ## PAYLOAD TYPES
201
202 ### OutgoingVariantPublication
203
204 Содержит:
205
206 - `variantName()`;
207 - `topologyVariant()`;
208 - `variantArtifact()`;
209 - `configuration()` — primary `<variant>Elements`;
210 - `primarySlot()`;
211 - `slots()` — все slot publications;
212 - `secondarySlots()`;
213 - `findSlot(name)`, `requireSlot(name)`.
214
215 Sugar:
216
217 - `configureConfiguration(Action|Closure)`.
218
219 ### OutgoingArtifactSlotPublication
220
221 Содержит:
222
223 - `slotName()`;
224 - `primary()`;
225 - `slot()` — модель `VariantArtifactSlot`;
226 - `assembly()`.
227
228 Sugar:
229
230 - `configureAssembly(Action|Closure)`;
231 - `configureArtifactAttributes(Action|Closure)`.
232
233 `configureArtifactAttributes(...)` пишет attributes:
234
235 - в `Configuration.attributes` для primary slot;
236 - в `ConfigurationVariant.attributes` для secondary slot.
237
238 ## CONSUMER SIDE
239
240 ### primary resolution
241
242 Обычное inter-project resolution выбирает primary artifact `<variant>Elements`.
243
244 Пример:
245
246 ```groovy
247 configurations {
248 compileView {
249 canBeResolved = true
250 canBeConsumed = false
251 canBeDeclared = true
252 attributes {
253 attribute(variantAttr, 'browser')
254 attribute(slotAttr, 'typesPackage')
255 }
256 }
257 }
258
259 dependencies {
260 compileView project(':producer')
261 }
262 ```
263
264 ### artifact selection for secondary slots
265
5
266 Secondary artifacts выбираются через `artifactView`.
6 Current documentation is maintained in the root [README.md](../README.md) and
267
7 [variant_artifacts.md](../variant_artifacts.md).
268 ```groovy
269 def jsFiles = configurations.compileView.incoming.artifactView {
270 attributes {
271 attribute(slotAttr, 'js')
272 }
273 }.files
274 ```
275
276 Здесь graph variant уже выбран, а `artifactView` выбирает нужный secondary
277 artifact representation.
278
279 ## VALIDATION
280
281 Проверяется:
282
283 - variant существует в topology model;
284 - slot contributions не ссылаются на неизвестные role/layer;
285 - при нескольких slots указан `primarySlot`;
286 - `primarySlot` ссылается на существующий slot.
287
288 ## API
289
290 ### VariantArtifactsExtension
291
292 - `variant(String)` — получить/создать variant artifact model;
293 - `variant(String, Action|Closure)` — сконфигурировать variant artifact;
294 - `getVariants()` — контейнер variant artifacts;
295 - `findVariant(name)`, `requireVariant(name)`;
296 - `whenOutgoingVariant(...)`.
297
298 ### VariantArtifact
299
300 - `slot(String)` — получить/создать slot;
301 - `slot(String, Action|Closure)` — сконфигурировать slot;
302 - `primarySlot(String)` — назначить primary slot;
303 - `primarySlot(String, Action|Closure)` — sugar: configure slot + mark as primary;
304 - `getSlots()`;
305 - `findSlot(name)`, `requireSlot(name)`;
306 - `findPrimarySlotName()`, `requirePrimarySlotName()`;
307 - `findPrimarySlot()`, `requirePrimarySlot()`.
308
309 ### VariantArtifactSlot
310
8
311 - `from(Object)`;
312 - `fromVariant(...)`;
313 - `fromRole(String, ...)`;
314 - `fromLayer(String, ...)`.
315
316 Внутренняя модель:
317
318 - slot хранит contributions, а не строковые rules;
319 - `fromVariant/fromRole/fromLayer` создают topology-aware contributions;
320 - `from(Object)` создает direct contribution, который materialize-ится даже
321 если у variant-а нет ни одного `SourceSetUsageBinding`;
322 - slot отдельно хранит topology references для validation:
323 `referencedRoleNames()` и `referencedLayerNames()`.
324
325 ### OutputSelectionSpec
326
327 - `output(name)`;
328 - `output(name, extra...)`.
329
330 `OutputSelectionSpec` это внутренний DSL-buffer для одного блока
331 `fromVariant/fromRole/fromLayer`. Он локально накапливает contributions и
332 передает их в slot только после успешного завершения configure-блока.
333
334 ## KEY CLASSES
335
336 - `VariantsArtifactsPlugin` — plugin adapter и materialization outgoing variants.
337 - `VariantArtifactsExtension` — root DSL и lifecycle.
338 - `VariantArtifact` — outgoing build variant model.
339 - `VariantArtifactSlot` — artifact representation slot.
340 - `VariantArtifactsResolver` — adapter между `variantSources` bindings и
341 contribution model slot-а.
342 - `OutgoingVariantPublication` — payload variant-level publication callback.
343 - `OutgoingArtifactSlotPublication` — payload per-slot publication callback.
344 - `ArtifactAssembly` — assembled files for a slot.
345
346 ## NOTES
347
348 - `common` не навязывает доменную логику выбора primary slot.
349 - `common` не фиксирует значения `usage`, `libraryelements` и прочих
350 slot-specific attributes.
351 - `common` не смешивает эту модель с отдельными publish осями вроде package
352 metadata.
353 - Closure callbacks используют delegate-first; для вложенных closure удобнее
354 явный параметр (`publication -> ...`, `slotPublication -> ...`).
@@ -1,159 +1,9
1 # Variant Sources Plugin
1 # Moved: Variant Sources Plugin
2
3 ## NAME
4
5 `VariantsSourcesPlugin` и extension `variantSources`.
6
7 ## SYNOPSIS
8
9 ```groovy
10 plugins {
11 id 'org.implab.gradle-variants-sources'
12 }
13
14 variants {
15 layer('main')
16
17 variant('browser') {
18 role('main') { layers('main') }
19 }
20
21 variant('node') {
22 role('main') { layers('main') }
23 }
24 }
25
26 variantSources {
27 bind('main').sourceSetNamePattern = '{layer}'
28
29 bind('main') {
30 configureSourceSet {
31 declareOutputs('compiled')
32 }
33 }
34
35 whenRegistered { sourceSetName() }
36 whenBound('browser') { roleName() }
37 }
38 ```
39
2
40 ## DESCRIPTION
3 The `VariantSourcesPlugin` implementation is now part of the `variants` module,
41
4 not the `common` module.
42 `VariantsSourcesPlugin` применяет `VariantsPlugin` и `SourcesPlugin`, затем
43 регистрирует source sets из модели `variants`.
44
45 Точка запуска registration:
46
47 - `variants.whenFinalized(model -> registerSourceSets(...))`
48
49 ### registration
50
51 Для каждой usage-связки `variant/role/layer` вычисляется имя source set,
52 регистрируется `GenericSourceSet` (если он еще не существует), затем
53 вызываются callbacks.
54
55 ### binding
56
57 `bind('<layer>')` возвращает `LayerBindingSpec` и задает policy для этого
58 слоя:
59
60 - как именовать source set;
61 - как конфигурировать source set;
62 - какие callbacks вызвать на registration/binding.
63
64 ### sourceSetNamePattern
65
66 `sourceSetNamePattern` определяет naming policy зарегистрированного source set.
67
68 Default:
69
70 - `{variant}{layerCap}`
71
72 Tokens:
73
74 - `{variant}`, `{variantCap}`
75 - `{role}`, `{roleCap}`
76 - `{layer}`, `{layerCap}`
77
78 Имя санитизируется (`[^A-Za-z0-9_.-] -> _`).
79
5
80 Ограничение:
6 Current documentation is maintained in the root [README.md](../README.md),
81
7 [variant_sources.md](../variant_sources.md), and
82 - один `sourceSetName` не может быть порожден разными слоями.
8 [variant_sources_precedence.md](../variant_sources_precedence.md).
83
84 ## EVENTS
85
86 ### whenRegistered
87
88 - callback на новый уникальный source set;
89 - replayable;
90 - при shared source set срабатывает один раз.
91
92 ### whenBound
93
94 - callback на каждую usage-связку `variant/role/layer`;
95 - replayable;
96 - подходит для per-usage логики.
97
98 ### variant filter
99
100 Фильтр по варианту поддерживает только usage-binding:
101
102 - `whenBound(String variantName, ...)`
103
104 ## PAYLOAD TYPES
105
106 `SourceSetRegistration` содержит:
107
108 - `layerName`, `sourceSetName`;
109 - `sourceSet` (`NamedDomainObjectProvider<GenericSourceSet>`).
110
111 Sugar:
112
113 - `configureSourceSet(Action|Closure)`.
114
115 `SourceSetUsageBinding` содержит:
116
117 - `variantName`, `roleName`, `layerName`, `sourceSetName`;
118 - `sourceSet` (`NamedDomainObjectProvider<GenericSourceSet>`).
119
9
120 Sugar:
121
122 - `configureSourceSet(Action|Closure)`.
123
124 ## API
125
126 ### VariantSourcesExtension
127
128 - `bind(BuildLayer)` — получить/создать binding для canonical layer identity.
129 - `bind(String)` — получить/создать binding по имени слоя.
130 - `bind(String, Action|Closure)` — сконфигурировать binding.
131 - `bind(BuildLayer, Action|Closure)` — сконфигурировать binding по `BuildLayer`.
132 - `getBindings()` — read-only snapshot текущих bindings.
133 - `whenRegistered(...)` — глобальные callbacks регистрации source set.
134 - `whenBound(...)` — глобальные callbacks usage-binding.
135 - `whenBound(String variantName, ...)` — usage-binding callbacks с variant-filter.
136
137 ### LayerBindingSpec
138
139 - `sourceSetNamePattern` — naming policy для source set слоя.
140 - `configureSourceSet(...)` — слойная конфигурация `GenericSourceSet`.
141 - `whenRegistered(...)` — callbacks регистрации в рамках слоя.
142 - `whenBound(...)` — callbacks usage-binding в рамках слоя.
143
144 ## KEY CLASSES
145
146 - `VariantsSourcesPlugin` — точка входа plugin adapter.
147 - `VariantSourcesExtension` — глобальный DSL bind/events.
148 - `LayerBindingSpec` — публичный DSL-contract layer-local policy/callbacks.
149 - `SourceSetRegistration` — payload регистрации source set.
150 - `SourceSetUsageBinding` — payload usage-binding.
151
152 ## NOTES
153
154 - `sourceSetNamePattern` фиксируется при первом чтении в registration
155 (`finalizeValueOnRead`).
156 - runtime state bindings скрыт внутри adapter implementation (`LayerBinding`).
157 - name-based bindings резолвятся к canonical `BuildLayer` через registry `variants`.
158 - Closure callbacks используют delegate-first.
159 - Для вложенных closure лучше явный параметр (`ctx -> ...`).
@@ -1,112 +1,8
1 # Variants Plugin
1 # Moved: Variants Plugin
2
3 ## NAME
4
5 `VariantsPlugin` и extension `variants`.
6
7 ## SYNOPSIS
8
9 ```groovy
10 plugins {
11 id 'org.implab.gradle-variants'
12 }
13
14 variants {
15 layer('mainBase')
16 layer('mainAmd')
17
18 variant('browser') {
19 attributes {
20 string('jsRuntime', 'browser')
21 string('jsModule', 'amd')
22 }
23
24 role('main') {
25 layers('mainBase', 'mainAmd')
26 }
27
28 artifactSlot('mainCompiled')
29 }
30 }
31 ```
32
33 ## DESCRIPTION
34
35 `VariantsPlugin` задает доменную модель сборки и ее валидацию. Плагин не
36 регистрирует compile/copy/bundle задачи напрямую.
37
38 ### layers
39
40 Глобальные логические слои. Служат единым словарем имен, на которые затем
41 ссылаются роли.
42
43 ### variants
44
45 Именованные варианты исполнения/пакетирования (`browser`, `node`, и т.д.).
46 Вариант агрегирует роли, атрибуты и artifact slots.
47
48 ### roles
49
50 Роль описывает набор слоев в пределах варианта (`main`, `test`, `tools`).
51 Одна роль может ссылаться на несколько слоев.
52
53 ### attributes
54
2
55 Typed-атрибуты (`Attribute<T> -> Provider<T>`) для передачи параметров в
3 The `VariantsPlugin` implementation is now part of the `variants` module, not
56 адаптеры и публикацию артефактов.
4 the `common` module.
57
58 ### artifact slots
59
60 Именованные слоты ожидаемых артефактов варианта. Используются как контракт
61 между моделью варианта и плагинами, создающими/публикующими результаты.
62
63 ## VALIDATION
64
65 В `finalizeModel()` выполняется проверка:
66
67 - роль не может ссылаться на неизвестный layer;
68 - пустые имена layer запрещены;
69 - имена ролей в варианте должны быть уникальны;
70 - имена artifact slots в варианте должны быть уникальны.
71
72 ## LIFECYCLE
73
74 - `VariantsPlugin` вызывает `variants.finalizeModel()` на `afterEvaluate`.
75 - после `finalizeModel()` мутации модели запрещены.
76 - `whenFinalized(...)` replayable.
77
78 ## API
79
80 ### BuildVariantsExtension
81
5
82 - `layer(...)` — объявление или конфигурация `BuildLayer`.
6 Current documentation is maintained in the root [README.md](../README.md) and
83 - `variant(...)` — объявление или конфигурация `BuildVariant`.
7 the design notes in [variant_sources.md](../variant_sources.md).
84 - `layers { layer(...) }`, `variants { ... }` — grouped DSL без публикации container API наружу.
85 - `all(...)` — callback для всех вариантов.
86 - `findLayer(name)`, `requireLayer(name)`, `getAllLayers()` — доступ к registry слоев.
87 - `getAll()`, `find(name)`, `require(name)` — доступ к вариантам.
88 - `validate()` — явный запуск валидации.
89 - `finalizeModel()` — валидация + финализация модели.
90 - `whenFinalized(...)` — callback по завершенной модели (replayable).
91
92 ### BuildVariant
93
94 - `attributes { ... }` — атрибуты варианта (+ sugar `string/bool/integer`).
95 - `role(...)`, `roles { ... }` — роли варианта.
96 - `artifactSlot(...)`, `artifactSlots { ... }` — артефактные слоты.
97
8
98 ## KEY CLASSES
99
100 - `VariantsPlugin` — точка входа плагина.
101 - `BuildVariantsExtension` — root extension и lifecycle.
102 - `BuildVariant` — агрегатная модель варианта.
103 - `BuildLayer` — canonical identity-model слоя.
104 - `BuildRole` — модель роли.
105 - `BuildArtifactSlot` — модель артефактного слота.
106 - `VariantAttributes` — typed wrapper для variant attributes.
107
108 ## NOTES
109
110 - Модель `variants` intentionally agnostic к toolchain.
111 - Layer registry хранится как явная identity-map, а не как публичный `NamedDomainObjectContainer`.
112 - Интеграция с задачами выполняется через `variantSources` и адаптеры.
@@ -1,2 +1,2
1 group=org.implab.gradle
1 group=org.implab.gradle
2 version=1.0 No newline at end of file
2 version=0.1.0
@@ -1,5 +1,9
1 # Variants and Variant Artifacts
1 # Variants and Variant Artifacts
2
2
3 > Design note. The current user-facing DSL and local publication workflow are
4 > documented in [README.md](README.md). Some snippets below are conceptual and
5 > describe model direction rather than exact public API.
6
3 ## Overview
7 ## Overview
4
8
5 This document describes the artifact model built on top of `variants` and
9 This document describes the artifact model built on top of `variants` and
@@ -592,7 +596,7 model rather than define it.
592
596
593 Examples:
597 Examples:
594
598
595 - `whenOutgoingVariant(...)`
599 - `whenOutgoingConfiguration(...)`
596 - `whenOutgoingSlot(...)`
600 - `whenOutgoingSlot(...)`
597
601
598 These hooks are adapter-facing customization points over already declared
602 These hooks are adapter-facing customization points over already declared
@@ -1,5 +1,9
1 # Variants and Variant Sources
1 # Variants and Variant Sources
2
2
3 > Design note. The current user-facing DSL and local publication workflow are
4 > documented in [README.md](README.md). Some snippets below are conceptual and
5 > describe model direction rather than exact public API.
6
3 ## Overview
7 ## Overview
4
8
5 This document describes a two-layer model for build variants:
9 This document describes a two-layer model for build variants:
@@ -510,7 +514,8 This policy is intentionally modeled as
510 property:
514 property:
511
515
512 * it must be chosen before the first selector rule is added
516 * it must be chosen before the first selector rule is added
513 * selector rules here mean `variant(...)`, `layer(...)`, and `unit(...)`
517 * selector rules here mean `configureEach(...)`, `variant(...)`, `layer(...)`,
518 and `unit(...)`
514 * once chosen, it cannot be changed later
519 * once chosen, it cannot be changed later
515 * it controls runtime behavior, not just a stored value
520 * it controls runtime behavior, not just a stored value
516 * the enforcement point is the first selector registration itself, not variants
521 * the enforcement point is the first selector registration itself, not variants
@@ -519,7 +524,7 property:
519 For source sets configured before materialization, selector precedence remains:
524 For source sets configured before materialization, selector precedence remains:
520
525
521 ```text
526 ```text
522 variant < layer < unit
527 configureEach < variant < layer < unit
523 ```
528 ```
524
529
525 For already materialized source sets in `warn` and `allow` modes:
530 For already materialized source sets in `warn` and `allow` modes:
@@ -16,14 +16,36 Instead, it provides configuration selec
16
16
17 ## Selectors
17 ## Selectors
18
18
19 Three selectors are available:
19 Four selectors are available:
20
20
21 - `configureEach(...)`
21 - `variant(...)`
22 - `variant(...)`
22 - `layer(...)`
23 - `layer(...)`
23 - `unit(...)`
24 - `unit(...)`
24
25
25 They all target the same set of compile units, but at different levels of specificity.
26 They all target the same set of compile units, but at different levels of specificity.
26
27
28 ### `configureEach(...)`
29
30 `configureEach(...)` applies configuration to every materialized compile-unit
31 source set.
32
33 Example:
34
35 ```groovy
36 variantSources {
37 configureEach {
38 sourceSet {
39 declareOutputs("js")
40 }
41 }
42 }
43 ```
44
45 Use this selector for global source-set conventions.
46
47 ---
48
27 ### `variant(...)`
49 ### `variant(...)`
28
50
29 `variant(...)` applies configuration to all compile units that belong to the given variant.
51 `variant(...)` applies configuration to all compile units that belong to the given variant.
@@ -33,9 +55,11 Example:
33 ```groovy
55 ```groovy
34 variantSources {
56 variantSources {
35 variant("browser") {
57 variant("browser") {
58 sourceSet {
36 declareOutputs("js", "dts")
59 declareOutputs("js", "dts")
37 }
60 }
38 }
61 }
62 }
39 ```
63 ```
40
64
41 This affects all compile units of `browser`, for example:
65 This affects all compile units of `browser`, for example:
@@ -57,11 +81,13 Example:
57 ```groovy
81 ```groovy
58 variantSources {
82 variantSources {
59 layer("main") {
83 layer("main") {
60 set("ts") {
84 sourceSet {
85 sets.create("ts") {
61 srcDir("src/main/ts")
86 srcDir("src/main/ts")
62 }
87 }
63 }
88 }
64 }
89 }
90 }
65 ```
91 ```
66
92
67 This affects all compile units with layer `main`, for example:
93 This affects all compile units with layer `main`, for example:
@@ -83,11 +109,13 Example:
83 ```groovy
109 ```groovy
84 variantSources {
110 variantSources {
85 unit("browser", "main") {
111 unit("browser", "main") {
86 set("resources") {
112 sourceSet {
113 sets.create("resources") {
87 srcDir("src/browserMain/resources")
114 srcDir("src/browserMain/resources")
88 }
115 }
89 }
116 }
90 }
117 }
118 }
91 ```
119 ```
92
120
93 This affects only:
121 This affects only:
@@ -103,14 +131,15 Use this selector for the most specific
103 For each compile unit, source-set configuration is applied in the following order:
131 For each compile unit, source-set configuration is applied in the following order:
104
132
105 ```text
133 ```text
106 variant < layer < unit
134 configureEach < variant < layer < unit
107 ```
135 ```
108
136
109 This means:
137 This means:
110
138
111 1. `variant(...)` actions are applied first
139 1. `configureEach(...)` actions are applied first
112 2. `layer(...)` actions are applied next
140 2. `variant(...)` actions are applied next
113 3. `unit(...)` actions are applied last
141 3. `layer(...)` actions are applied next
142 4. `unit(...)` actions are applied last
114
143
115 Each next level is allowed to refine or override the previous one.
144 Each next level is allowed to refine or override the previous one.
116
145
@@ -160,7 +189,8 Available modes:
160 Policy rules:
189 Policy rules:
161
190
162 - the policy must be chosen before the first selector rule is added
191 - the policy must be chosen before the first selector rule is added
163 - selector rules here mean `variant(...)`, `layer(...)`, and `unit(...)`
192 - selector rules here mean `configureEach(...)`, `variant(...)`, `layer(...)`,
193 and `unit(...)`
164 - once chosen, the policy cannot be changed later
194 - once chosen, the policy cannot be changed later
165 - the policy is single-valued; it is not intended to be switched during further
195 - the policy is single-valued; it is not intended to be switched during further
166 configuration
196 configuration
@@ -173,8 +203,8 Operationally:
173 already materialized targets
203 already materialized targets
174 - `warn` and `allow` keep compatibility with imperative late mutation
204 - `warn` and `allow` keep compatibility with imperative late mutation
175 - in `warn` and `allow`, already materialized targets observe the late action in
205 - in `warn` and `allow`, already materialized targets observe the late action in
176 actual registration order, not in reconstructed `variant < layer < unit`
206 actual registration order, not in reconstructed
177 order
207 `configureEach < variant < layer < unit` order
178
208
179 ---
209 ---
180
210
@@ -234,11 +264,11 Naming policy is fixed when the finalize
234
264
235 Operationally this means:
265 Operationally this means:
236
266
237 - policy selection must happen before `variantSources.whenFinalized(...)`
267 - policy selection must happen before `variantSources.whenAvailable(...)`
238 becomes observable
268 becomes observable
239 - compile-unit names are projected and validated before queued
269 - compile-unit names are projected and validated before queued
240 `whenFinalized(...)` callbacks are replayed
270 `whenAvailable(...)` callbacks are replayed
241 - changing naming policy from inside a `whenFinalized(...)` callback is too late
271 - changing naming policy from inside a `whenAvailable(...)` callback is too late
242
272
243 ---
273 ---
244
274
@@ -246,22 +276,34 Operationally this means:
246
276
247 ```groovy
277 ```groovy
248 variantSources {
278 variantSources {
279 configureEach {
280 sourceSet {
281 declareOutputs("js", "dts")
282 }
283 }
284
249 variant("browser") {
285 variant("browser") {
250 declareOutputs("js", "dts")
286 sourceSet {
287 registerOutput("js", layout.projectDirectory.file("inputs/browser.js"))
288 }
251 }
289 }
252
290
253 layer("main") {
291 layer("main") {
254 set("ts") {
292 sourceSet {
293 sets.create("ts") {
255 srcDir("src/main/ts")
294 srcDir("src/main/ts")
256 }
295 }
257 }
296 }
297 }
258
298
259 unit("browser", "main") {
299 unit("browser", "main") {
260 set("resources") {
300 sourceSet {
301 sets.create("resources") {
261 srcDir("src/browserMain/resources")
302 srcDir("src/browserMain/resources")
262 }
303 }
263 }
304 }
264 }
305 }
306 }
265 ```
307 ```
266
308
267 For compile unit `(browser, main)` the effective configuration is built in this order:
309 For compile unit `(browser, main)` the effective configuration is built in this order:
@@ -270,6 +312,9 1. `variant("browser")`
270 2. `layer("main")`
312 2. `layer("main")`
271 3. `unit("browser", "main")`
313 3. `unit("browser", "main")`
272
314
315 The global `configureEach(...)` selector is applied before the listed
316 variant/layer/unit selectors for every compile unit.
317
273 For compile unit `(browser, rjs)` the effective configuration is built in this order:
318 For compile unit `(browser, rjs)` the effective configuration is built in this order:
274
319
275 1. `variant("browser")`
320 1. `variant("browser")`
@@ -324,7 +369,7 This guarantees that:
324 - precedence is:
369 - precedence is:
325
370
326 ```text
371 ```text
327 variant < layer < unit
372 configureEach < variant < layer < unit
328 ```
373 ```
329
374
330 - registration order is preserved within the same selector level
375 - registration order is preserved within the same selector level
@@ -3,6 +3,8 plugins {
3 id "ivy-publish"
3 id "ivy-publish"
4 }
4 }
5
5
6 description = "Variant, source-set, and outgoing artifact model plugins for Gradle builds"
7
6 java {
8 java {
7 withJavadocJar()
9 withJavadocJar()
8 withSourcesJar()
10 withSourcesJar()
@@ -15,9 +17,7 dependencies {
15 compileOnly libs.jdt.annotations
17 compileOnly libs.jdt.annotations
16
18
17 api gradleApi(),
19 api gradleApi(),
18 libs.bundles.jackson
20 project(":common")
19
20 implementation project(":common")
21
21
22 testImplementation gradleTestKit()
22 testImplementation gradleTestKit()
23 testImplementation "org.junit.jupiter:junit-jupiter-api:5.11.4"
23 testImplementation "org.junit.jupiter:junit-jupiter-api:5.11.4"
@@ -52,6 +52,10 publishing {
52 descriptor.description {
52 descriptor.description {
53 text = providers.provider({ description })
53 text = providers.provider({ description })
54 }
54 }
55 descriptor.license {
56 name = "BSD-2-Clause"
57 url = "https://spdx.org/licenses/BSD-2-Clause.html"
55 }
58 }
56 }
59 }
57 }
60 }
61 }
General Comments 0
You need to be logged in to leave comments. Login now