| @@ -49,7 +49,7 public abstract class VariantArtifactsPl | |||||
| 49 | // wire artifact assemblies to configuration variants |
|
49 | // wire artifact assemblies to configuration variants | |
| 50 | var assembliesBridge = new ArtifactAssemblyBinder(assemblies); |
|
50 | var assembliesBridge = new ArtifactAssemblyBinder(assemblies); | |
| 51 | var primarySlotConvention = new SingleSlotConvention(providers); |
|
51 | var primarySlotConvention = new SingleSlotConvention(providers); | |
| 52 | var materializationHandler = new MaterializationPolicyHandler(); |
|
52 | var materializationHandler = new MaterializationPolicyHandler(objects); | |
| 53 |
|
53 | |||
| 54 | // bind slot assemblies to outgoing variants |
|
54 | // bind slot assemblies to outgoing variants | |
| 55 | outgoing.configureEach(assembliesBridge::execute); |
|
55 | outgoing.configureEach(assembliesBridge::execute); | |
| @@ -51,6 +51,11 public interface ArtifactAssemblies { | |||||
| 51 | */ |
|
51 | */ | |
| 52 | void configureEach(Action<? super ArtifactAssembly> action); |
|
52 | void configureEach(Action<? super ArtifactAssembly> action); | |
| 53 |
|
53 | |||
| 54 | /** ΠΡΠ΅Ρ Π·Π°ΡΠ΅Π³ΠΈΡΡΡΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ ΡΠ»ΠΎΡ */ |
|
54 | /** | |
|
|
55 | * Finds a registered assembly for the given slot identity. | |||
|
|
56 | * | |||
|
|
57 | * @param slot slot identity inside a variant outgoing contract | |||
|
|
58 | * @return registered assembly, if the slot body has already been materialized | |||
|
|
59 | */ | |||
| 55 | Optional<ArtifactAssembly> find(ArtifactSlot slot); |
|
60 | Optional<ArtifactAssembly> find(ArtifactSlot slot); | |
| 56 | } |
|
61 | } | |
| @@ -11,7 +11,7 import groovy.lang.Closure; | |||||
| 11 | * Materialized root outgoing configuration of a variant. |
|
11 | * Materialized root outgoing configuration of a variant. | |
| 12 | * |
|
12 | * | |
| 13 | * <p>This is a variant-level publication hook. Slot-specific publication state is exposed separately via |
|
13 | * <p>This is a variant-level publication hook. Slot-specific publication state is exposed separately via | |
| 14 |
* {@link Outgoing |
|
14 | * {@link OutgoingConfigurationSlotSpec}. | |
| 15 | */ |
|
15 | */ | |
| 16 | public interface OutgoingConfigurationSpec { |
|
16 | public interface OutgoingConfigurationSpec { | |
| 17 | /** |
|
17 | /** | |
| @@ -8,43 +8,56 import org.gradle.api.provider.Property; | |||||
| 8 | import org.implab.gradle.variants.core.Variant; |
|
8 | import org.implab.gradle.variants.core.Variant; | |
| 9 |
|
9 | |||
| 10 | /** |
|
10 | /** | |
| 11 | * ΠΠΏΠΈΡΡΠ²Π°Π΅Ρ ΠΈΡΡ ΠΎΠ΄ΡΡΡΡ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ Π²Π°ΡΠΈΠ°Π½ΡΠ° |
|
11 | * Plugin model object for one variant-level outgoing contract. | |
| 12 | * |
|
12 | * | |
| 13 | * ΠΠ°Π΄Π°Π΅Ρ ΡΠ²ΡΠ·Ρ ΠΌΠ΅ΠΆΠ΄Ρ ΠΌΠΎΠ΄Π΅Π»ΡΡ Π²Π°ΡΠΈΠ°Π½ΡΠΎΠ² ΠΈ ΠΌΠΎΠ΄Π΅Π»ΡΡ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΉ gradle ΡΠ΅ΡΠ΅Π· |
|
13 | * <p>An outgoing variant connects a core {@link Variant} identity with the lazy | |
| 14 | * ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ {@link #getConfiguration()}. Π’Π°ΠΊΠΆΠ΅ Π·Π°Π΄Π°Π΅Ρ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΡ ΠΎΡΡ ΡΠ»ΠΎΡΠΎΠ² |
|
14 | * Gradle consumable configuration registered for that variant. It also exposes a | |
| 15 | * ΠΏΡΠ±Π»ΠΈΠΊΠ°ΡΠΈΠΈ, Π½ΠΎ Π½Π΅ Π·Π°Π΄Π°Π΅Ρ ΠΏΡΠ°Π²ΠΈΠ» ΡΠ²ΡΠ·ΡΠ²Π°Π½ΠΈΡ ΡΡΠΈΡ ΡΠ»ΠΎΡΠΎΠ² Ρ ΡΠ°ΠΌΠΎΠΉ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠ΅ΠΉ |
|
15 | * live container of slot identities. Slot identities are only declarations and do | |
| 16 | * ΠΈ ΠΈΡ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΡΠΌ. Π‘Π°ΠΌΡΠΉ ΠΏΡΠΎΡΡΠΎΠΉ Π²Π°ΡΠΈΠ°Π½Ρ ΡΡΠΎ {@link ArtifactAssemblies}. |
|
16 | * not imply that a Gradle outgoing artifact variant or an {@link ArtifactAssembly} | |
|
|
17 | * has been materialized. | |||
| 17 | */ |
|
18 | */ | |
| 18 | public interface OutgoingVariant { |
|
19 | public interface OutgoingVariant { | |
| 19 | /** |
|
20 | /** | |
| 20 | * ΠΡΡ ΠΎΠ΄Π½ΡΠΉ Π²Π°ΡΠΈΠ°Π½Ρ Π΄Π»Ρ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ ΡΡΡΠΎΠΈΡΡΡ Outgoing ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ |
|
21 | * Returns the variant that owns this outgoing contract. | |
|
|
22 | * | |||
|
|
23 | * @return variant identity | |||
| 21 | */ |
|
24 | */ | |
| 22 | Variant getVariant(); |
|
25 | Variant getVariant(); | |
| 23 |
|
26 | |||
| 24 | /** |
|
27 | /** | |
| 25 | * ΠΡΠΎΠ²Π°ΠΉΠ΄Π΅Ρ Π·Π°ΡΠ΅Π³ΠΈΡΡΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΉ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ |
|
28 | * Returns the provider of the registered consumable outgoing configuration. | |
|
|
29 | * | |||
|
|
30 | * @return outgoing configuration provider | |||
| 26 | */ |
|
31 | */ | |
| 27 | NamedDomainObjectProvider<? extends Configuration> getConfiguration(); |
|
32 | NamedDomainObjectProvider<? extends Configuration> getConfiguration(); | |
| 28 |
|
33 | |||
|
|
34 | /** | |||
|
|
35 | * Configures the registered outgoing configuration. | |||
|
|
36 | * | |||
|
|
37 | * @param action configuration action | |||
|
|
38 | */ | |||
| 29 | default void configureOutgoing(Action<? super Configuration> action) { |
|
39 | default void configureOutgoing(Action<? super Configuration> action) { | |
| 30 | getConfiguration().configure(action); |
|
40 | getConfiguration().configure(action); | |
| 31 | } |
|
41 | } | |
| 32 |
|
42 | |||
| 33 | /** |
|
43 | /** | |
| 34 | * Π‘Π»ΠΎΡΡ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ, Π΄Π°Π½Π½Π°Ρ ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΡ ΠΆΠΈΠ²Π°Ρ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ |
|
44 | * Returns the live slot identity container. | |
| 35 | * ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΈ ΠΎΠ± ΠΎΠ±ΡΡΠ²Π»Π΅Π½Π½ΡΡ ΡΠ»ΠΎΡΠ°Ρ , Π½ΠΎ ΡΡΠΈ ΡΠ»ΠΎΡΡ Π½Π΅ |
|
45 | * | |
| 36 | * ΠΎΠ±ΡΠ·Π°Π½Ρ Π±ΡΡΡ ΡΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠΈΡΠΎΠ²Π°Π½Ρ, Ρ.Π΅. ΡΡΠΎ ΡΠΎΠ»ΡΠΊΠΎ Identity. |
|
46 | * <p>This collection is intended for discovery and selection. Slot presence does | |
|
|
47 | * not guarantee that the slot has a configured assembly body or a materialized | |||
|
|
48 | * Gradle outgoing artifact variant. | |||
| 37 | * |
|
49 | * | |
| 38 | * @see {@link ArtifactSlot} |
|
50 | * @see {@link ArtifactSlot} | |
| 39 | */ |
|
51 | */ | |
| 40 | NamedDomainObjectContainer<Slot> getSlots(); |
|
52 | NamedDomainObjectContainer<Slot> getSlots(); | |
| 41 |
|
53 | |||
| 42 | /** |
|
54 | /** | |
| 43 | * ΠΡΠ½ΠΎΠ²Π½ΠΎΠΉ Π½Π°Π±ΠΎΡ Π°ΡΡΠ΅ΡΠ°ΠΊΡΠΎΠ² (primary variant) Π΄Π»Ρ ΠΈΡΡ ΠΎΠ΄ΡΡΠ΅ΠΉ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ |
|
55 | * Returns the primary slot property. | |
| 44 | * |
|
56 | * | |
| 45 | * <p> |
|
57 | * <p>If exactly one slot is declared, the single-slot convention uses that slot as | |
| 46 | * ΠΡΠ»ΠΈ Π² ΡΠ²ΠΎΠΉΡΡΠ²Π΅ {@link #getSlots()} Π΅ΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΡΠ»ΠΎΠΉ, ΡΠΎ ΠΏΠΎ ΠΊΠΎΠ½Π²Π΅Π½ΡΠΈΠΈ ΠΎΠ½ |
|
58 | * the primary one. Reading this property finalizes the selected primary slot. | |
| 47 | * ΡΡΠΈΡΠ°Π΅ΡΡΡ ΡΠ°ΠΊΠΆΠ΅ ΠΎΡΠ½ΠΎΠ²Π½ΡΠΌ. |
|
59 | * | |
|
|
60 | * @return primary slot property | |||
| 48 | */ |
|
61 | */ | |
| 49 | Property<Slot> getPrimarySlot(); |
|
62 | Property<Slot> getPrimarySlot(); | |
| 50 | } |
|
63 | } | |
| @@ -7,29 +7,80 import org.gradle.api.InvalidUserDataExc | |||||
| 7 | import org.implab.gradle.variants.core.Variant; |
|
7 | import org.implab.gradle.variants.core.Variant; | |
| 8 |
|
8 | |||
| 9 | /** |
|
9 | /** | |
| 10 | * ΠΠΎΠ½ΡΠ΅ΠΊΡΡ ΡΠ°Π±ΠΎΡΡ Ρ Π²Π°ΡΠΈΠ°Π½ΡΠ°ΠΌΠΈ ΠΏΡΠ±Π»ΠΈΠΊΠ°ΡΠΈΠΈ, ΡΡΠ°Π½ΠΎΠ²ΠΈΡΡΡ Π΄ΠΎΡΡΡΠΏΠ½ΡΠΌ ΠΏΠΎΡΠ»Π΅ |
|
10 | * Live context for declaring and observing variant outgoing publications. | |
| 11 | * ΡΠΈΠ½Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΌΠΎΠ΄Π΅Π»ΠΈ Π²Π°ΡΠΈΠ°Π½ΡΠΎΠ². Π€Π°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΆΠΈΠ²ΠΎΠΉ ΠΌΠΎΠ΄Π΅Π»ΡΡ |
|
11 | * | |
|
|
12 | * <p>The context becomes available after the core variant model has been finalized. | |||
|
|
13 | * It owns variant-level outgoing declarations, assembly lookup, and hooks for | |||
|
|
14 | * materialized Gradle-facing publication state. | |||
| 12 | */ |
|
15 | */ | |
| 13 | public interface OutgoingVariantsContext { |
|
16 | public interface OutgoingVariantsContext { | |
| 14 |
|
17 | |||
|
|
18 | /** | |||
|
|
19 | * Returns the assembly lookup service. | |||
|
|
20 | * | |||
|
|
21 | * <p>Assemblies are stateful slot bodies resolved from cheap {@link ArtifactSlot} | |||
|
|
22 | * identities. | |||
|
|
23 | * | |||
|
|
24 | * @return assembly lookup service | |||
|
|
25 | */ | |||
| 15 | ArtifactAssemblies getAssemblies(); |
|
26 | ArtifactAssemblies getAssemblies(); | |
| 16 |
|
27 | |||
|
|
28 | /** | |||
|
|
29 | * Configures artifact slots of the given variant. | |||
|
|
30 | * | |||
|
|
31 | * @param variant variant identity | |||
|
|
32 | * @param action variant artifact declaration | |||
|
|
33 | */ | |||
| 17 | void configureVariant(Variant variant, Action<? super VariantArtifactsSpec> action); |
|
34 | void configureVariant(Variant variant, Action<? super VariantArtifactsSpec> action); | |
| 18 |
|
35 | |||
| 19 | /** |
|
36 | /** | |
| 20 | * Replayable hook Π΄Π»Ρ Π²ΡΠ΅Ρ ΠΎΠ±ΡΡΠ²Π»Π΅Π½Π½ΡΡ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΉ |
|
37 | * Registers a replayable action for declared outgoing variants. | |
|
|
38 | * | |||
|
|
39 | * <p>The action receives the plugin model object, not necessarily a materialized | |||
|
|
40 | * Gradle publication. Use {@link #whenOutgoingConfiguration(Action)} and | |||
|
|
41 | * {@link #whenOutgoingSlot(Action)} for materialized Gradle-facing state. | |||
|
|
42 | * | |||
|
|
43 | * @param action outgoing variant action | |||
| 21 | */ |
|
44 | */ | |
| 22 | void configureEach(Action<? super OutgoingVariant> action); |
|
45 | void configureEach(Action<? super OutgoingVariant> action); | |
| 23 |
|
46 | |||
|
|
47 | /** | |||
|
|
48 | * Finds the outgoing model for the given variant. | |||
|
|
49 | * | |||
|
|
50 | * @param variant variant identity | |||
|
|
51 | * @return outgoing model, if declared | |||
|
|
52 | */ | |||
| 24 | Optional<OutgoingVariant> findOutgoing(Variant variant); |
|
53 | Optional<OutgoingVariant> findOutgoing(Variant variant); | |
| 25 |
|
54 | |||
|
|
55 | /** | |||
|
|
56 | * Requires the outgoing model for the given variant. | |||
|
|
57 | * | |||
|
|
58 | * @param variant variant identity | |||
|
|
59 | * @return outgoing model | |||
|
|
60 | * @throws InvalidUserDataException if the outgoing variant is not declared | |||
|
|
61 | */ | |||
| 26 | default OutgoingVariant requireOutgoing(Variant variant) { |
|
62 | default OutgoingVariant requireOutgoing(Variant variant) { | |
| 27 | return findOutgoing(variant) |
|
63 | return findOutgoing(variant) | |
| 28 | .orElseThrow(() -> new InvalidUserDataException("Outgoing variant '" + variant + "' isn't registered")); |
|
64 | .orElseThrow(() -> new InvalidUserDataException("Outgoing variant '" + variant + "' isn't registered")); | |
| 29 | } |
|
65 | } | |
| 30 |
|
66 | |||
|
|
67 | /** | |||
|
|
68 | * Registers a replayable action for materialized variant-level outgoing | |||
|
|
69 | * configurations. | |||
|
|
70 | * | |||
|
|
71 | * @param action materialized outgoing configuration action | |||
|
|
72 | */ | |||
| 31 | void whenOutgoingConfiguration(Action<? super OutgoingConfigurationSpec> action); |
|
73 | void whenOutgoingConfiguration(Action<? super OutgoingConfigurationSpec> action); | |
| 32 |
|
74 | |||
|
|
75 | /** | |||
|
|
76 | * Registers a replayable action for materialized slot publications. | |||
|
|
77 | * | |||
|
|
78 | * <p>Slot publication hooks follow the Gradle outgoing publication model. A | |||
|
|
79 | * declared slot identity by itself does not guarantee that a slot publication has | |||
|
|
80 | * been materialized. | |||
|
|
81 | * | |||
|
|
82 | * @param action materialized slot publication action | |||
|
|
83 | */ | |||
| 33 | void whenOutgoingSlot(Action<? super OutgoingConfigurationSlotSpec> action); |
|
84 | void whenOutgoingSlot(Action<? super OutgoingConfigurationSlotSpec> action); | |
| 34 |
|
85 | |||
| 35 |
|
86 | |||
| @@ -17,7 +17,6 public interface VariantArtifactsSpec { | |||||
| 17 | * |
|
17 | * | |
| 18 | * @param name slot name |
|
18 | * @param name slot name | |
| 19 | * @param action slot declaration |
|
19 | * @param action slot declaration | |
| 20 | * @return slot identity |
|
|||
| 21 | */ |
|
20 | */ | |
| 22 | void slot(String name, Action<? super ArtifactAssemblySpec> action); |
|
21 | void slot(String name, Action<? super ArtifactAssemblySpec> action); | |
| 23 |
|
22 | |||
| @@ -30,7 +29,6 public interface VariantArtifactsSpec { | |||||
| 30 | * |
|
29 | * | |
| 31 | * @param name slot name |
|
30 | * @param name slot name | |
| 32 | * @param action slot declaration |
|
31 | * @param action slot declaration | |
| 33 | * @return slot identity |
|
|||
| 34 | */ |
|
32 | */ | |
| 35 | void primarySlot(String name, Action<? super ArtifactAssemblySpec> action); |
|
33 | void primarySlot(String name, Action<? super ArtifactAssemblySpec> action); | |
| 36 |
|
34 | |||
| @@ -7,8 +7,7 import org.implab.gradle.variants.artifa | |||||
| 7 | import org.implab.gradle.variants.artifacts.OutgoingVariant; |
|
7 | import org.implab.gradle.variants.artifacts.OutgoingVariant; | |
| 8 |
|
8 | |||
| 9 | /** |
|
9 | /** | |
| 10 | * Π‘Π²ΡΠ·ΡΠ²Π°Π΅Ρ ΠΎΠΏΠΈΡΠ°Π½ΠΈΠ΅ ΠΈΡΡ ΠΎΠ΄ΡΡΠΈΡ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΉ gradle ΠΈ ΡΠ±ΠΎΡΠΊΡ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ³ΠΎ ΡΠ»ΠΎΡΠΎΠ² |
|
10 | * Binds materialized slot assemblies to Gradle outgoing publications. | |
| 11 | * ΠΈΠ· {@link ArtifactAssemblies} |
|
|||
| 12 | */ |
|
11 | */ | |
| 13 | @NonNullByDefault |
|
12 | @NonNullByDefault | |
| 14 | public class ArtifactAssemblyBinder implements Action<OutgoingVariant> { |
|
13 | public class ArtifactAssemblyBinder implements Action<OutgoingVariant> { | |
| @@ -25,28 +24,29 public class ArtifactAssemblyBinder impl | |||||
| 25 | var primarySlotProvider = outgoingVariant.getPrimarySlot(); |
|
24 | var primarySlotProvider = outgoingVariant.getPrimarySlot(); | |
| 26 | var variant = outgoingVariant.getVariant(); |
|
25 | var variant = outgoingVariant.getVariant(); | |
| 27 |
|
26 | |||
| 28 | // ΡΠ²ΡΠ·ΡΠ²Π°Π΅ΠΌ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ |
|
27 | // Bind publication state when the owning configuration is materialized. | |
| 29 | outgoingVariant.configureOutgoing(configuration -> { |
|
28 | outgoingVariant.configureOutgoing(configuration -> { | |
| 30 | var primarySlot = primarySlotProvider.get(); |
|
29 | var primarySlot = primarySlotProvider.get(); | |
| 31 | var outgoing = configuration.getOutgoing(); |
|
30 | var outgoing = configuration.getOutgoing(); | |
| 32 |
|
31 | |||
| 33 | // ΡΠ²ΡΠ·ΡΠ²Π°Π΅ΠΌ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ Π²Π°ΡΠΈΠ°Π½Ρ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ |
|
32 | // Bind the primary artifact set to the root outgoing configuration. | |
| 34 | resolver.when( |
|
33 | resolver.when( | |
| 35 | new ArtifactSlot(variant, primarySlot), |
|
34 | new ArtifactSlot(variant, primarySlot), | |
| 36 | assembly -> outgoing.artifact(assembly.getArtifact())); |
|
35 | assembly -> outgoing.artifact(assembly.getArtifact())); | |
| 37 |
|
36 | |||
| 38 | // Π΄Π»Ρ Π²ΡΠ΅Ρ ΠΎΠ±ΡΡΠ²Π»Π΅Π½Π½ΡΡ ΡΠ»ΠΎΡΠΎΠ² |
|
37 | // Bind non-primary slots to Gradle secondary artifact variants. | |
| 39 | slots.all(slot -> { |
|
38 | slots.all(slot -> { | |
| 40 | // ΠΊΡΠΎΠΌΠ΅ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠ³ΠΎ |
|
|||
| 41 | if (slot.equals(primarySlot)) |
|
39 | if (slot.equals(primarySlot)) | |
| 42 | return; |
|
40 | return; | |
| 43 |
|
41 | |||
| 44 | // ΡΠ²ΡΠ·ΡΠ²Π°Π΅ΠΌ Π°ΡΡΠ΅ΡΠ°ΠΊΡΡ |
|
|||
| 45 | resolver.when( |
|
42 | resolver.when( | |
| 46 | new ArtifactSlot(variant, slot), |
|
43 | new ArtifactSlot(variant, slot), | |
|
|
44 | // Gradle artifact variants must be created while the owning | |||
|
|
45 | // configuration is being materialized. Lazy registration may | |||
|
|
46 | // otherwise be realized only after dependency resolution starts. | |||
| 47 | assembly -> outgoing.getVariants() |
|
47 | assembly -> outgoing.getVariants() | |
| 48 |
. |
|
48 | .create(slot.getName()) | |
| 49 |
|
|
49 | .artifact(assembly.getArtifact())); | |
| 50 | }); |
|
50 | }); | |
| 51 | }); |
|
51 | }); | |
| 52 | } |
|
52 | } | |
| @@ -17,6 +17,7 import org.gradle.api.tasks.Sync; | |||||
| 17 | import org.gradle.api.tasks.TaskContainer; |
|
17 | import org.gradle.api.tasks.TaskContainer; | |
| 18 | import org.gradle.language.base.plugins.LifecycleBasePlugin; |
|
18 | import org.gradle.language.base.plugins.LifecycleBasePlugin; | |
| 19 | import org.implab.gradle.common.core.lang.FilePaths; |
|
19 | import org.implab.gradle.common.core.lang.FilePaths; | |
|
|
20 | import org.implab.gradle.variants.artifacts.ArtifactAssembly; | |||
| 20 | import org.implab.gradle.variants.artifacts.ArtifactAssemblySpec; |
|
21 | import org.implab.gradle.variants.artifacts.ArtifactAssemblySpec; | |
| 21 | import org.implab.gradle.variants.artifacts.ArtifactSlot; |
|
22 | import org.implab.gradle.variants.artifacts.ArtifactSlot; | |
| 22 | import org.implab.gradle.variants.sources.CompileUnit; |
|
23 | import org.implab.gradle.variants.sources.CompileUnit; | |
| @@ -25,26 +26,17 import org.implab.gradle.variants.source | |||||
| 25 | import org.implab.gradle.variants.sources.SourceSetMaterializer; |
|
26 | import org.implab.gradle.variants.sources.SourceSetMaterializer; | |
| 26 |
|
27 | |||
| 27 | /** |
|
28 | /** | |
| 28 | * ΠΠ΄Π°ΠΏΡΠ΅Ρ ΠΌΠ΅ΠΆΠ΄Ρ ΡΡΠ°Π³ΠΌΠ΅Π½ΡΠ°ΠΌΠΈ Π°ΡΡΠ΅ΡΠ°ΠΊΡΠΎΠ², ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½Π½ΡΠΌΠΈ Π² Π²ΠΈΠ΄Π΅ |
|
29 | * Adapts slot contribution declarations to materialized {@link ArtifactAssembly} | |
| 29 | * {@link SlotContribution}, |
|
30 | * handles. | |
| 30 | * ΠΈ ArtifactAssemblyRegistry, ΠΊΠΎΡΠΎΡΡΠΉ ΠΎΠΏΠ΅ΡΠΈΡΡΠ΅Ρ ΡΠΆΠ΅ ΡΠΎΠ±ΡΠ°Π½Π½ΡΠΌΠΈ |
|
|||
| 31 | * {@link ArtifactAssembly}. |
|
|||
| 32 | * |
|
31 | * | |
| 33 | * ΠΠ°Π½Π½ΡΠΉ ΠΊΠ»Π°ΡΡ ΠΎΡΠ²Π΅ΡΠ°Π΅Ρ Π·Π° ΡΠ±ΠΎΡΠΊΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΡ ΡΡΠ°Π³ΠΌΠ΅Π½ΡΠΎΠ² Π°ΡΡΠ΅ΡΠ°ΠΊΡΠΎΠ² Π² Π΅Π΄ΠΈΠ½ΡΠΉ |
|
32 | * <p>The handler creates one {@link Sync} task per {@link ArtifactSlot}. The task | |
| 34 | * ΠΊΠ°ΡΠ°Π»ΠΎΠ³, ΠΊΠΎΡΠΎΡΡΠΉ Π·Π°ΡΠ΅ΠΌ ΡΠ΅Π³ΠΈΡΡΡΠΈΡΡΠ΅ΡΡΡ Π² ArtifactAssemblyRegistry Π² Π²ΠΈΠ΄Π΅ |
|
33 | * copies all collected slot inputs into a single output directory. That output | |
| 35 | * {@link ArtifactAssembly}. Π‘Π±ΠΎΡΠΊΠ° ΠΊΠΎΠ½Π΅ΡΠ½ΠΎΠ³ΠΎ Π°ΡΡΠ΅ΡΠ°ΠΊΡΠ° ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ ΠΏΡΠΈ ΠΏΠΎΠΌΠΎΡΠΈ |
|
34 | * directory is then registered in {@link ArtifactAssemblyRegistry} as the | |
| 36 | * Π·Π°Π΄Π°ΡΠΈ, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΊΠΎΠΏΠΈΡΡΠ΅Ρ Π²ΡΠ΅ Π²Ρ ΠΎΠ΄Π½ΡΠ΅ ΡΠ°ΠΉΠ»Ρ Π² Π²ΡΡ ΠΎΠ΄Π½ΠΎΠΉ ΠΊΠ°ΡΠ°Π»ΠΎΠ³. ΠΠ°Π΄Π°ΡΠ° |
|
35 | * published artifact for the slot. | |
| 37 | * ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ {@link ArtifactSlot} ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ |
|
|||
| 38 | * {@link SlotAssembly#inputs()} ΠΊΠ°ΠΊ ΠΈΡΡΠΎΡΠ½ΠΈΠΊ Π²Ρ ΠΎΠ΄Π½ΡΡ Π΄Π°Π½Π½ΡΡ . |
|
|||
| 39 | * |
|
36 | * | |
| 40 | * ΠΠ»Ρ ΡΠ±ΠΎΡΠΊΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΏΠ°ΡΡΠ΅ΡΠ½ Visitor: ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΡΠ°Π³ΠΌΠ΅Π½Ρ Π°ΡΡΠ΅ΡΠ°ΠΊΡΠ° |
|
37 | * <p>Input collection uses {@link SlotContributionVisitor}. Each contribution is | |
| 41 | * ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ Π² Π²ΠΈΠ΄Π΅ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° {@link SlotContribution}, ΠΊΠΎΡΠΎΡΡΠΉ |
|
38 | * converted to a {@link SlotInputKey}; duplicate keys are ignored so that repeated | |
| 42 | * ΠΈΠΌΠ΅Π΅Ρ ΠΌΠ΅ΡΠΎΠ΄ accept, ΠΏΡΠΈΠ½ΠΈΠΌΠ°ΡΡΠΈΠΉ Visitor. |
|
39 | * topology-based selections do not add the same input twice. | |
| 43 | * Visitor ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ Π²ΠΎ Π²Π½ΡΡΡΠ΅Π½Π½Π΅ΠΌ ΠΊΠ»Π°ΡΡΠ΅ {@link ContributionVisitor}, ΠΊΠΎΡΠΎΡΡΠΉ |
|
|||
| 44 | * Π·Π½Π°Π΅Ρ, ΠΊΠ°ΠΊ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠΈΠΏ ΡΡΠ°Π³ΠΌΠ΅Π½ΡΠ° ΠΈ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ Π΅Π³ΠΎ Π² ΡΠ±ΠΎΡΠΊΡ. |
|
|||
| 45 | * ΠΠ»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ {@link SlotContribution} ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ ΠΊΠ»ΡΡ {@link SlotInputKey}, |
|
|||
| 46 | * ΠΊΠΎΡΠΎΡΡΠΉ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ Π΄Π΅Π΄ΡΠΏΠ»ΠΈΠΊΠ°ΡΠΈΠΈ: Π΅ΡΠ»ΠΈ ΡΡΠ°Π³ΠΌΠ΅Π½Ρ Ρ ΡΠ°ΠΊΠΈΠΌ ΠΆΠ΅ ΠΊΠ»ΡΡΠΎΠΌ ΡΠΆΠ΅ |
|
|||
| 47 | * Π±ΡΠ» Π΄ΠΎΠ±Π°Π²Π»Π΅Π½, ΡΠΎ ΠΎΠ½ ΠΈΠ³Π½ΠΎΡΠΈΡΡΠ΅ΡΡΡ. |
|
|||
| 48 | */ |
|
40 | */ | |
| 49 | @NonNullByDefault |
|
41 | @NonNullByDefault | |
| 50 | public class ArtifactAssemblyHandler { |
|
42 | public class ArtifactAssemblyHandler { | |
| @@ -97,9 +89,7 public class ArtifactAssemblyHandler { | |||||
| 97 | } |
|
89 | } | |
| 98 |
|
90 | |||
| 99 | /** |
|
91 | /** | |
| 100 | * Π‘ΠΎΠ·Π΄Π°Π΅Ρ ΡΠ±ΠΎΡΠΊΡ Π΄Π»Ρ ΡΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ ΡΠ»ΠΎΡΠ° Π°ΡΡΠ΅ΡΠ°ΠΊΡΠ°, ΡΠ±ΠΎΡΠΊΠ° ΡΠ΅Π³ΠΈΡΡΡΠΈΡΡΠ΅ΡΡΡ Π² |
|
92 | * Creates the assembly task for the given slot and registers its output artifact. | |
| 101 | * ArtifactAssemblyRegistry, Π΅ΡΠ»ΠΈ Π΄Π»Ρ ΡΠ»ΠΎΡΠ° ΡΠ±ΠΎΡΠΊΠ° ΡΠΆΠ΅ Π±ΡΠ»Π° Π·Π°ΡΠ΅Π³ΠΈΡΡΡΠΈΡΠΎΠ²Π°Π½Π° |
|
|||
| 102 | * ΠΊΠ΅ΠΌ-ΡΠΎ Π΅ΡΠ΅, ΡΠΎ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ ΠΎΡΠΈΠ±ΠΊΠ°. |
|
|||
| 103 | */ |
|
93 | */ | |
| 104 | private SlotAssembly createSlotAssembly(ArtifactSlot artifactSlot) { |
|
94 | private SlotAssembly createSlotAssembly(ArtifactSlot artifactSlot) { | |
| 105 | var assembly = new SlotAssembly(); |
|
95 | var assembly = new SlotAssembly(); | |
| @@ -135,13 +125,7 public class ArtifactAssemblyHandler { | |||||
| 135 | } |
|
125 | } | |
| 136 |
|
126 | |||
| 137 | /** |
|
127 | /** | |
| 138 | * Π‘ΠΎΠ±ΠΈΡΠ°Π΅Ρ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠ΅ ΡΡΠ°Π³ΠΌΠ΅Π½ΡΡ Π°ΡΡΠ΅ΡΠ°ΠΊΡΠΎΠ² Π² Π΅Π΄ΠΈΠ½ΡΠΉ ΠΈΡΡΠΎΡΠ½ΠΈΠΊ |
|
128 | * Collects slot contributions into one {@link ConfigurableFileCollection}. | |
| 139 | * {@link ConfigurableFileCollection}. |
|
|||
| 140 | * ΠΠ»Ρ ΡΡΠ°Π³ΠΌΠ΅Π½ΡΠΎΠ² {@link SlotContribution} ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌ Π΄Π΅Π΄ΡΠΏΠ»ΠΈΠΊΠ°ΡΠΈΠΈ: |
|
|||
| 141 | * Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ |
|
|||
| 142 | * Π²ΠΎΠ΄ΡΡΠ΅Π³ΠΎ ΡΡΠ°Π³ΠΌΠ΅Π½ΡΠ° ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ ΠΊΠ»ΡΡ {@link SlotInputKey} ΠΈ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡΡΡ |
|
|||
| 143 | * ΡΡΠ°Π³ΠΌΠ΅Π½ΡΡ ΡΠΎΠ»ΡΠΊΠΎ |
|
|||
| 144 | * Ρ ΡΠ½ΠΈΠΊΠ°Π»ΡΠ½ΡΠΌ ΠΊΠ»ΡΡΠΎΠΌ, ΠΏΠΎΠ²ΡΠΎΡΡ ΠΈΠ³Π½ΠΎΡΠΈΡΡΡΡΡΡ. |
|
|||
| 145 | */ |
|
129 | */ | |
| 146 | private class ContributionVisitor implements SlotContributionVisitor { |
|
130 | private class ContributionVisitor implements SlotContributionVisitor { | |
| 147 | // artifact slot for this assembly |
|
131 | // artifact slot for this assembly | |
| @@ -200,7 +184,7 public class ArtifactAssemblyHandler { | |||||
| 200 | } |
|
184 | } | |
| 201 | } |
|
185 | } | |
| 202 |
|
186 | |||
| 203 | /** Π‘ΠΎΡΡΠΎΡΠ½ΠΈΠ΅ Π΄Π»Ρ ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎΠ³ΠΎ ΡΠ»ΠΎΡΠ° */ |
|
187 | /** Mutable input state for one slot assembly. */ | |
| 204 | class SlotAssembly { |
|
188 | class SlotAssembly { | |
| 205 | private final ConfigurableFileCollection inputs = objects.fileCollection(); |
|
189 | private final ConfigurableFileCollection inputs = objects.fileCollection(); | |
| 206 | private final Set<SlotInputKey> seen = new HashSet<>(); |
|
190 | private final Set<SlotInputKey> seen = new HashSet<>(); | |
| @@ -15,10 +15,12 import org.implab.gradle.variants.core.R | |||||
| 15 | import org.implab.gradle.variants.artifacts.OutputSelectionSpec; |
|
15 | import org.implab.gradle.variants.artifacts.OutputSelectionSpec; | |
| 16 |
|
16 | |||
| 17 | /** |
|
17 | /** | |
| 18 | * Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ DSL ΠΌΠΎΠ΄Π΅Π»ΠΈ, ΡΡΡΠΎΠΈΡ Π½Π°Π±ΠΎΡ {@link SlotContribution}. ΠΡΠΈ ΠΏΠΎΡΡΡΠΎΠ΅Π½ΠΈΠΈ Π½Π°Π±ΠΎΡΠ° |
|
18 | * Default DSL facade for collecting {@link SlotContribution} declarations. | |
| 19 | * ΠΏΡΠ°Π²ΠΈΠ»Π° ΠΈ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎΡΡΡ Π½Π΅ ΠΏΡΠΎΠ²Π΅ΡΡΡΡΡΡ. ΠΠΎ ΠΎΠΊΠΎΠ½ΡΠ°Π½ΠΈΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΊΠ»ΠΈΠ΅Π½Ρ |
|
|||
| 20 | * Π²ΡΠ·ΡΠ²Π°Π΅Ρ ΠΌΠ΅ΡΠΎΠ΄ {@link #process(Consumer)} Π΄Π»Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠ². |
|
|||
| 21 | * |
|
19 | * | |
|
|
20 | * <p>The spec does not validate topology references immediately. It translates DSL | |||
|
|
21 | * calls to contribution objects and passes them to the supplied consumer; semantic | |||
|
|
22 | * validation happens later when the assembly handler resolves contributions | |||
|
|
23 | * against the finalized source model. | |||
| 22 | */ |
|
24 | */ | |
| 23 | @NonNullByDefault |
|
25 | @NonNullByDefault | |
| 24 | final class DefaultArtifactAssemblySpec implements ArtifactAssemblySpec { |
|
26 | final class DefaultArtifactAssemblySpec implements ArtifactAssemblySpec { | |
| @@ -4,11 +4,13 import org.eclipse.jdt.annotation.NonNul | |||||
| 4 | import org.gradle.api.Action; |
|
4 | import org.gradle.api.Action; | |
| 5 | import org.gradle.api.artifacts.Configuration; |
|
5 | import org.gradle.api.artifacts.Configuration; | |
| 6 | import org.gradle.api.attributes.AttributeContainer; |
|
6 | import org.gradle.api.attributes.AttributeContainer; | |
| 7 | import org.implab.gradle.internal.ReplayableQueue; |
|
7 | import org.gradle.api.model.ObjectFactory; | |
|
|
8 | import org.implab.gradle.common.core.lang.ReplayableQueue; | |||
| 8 | import org.implab.gradle.variants.artifacts.ArtifactSlot; |
|
9 | import org.implab.gradle.variants.artifacts.ArtifactSlot; | |
| 9 | import org.implab.gradle.variants.artifacts.OutgoingConfigurationSlotSpec; |
|
10 | import org.implab.gradle.variants.artifacts.OutgoingConfigurationSlotSpec; | |
| 10 | import org.implab.gradle.variants.artifacts.OutgoingConfigurationSpec; |
|
11 | import org.implab.gradle.variants.artifacts.OutgoingConfigurationSpec; | |
| 11 | import org.implab.gradle.variants.artifacts.OutgoingVariant; |
|
12 | import org.implab.gradle.variants.artifacts.OutgoingVariant; | |
|
|
13 | import org.implab.gradle.variants.artifacts.Slot; | |||
| 12 | import org.implab.gradle.variants.core.Variant; |
|
14 | import org.implab.gradle.variants.core.Variant; | |
| 13 |
|
15 | |||
| 14 | /** |
|
16 | /** | |
| @@ -32,17 +34,18 public class MaterializationPolicyHandle | |||||
| 32 |
|
34 | |||
| 33 | private final ReplayableQueue<OutgoingConfigurationSpec> variantMaterialization = new ReplayableQueue<>(); |
|
35 | private final ReplayableQueue<OutgoingConfigurationSpec> variantMaterialization = new ReplayableQueue<>(); | |
| 34 | private final ReplayableQueue<OutgoingConfigurationSlotSpec> slotMaterialization = new ReplayableQueue<>(); |
|
36 | private final ReplayableQueue<OutgoingConfigurationSlotSpec> slotMaterialization = new ReplayableQueue<>(); | |
|
|
37 | private final ObjectFactory objects; | |||
| 35 |
|
38 | |||
| 36 | public MaterializationPolicyHandler() { |
|
39 | public MaterializationPolicyHandler(ObjectFactory objects) { | |
|
|
40 | this.objects = objects; | |||
| 37 | } |
|
41 | } | |
| 38 |
|
42 | |||
| 39 | @Override |
|
43 | @Override | |
| 40 | public void execute(OutgoingVariant outgoingVariant) { |
|
44 | public void execute(OutgoingVariant outgoingVariant) { | |
| 41 | var slots = outgoingVariant.getSlots(); |
|
|||
| 42 | var primarySlotProvider = outgoingVariant.getPrimarySlot(); |
|
45 | var primarySlotProvider = outgoingVariant.getPrimarySlot(); | |
| 43 | var variant = outgoingVariant.getVariant(); |
|
46 | var variant = outgoingVariant.getVariant(); | |
| 44 |
|
47 | |||
| 45 | // ΡΠ²ΡΠ·ΡΠ²Π°Π΅ΠΌ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ |
|
48 | // Materialization hooks are attached to the owning outgoing configuration. | |
| 46 | outgoingVariant.configureOutgoing(configuration -> { |
|
49 | outgoingVariant.configureOutgoing(configuration -> { | |
| 47 | var primarySlot = primarySlotProvider.get(); |
|
50 | var primarySlot = primarySlotProvider.get(); | |
| 48 | var outgoing = configuration.getOutgoing(); |
|
51 | var outgoing = configuration.getOutgoing(); | |
| @@ -51,11 +54,13 public class MaterializationPolicyHandle | |||||
| 51 |
|
54 | |||
| 52 | slotMaterialized(new ArtifactSlot(variant, primarySlot), true, outgoing.getAttributes()); |
|
55 | slotMaterialized(new ArtifactSlot(variant, primarySlot), true, outgoing.getAttributes()); | |
| 53 |
|
56 | |||
| 54 | slots.forEach(slot -> { |
|
57 | // Slot publication hooks follow materialized Gradle artifact variants, | |
|
|
58 | // not the live slot identity view. | |||
|
|
59 | outgoing.getVariants().configureEach(variantConfiguration -> { | |||
|
|
60 | var slot = objects.named(Slot.class, variantConfiguration.getName()); | |||
| 55 | if (slot.equals(primarySlot)) |
|
61 | if (slot.equals(primarySlot)) | |
| 56 | return; |
|
62 | return; | |
| 57 |
|
63 | |||
| 58 | var variantConfiguration = outgoing.getVariants().getByName(slot.getName()); |
|
|||
| 59 | slotMaterialized(new ArtifactSlot(variant, slot), false, variantConfiguration.getAttributes()); |
|
64 | slotMaterialized(new ArtifactSlot(variant, slot), false, variantConfiguration.getAttributes()); | |
| 60 | }); |
|
65 | }); | |
| 61 | }); |
|
66 | }); | |
| @@ -18,7 +18,7 public class SingleSlotConvention implem | |||||
| 18 | var slots = outgoingVariant.getSlots(); |
|
18 | var slots = outgoingVariant.getSlots(); | |
| 19 |
|
19 | |||
| 20 | outgoingVariant.getPrimarySlot().convention( |
|
20 | outgoingVariant.getPrimarySlot().convention( | |
| 21 | // Π΅ΡΠ»ΠΈ Π΅ΡΡΡ ΡΠΎΠ²Π½ΠΎ ΠΎΠ΄ΠΈΠ½ ΡΠ»ΠΎΡ, ΡΠΎ ΠΎΠ½ ΡΡΠΈΡΠ°Π΅ΡΡΡ primary |
|
21 | // If exactly one slot is declared, it becomes the primary slot. | |
| 22 | providers.provider(() -> { |
|
22 | providers.provider(() -> { | |
| 23 | if (slots.size() == 0) |
|
23 | if (slots.size() == 0) | |
| 24 | throw new InvalidUserDataException("No slots declared for " + outgoingVariant.getVariant()); |
|
24 | throw new InvalidUserDataException("No slots declared for " + outgoingVariant.getVariant()); | |
| @@ -33,9 +33,8 | |||||
| 33 | * } |
|
33 | * } | |
| 34 | * }</pre> |
|
34 | * }</pre> | |
| 35 | * |
|
35 | * | |
| 36 | * <p>After finalization, slot identities can be observed through |
|
36 | * <p>After finalization, {@link org.implab.gradle.variants.artifacts.OutgoingVariant} exposes declared slot | |
| 37 | * {@link org.implab.gradle.variants.artifacts.OutgoingVariantsContext#getSlots()}, while slot bodies are |
|
37 | * identities through {@code getSlots()}, while slot bodies are obtained on demand through | |
| 38 | * obtained on demand through |
|
|||
| 39 | * {@link org.implab.gradle.variants.artifacts.OutgoingVariantsContext#getAssemblies()}. |
|
38 | * {@link org.implab.gradle.variants.artifacts.OutgoingVariantsContext#getAssemblies()}. | |
| 40 | */ |
|
39 | */ | |
| 41 | package org.implab.gradle.variants.artifacts; |
|
40 | package org.implab.gradle.variants.artifacts; | |
| @@ -103,6 +103,74 class VariantArtifactsPluginFunctionalTe | |||||
| 103 | } |
|
103 | } | |
| 104 |
|
104 | |||
| 105 | @Test |
|
105 | @Test | |
|
|
106 | void gradleReferenceRegisteredSecondaryArtifactVariantIsNotRealizedBeforeResolution() throws Exception { | |||
|
|
107 | // Gradle issue: https://github.com/gradle/gradle/issues/27441 | |||
|
|
108 | // Registered outgoing artifact variants are not realized before dependency resolution. | |||
|
|
109 | writeFile("settings.gradle", """ | |||
|
|
110 | rootProject.name = 'gradle-reference-registered-secondary-variant' | |||
|
|
111 | include 'producer', 'consumer' | |||
|
|
112 | """); | |||
|
|
113 | writeFile("producer/inputs/typesPackage", "types\n"); | |||
|
|
114 | writeFile("producer/inputs/js", "js\n"); | |||
|
|
115 | writeFile("build.gradle", """ | |||
|
|
116 | import org.gradle.api.attributes.Attribute | |||
|
|
117 | ||||
|
|
118 | def variantAttr = Attribute.of('test.variant', String) | |||
|
|
119 | def slotAttr = Attribute.of('test.slot', String) | |||
|
|
120 | ||||
|
|
121 | project(':producer') { | |||
|
|
122 | def browserElements = configurations.consumable('browserElements') | |||
|
|
123 | ||||
|
|
124 | browserElements.configure { configuration -> | |||
|
|
125 | configuration.attributes.attribute(variantAttr, 'browser') | |||
|
|
126 | configuration.outgoing.attributes.attribute(slotAttr, 'typesPackage') | |||
|
|
127 | configuration.outgoing.artifact(layout.projectDirectory.file('inputs/typesPackage')) | |||
|
|
128 | ||||
|
|
129 | configuration.outgoing.variants.register('js') { secondary -> | |||
|
|
130 | secondary.attributes.attribute(slotAttr, 'js') | |||
|
|
131 | secondary.artifact(layout.projectDirectory.file('inputs/js')) | |||
|
|
132 | } | |||
|
|
133 | } | |||
|
|
134 | } | |||
|
|
135 | ||||
|
|
136 | project(':consumer') { | |||
|
|
137 | configurations { | |||
|
|
138 | compileView { | |||
|
|
139 | canBeResolved = true | |||
|
|
140 | canBeConsumed = false | |||
|
|
141 | canBeDeclared = true | |||
|
|
142 | attributes { | |||
|
|
143 | attribute(variantAttr, 'browser') | |||
|
|
144 | attribute(slotAttr, 'typesPackage') | |||
|
|
145 | } | |||
|
|
146 | } | |||
|
|
147 | } | |||
|
|
148 | ||||
|
|
149 | dependencies { | |||
|
|
150 | compileView project(':producer') | |||
|
|
151 | } | |||
|
|
152 | ||||
|
|
153 | tasks.register('probe') { | |||
|
|
154 | doLast { | |||
|
|
155 | def compileFiles = configurations.compileView.files.collect { it.name }.sort().join(',') | |||
|
|
156 | def jsFiles = configurations.compileView.incoming.artifactView { | |||
|
|
157 | attributes { | |||
|
|
158 | attribute(slotAttr, 'js') | |||
|
|
159 | } | |||
|
|
160 | }.files.files.collect { it.name }.sort().join(',') | |||
|
|
161 | ||||
|
|
162 | println('compileFiles=' + compileFiles) | |||
|
|
163 | println('jsFiles=' + jsFiles) | |||
|
|
164 | } | |||
|
|
165 | } | |||
|
|
166 | } | |||
|
|
167 | """); | |||
|
|
168 | ||||
|
|
169 | assertBuildFails("Cannot create variant 'js' after dependency configuration ':producer:browserElements' has been resolved", | |||
|
|
170 | ":consumer:probe"); | |||
|
|
171 | } | |||
|
|
172 | ||||
|
|
173 | @Test | |||
| 106 | void materializesPrimaryAndSecondarySlotsAndInvokesOutgoingHooks() throws Exception { |
|
174 | void materializesPrimaryAndSecondarySlotsAndInvokesOutgoingHooks() throws Exception { | |
| 107 | writeSettings("variant-artifacts-slots"); |
|
175 | writeSettings("variant-artifacts-slots"); | |
| 108 | writeFile("inputs/base.js", "console.log('base')\n"); |
|
176 | writeFile("inputs/base.js", "console.log('base')\n"); | |
| @@ -207,6 +275,66 class VariantArtifactsPluginFunctionalTe | |||||
| 207 | } |
|
275 | } | |
| 208 |
|
276 | |||
| 209 | @Test |
|
277 | @Test | |
|
|
278 | void outgoingSlotHookFollowsMaterializedGradleArtifactVariants() throws Exception { | |||
|
|
279 | writeSettings("variant-artifacts-materialized-gradle-variant"); | |||
|
|
280 | writeFile("inputs/typesPackage", "types\n"); | |||
|
|
281 | writeFile("inputs/js", "js\n"); | |||
|
|
282 | writeBuildFile(""" | |||
|
|
283 | import org.gradle.api.attributes.Attribute | |||
|
|
284 | ||||
|
|
285 | apply plugin: org.implab.gradle.variants.VariantArtifactsPlugin | |||
|
|
286 | ||||
|
|
287 | def slotAttr = Attribute.of('test.slot', String) | |||
|
|
288 | ||||
|
|
289 | variants.layers.create('main') | |||
|
|
290 | variants.roles.create('main') | |||
|
|
291 | variants.variant('browser') { | |||
|
|
292 | role('main') { | |||
|
|
293 | layers('main') | |||
|
|
294 | } | |||
|
|
295 | } | |||
|
|
296 | ||||
|
|
297 | variantArtifacts { | |||
|
|
298 | variant('browser') { | |||
|
|
299 | primarySlot('typesPackage') { | |||
|
|
300 | from(layout.projectDirectory.file('inputs/typesPackage')) | |||
|
|
301 | } | |||
|
|
302 | } | |||
|
|
303 | ||||
|
|
304 | whenOutgoingConfiguration { publication -> | |||
|
|
305 | publication.configuration { | |||
|
|
306 | outgoing.variants.create('js') { secondary -> | |||
|
|
307 | secondary.artifact(layout.projectDirectory.file('inputs/js')) | |||
|
|
308 | } | |||
|
|
309 | } | |||
|
|
310 | } | |||
|
|
311 | ||||
|
|
312 | whenOutgoingSlot { publication -> | |||
|
|
313 | publication.artifactAttributes { | |||
|
|
314 | attribute(slotAttr, publication.artifactSlot.slot.name) | |||
|
|
315 | } | |||
|
|
316 | } | |||
|
|
317 | } | |||
|
|
318 | ||||
|
|
319 | tasks.register('probe') { | |||
|
|
320 | doLast { | |||
|
|
321 | def elements = configurations.getByName('browserElements') | |||
|
|
322 | def jsVariant = elements.outgoing.variants.getByName('js') | |||
|
|
323 | ||||
|
|
324 | println('primarySlotAttr=' + elements.outgoing.attributes.getAttribute(slotAttr)) | |||
|
|
325 | println('jsSlotAttr=' + jsVariant.attributes.getAttribute(slotAttr)) | |||
|
|
326 | } | |||
|
|
327 | } | |||
|
|
328 | """); | |||
|
|
329 | ||||
|
|
330 | BuildResult result = runner("probe").build(); | |||
|
|
331 | ||||
|
|
332 | assertTrue(result.getOutput().contains("primarySlotAttr=typesPackage")); | |||
|
|
333 | assertTrue(result.getOutput().contains("jsSlotAttr=js")); | |||
|
|
334 | assertTrue(result.task(":probe").getOutcome() == TaskOutcome.SUCCESS); | |||
|
|
335 | } | |||
|
|
336 | ||||
|
|
337 | @Test | |||
| 210 | void allowsSingleSlotVariantWithoutExplicitPrimarySlot() throws Exception { |
|
338 | void allowsSingleSlotVariantWithoutExplicitPrimarySlot() throws Exception { | |
| 211 | writeSettings("variant-artifacts-single-slot"); |
|
339 | writeSettings("variant-artifacts-single-slot"); | |
| 212 | writeBuildFile(""" |
|
340 | writeBuildFile(""" | |
General Comments 0
You need to be logged in to leave comments.
Login now
