##// END OF EJS Templates
more documentation
cin -
r44:ae7ec3f08ac3 default
parent child
Show More
@@ -164,6 +164,8 Policy rules:
164 164 - once chosen, the policy cannot be changed later
165 165 - the policy is single-valued; it is not intended to be switched during further
166 166 configuration
167 - the enforcement point is the first selector registration itself; finalization
168 of `variants` alone does not freeze this policy
167 169
168 170 Operationally:
169 171
@@ -176,6 +178,70 Operationally:
176 178
177 179 ---
178 180
181 ## Compile-Unit Naming Policy
182
183 `variantSources` also exposes a policy for projecting compile units to symbolic
184 source-set names:
185
186 ```groovy
187 variantSources {
188 namingPolicy {
189 failOnNameCollision()
190 }
191 }
192 ```
193
194 Base projected name:
195
196 - `sourceSetName = variantName + capitalize(layerName)`
197
198 Example:
199
200 - `(browser, main)` -> `browserMain`
201 - `(browser, rjs)` -> `browserRjs`
202
203 Available modes:
204
205 - `failOnNameCollision()` rejects finalized compile-unit models that project the
206 same base name for different compile units
207 - `resolveNameCollision()` resolves such collisions deterministically
208
209 ### `resolveNameCollision()` semantics
210
211 Conflicting compile units are ordered canonically by:
212
213 ```text
214 (variant.name, layer.name)
215 ```
216
217 Name assignment in a conflicting group is:
218
219 - the first compile unit keeps the base name
220 - the second gets suffix `2`
221 - the third gets suffix `3`
222 - and so on
223
224 Example:
225
226 - `(foo, variantBar)` and `(fooVariant, bar)` both project to `fooVariantBar`
227 - after canonical ordering:
228 - `(foo, variantBar)` -> `fooVariantBar`
229 - `(fooVariant, bar)` -> `fooVariantBar2`
230
231 ### Fixation Point
232
233 Naming policy is fixed when the finalized `VariantSourcesContext` is created.
234
235 Operationally this means:
236
237 - policy selection must happen before `variantSources.whenFinalized(...)`
238 becomes observable
239 - compile-unit names are projected and validated before queued
240 `whenFinalized(...)` callbacks are replayed
241 - changing naming policy from inside a `whenFinalized(...)` callback is too late
242
243 ---
244
179 245 ## Example
180 246
181 247 ```groovy
@@ -265,5 +331,7 variant < layer < unit
265 331 - already materialized targets are handled by `lateConfigurationPolicy(...)`
266 332 - the late-configuration policy must be selected before the first selector rule
267 333 and cannot be changed later
334 - compile-unit naming is governed by `namingPolicy(...)`
335 - by default, name collisions fail fast during finalized context creation
268 336 - `variants` defines what exists
269 337 - `variantSources` defines how those compile units are materialized as source sets
@@ -4,14 +4,18 import org.gradle.api.NamedDomainObjectP
4 4 import org.implab.gradle.common.sources.GenericSourceSet;
5 5
6 6 /**
7 * Materializes symbolic source set names into actual GenericSourceSet
7 * Materializes symbolic source set names into actual {@link GenericSourceSet}
8 8 * instances.
9 *
10 * <p>Symbolic names are assigned from the finalized compile-unit model using
11 * the selected
12 * {@link VariantSourcesExtension#namingPolicy(org.gradle.api.Action)}.
9 13 */
10 14 public interface SourceSetMaterializer {
11 15 /**
12 16 * Returns a lazy provider for the source set corresponding to the compile unit.
13 17 *
14 * The provider is stable and cached per compile unit.
18 * <p>The provider is stable and cached per compile unit.
15 19 */
16 20 NamedDomainObjectProvider<GenericSourceSet> getSourceSet(CompileUnit unit);
17 } No newline at end of file
21 }
@@ -9,7 +9,9 import org.implab.gradle.variants.core.V
9 9 /**
10 10 * Registry of symbolic source set names produced by sources projection.
11 11 *
12 * Identity in this registry is the GenericSourceSet name.
12 * <p>Identity in this registry is the {@link GenericSourceSet} name assigned
13 * by the finalized
14 * {@link VariantSourcesExtension#namingPolicy(org.gradle.api.Action)}.
13 15 */
14 16 public interface VariantSourcesContext {
15 17
@@ -21,6 +21,9 public interface VariantSourcesExtension
21 21 * <li>once selected, it cannot be changed later;</li>
22 22 * <li>the policy controls both diagnostics and late-application semantics.</li>
23 23 * </ul>
24 *
25 * <p>If not selected explicitly, the default is
26 * {@link LateConfigurationPolicySpec#failOnLateConfiguration()}.
24 27 */
25 28 void lateConfigurationPolicy(Action<? super LateConfigurationPolicySpec> action);
26 29
@@ -28,24 +31,63 public interface VariantSourcesExtension
28 31 lateConfigurationPolicy(Closures.action(closure));
29 32 }
30 33
34 /**
35 * Selects how compile-unit name collisions are handled when the finalized
36 * source context is created.
37 *
38 * <p>This policy is single-valued:
39 * <ul>
40 * <li>it must be selected before the finalized
41 * {@link VariantSourcesContext} becomes observable through
42 * {@link #whenFinalized(Action)};</li>
43 * <li>once the context is being created, the policy is fixed and cannot be
44 * changed later;</li>
45 * <li>the policy governs validation of compile-unit names produced by the
46 * source-set materializer.</li>
47 * </ul>
48 *
49 * <p>If not selected explicitly, the default is
50 * {@link NamingPolicySpec#failOnNameCollision()}.
51 */
31 52 void namingPolicy(Action<? super NamingPolicySpec> action);
32 53
33 54 default void namingPolicy(Closure<?> closure) {
34 55 namingPolicy(Closures.action(closure));
35 56 }
36 57
58 /**
59 * Registers a selector rule for all compile units of the given layer.
60 *
61 * <p>Registering the first selector rule fixes the selected
62 * {@link #lateConfigurationPolicy(Action)} for the remaining extension
63 * lifecycle.
64 */
37 65 void layer(String layerName, Action<? super GenericSourceSet> action);
38 66
39 67 default void layer(String layerName, Closure<?> closure) {
40 68 layer(layerName, Closures.action(closure));
41 69 }
42 70
71 /**
72 * Registers a selector rule for all compile units of the given variant.
73 *
74 * <p>Registering the first selector rule fixes the selected
75 * {@link #lateConfigurationPolicy(Action)} for the remaining extension
76 * lifecycle.
77 */
43 78 void variant(String variantName, Action<? super GenericSourceSet> action);
44 79
45 80 default void variant(String variantName, Closure<?> closure) {
46 81 variant(variantName, Closures.action(closure));
47 82 }
48 83
84 /**
85 * Registers a selector rule for one exact compile unit.
86 *
87 * <p>Registering the first selector rule fixes the selected
88 * {@link #lateConfigurationPolicy(Action)} for the remaining extension
89 * lifecycle.
90 */
49 91 void unit(String variantName, String layerName, Action<? super GenericSourceSet> action);
50 92
51 93 /**
@@ -56,6 +98,10 public interface VariantSourcesExtension
56 98 * <li>if called before variants finalization, action is queued
57 99 * <li>if called after variants finalization, action is invoked immediately
58 100 * </ul>
101 *
102 * <p>By the time this callback becomes observable, compile-unit naming
103 * policy has already been fixed and symbolic source-set names for finalized
104 * compile units are determined.
59 105 */
60 106 void whenFinalized(Action<? super VariantSourcesContext> action);
61 107
@@ -98,8 +144,21 public interface VariantSourcesExtension
98 144 }
99 145
100 146 interface NamingPolicySpec {
147 /**
148 * Rejects finalized compile-unit models that project the same source-set
149 * name for different compile units.
150 */
101 151 void failOnNameCollision();
102 152
153 /**
154 * Resolves name collisions deterministically for the finalized
155 * compile-unit model.
156 *
157 * <p>Conflicting compile units are ordered canonically by
158 * {@code (variant.name, layer.name)}. The first unit keeps the base
159 * projected name, and each next unit receives a numeric suffix
160 * ({@code 2}, {@code 3}, ...).
161 */
103 162 void resolveNameCollision();
104 163 }
105 164 }
@@ -453,7 +453,7 Reasons:
453 453
454 454 * the DSL is internal to source materialization
455 455 * the source of truth for unit existence is already finalized in `VariantsView`
456 * `GenericSourceSetMaterializer` returns `NamedDomainObjectProvider<GenericSourceSet>`
456 * `SourceSetMaterializer` returns `NamedDomainObjectProvider<GenericSourceSet>`
457 457 * adapters may need to refine source-related behavior after `variants` is finalized
458 458
459 459 Therefore:
@@ -468,6 +468,11 It reflects the difference between:
468 468 * a closed domain model
469 469 * an open infrastructure/materialization model
470 470
471 This openness is still constrained by explicit policy fixation points:
472
473 * late-configuration policy is fixed when the first selector rule is registered
474 * naming policy is fixed when the finalized `VariantSourcesContext` is created
475
471 476 ---
472 477
473 478 ## Late configuration policy
@@ -508,6 +513,8 property:
508 513 * selector rules here mean `variant(...)`, `layer(...)`, and `unit(...)`
509 514 * once chosen, it cannot be changed later
510 515 * it controls runtime behavior, not just a stored value
516 * the enforcement point is the first selector registration itself, not variants
517 finalization in isolation
511 518
512 519 For source sets configured before materialization, selector precedence remains:
513 520
@@ -523,6 +530,82 For already materialized source sets in
523 530
524 531 ---
525 532
533 ## Compile-unit naming policy
534
535 Source-set naming is treated as a separate policy concern from selector
536 registration.
537
538 Conceptually, `variantSources` exposes:
539
540 ```groovy
541 variantSources {
542 namingPolicy {
543 failOnNameCollision()
544 }
545 }
546 ```
547
548 The base projected name of a compile unit is:
549
550 ```text
551 variantName + capitalize(layerName)
552 ```
553
554 Examples:
555
556 * `(browser, main)` -> `browserMain`
557 * `(browser, rjs)` -> `browserRjs`
558
559 Available modes are:
560
561 * `failOnNameCollision()` - reject finalized compile-unit models that project
562 the same source-set name for different compile units
563 * `resolveNameCollision()` - resolve such conflicts deterministically
564
565 ### `resolveNameCollision()` semantics
566
567 Conflicting compile units are ordered canonically by:
568
569 ```text
570 (variant.name, layer.name)
571 ```
572
573 Within one conflicting group:
574
575 * the first compile unit keeps the base name
576 * the second gets suffix `2`
577 * the third gets suffix `3`
578 * and so on
579
580 For example, if:
581
582 * `(foo, variantBar)` projects to `fooVariantBar`
583 * `(fooVariant, bar)` also projects to `fooVariantBar`
584
585 then canonical ordering yields:
586
587 * `(foo, variantBar)` -> `fooVariantBar`
588 * `(fooVariant, bar)` -> `fooVariantBar2`
589
590 ### Fixation point
591
592 Naming policy is fixed when the finalized `VariantSourcesContext` is created.
593
594 Operationally this means:
595
596 * naming policy must be selected before `variantSources.whenFinalized(...)`
597 becomes observable
598 * compile-unit names are projected and validated before queued
599 `whenFinalized(...)` callbacks are replayed
600 * changing naming policy from inside a `whenFinalized(...)` callback is too late
601
602 This differs intentionally from late-configuration policy:
603
604 * late-configuration policy is fixed by the first selector rule
605 * naming policy is fixed by finalized-context creation
606
607 ---
608
526 609 ## `VariantSourcesContext`
527 610
528 611 `variantSources.whenFinalized(...)` remains useful, but not because `variantSources` itself is frozen.
@@ -533,7 +616,12 This context contains:
533 616
534 617 * `CompileUnitsView`
535 618 * `RoleProjectionsView`
536 * `GenericSourceSetMaterializer`
619 * `SourceSetMaterializer`
620
621 By the time the context becomes observable:
622
623 * compile-unit naming policy is already fixed
624 * symbolic source-set names for finalized compile units are already determined
537 625
538 626 Conceptually:
539 627
@@ -541,7 +629,7 Conceptually:
541 629 interface VariantSourcesContext {
542 630 CompileUnitsView getCompileUnits();
543 631 RoleProjectionsView getRoleProjections();
544 GenericSourceSetMaterializer getSourceSets();
632 SourceSetMaterializer getSourceSets();
545 633 }
546 634 ```
547 635
@@ -559,15 +647,17 variantSources.whenFinalized(ctx -> {
559 647
560 648 ---
561 649
562 ## `GenericSourceSetMaterializer`
650 ## `SourceSetMaterializer`
563 651
564 652 ### Purpose
565 653
566 `GenericSourceSetMaterializer` is the official source of truth for materialized source sets.
654 `SourceSetMaterializer` is the official source of truth for materialized source sets.
567 655
568 656 It is responsible for:
569 657
570 658 * lazy creation of `GenericSourceSet`
659 * projecting finalized compile units to symbolic source-set names
660 * validating or resolving name collisions according to naming policy
571 661 * applying `layerRule`
572 662 * connecting a compile unit to a source set provider
573 663 * exposing source sets to adapters
@@ -579,14 +669,14 Adapters should not apply layer rules th
579 669 ### Conceptual API
580 670
581 671 ```java
582 interface GenericSourceSetMaterializer {
672 interface SourceSetMaterializer {
583 673 NamedDomainObjectProvider<GenericSourceSet> getSourceSet(CompileUnit unit);
584 674 }
585 675 ```
586 676
587 677 ---
588 678
589 ## Why `GenericSourceSetMaterializer` should own `layerRule` application
679 ## Why `SourceSetMaterializer` should own `layerRule` application
590 680
591 681 If adapters applied `layerRule` directly, responsibility would leak across multiple layers:
592 682
@@ -599,7 +689,7 This would make the model harder to reas
599 689 Instead:
600 690
601 691 * `layerRule` is DSL/spec-level
602 * `GenericSourceSetMaterializer` is execution/materialization-level
692 * `SourceSetMaterializer` is execution/materialization-level
603 693 * adapters are consumption-level
604 694
605 695 This gives a much cleaner separation.
@@ -737,6 +827,11 guarantee.
737 827
738 828 Materialized `GenericSourceSet` objects should remain behind a lazy API.
739 829
830 ### 7. Make name-collision behavior explicit
831
832 Compile-unit naming must be governed by an explicit policy, not by incidental
833 materialization order.
834
740 835 ---
741 836
742 837 ## Summary
@@ -758,6 +853,7 An open, source-materialization layer:
758 853
759 854 * layer source rules
760 855 * compile-unit source set materialization
856 * compile-unit naming policy
761 857 * adapter-facing `GenericSourceSet` providers
762 858
763 859 ### Derived views
General Comments 0
You need to be logged in to leave comments. Login now