| @@ -49,7 +49,7 public abstract class VariantArtifactsPl | |||
|
|
49 | 49 | // wire artifact assemblies to configuration variants |
|
|
50 | 50 | var assembliesBridge = new ArtifactAssemblyBinder(assemblies); |
|
|
51 | 51 | var primarySlotConvention = new SingleSlotConvention(providers); |
|
|
52 | var materializationHandler = new MaterializationPolicyHandler(); | |
|
|
52 | var materializationHandler = new MaterializationPolicyHandler(objects); | |
|
|
53 | 53 | |
|
|
54 | 54 | // bind slot assemblies to outgoing variants |
|
|
55 | 55 | outgoing.configureEach(assembliesBridge::execute); |
| @@ -51,6 +51,11 public interface ArtifactAssemblies { | |||
|
|
51 | 51 | */ |
|
|
52 | 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 | 60 | Optional<ArtifactAssembly> find(ArtifactSlot slot); |
|
|
56 | 61 | } |
| @@ -11,7 +11,7 import groovy.lang.Closure; | |||
|
|
11 | 11 | * Materialized root outgoing configuration of a variant. |
|
|
12 | 12 | * |
|
|
13 | 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 | 16 | public interface OutgoingConfigurationSpec { |
|
|
17 | 17 | /** |
| @@ -8,43 +8,56 import org.gradle.api.provider.Property; | |||
|
|
8 | 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 ΡΠ΅ΡΠ΅Π· | |
|
|
14 | * ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ {@link #getConfiguration()}. Π’Π°ΠΊΠΆΠ΅ Π·Π°Π΄Π°Π΅Ρ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΡ ΠΎΡΡ ΡΠ»ΠΎΡΠΎΠ² | |
|
|
15 | * ΠΏΡΠ±Π»ΠΈΠΊΠ°ΡΠΈΠΈ, Π½ΠΎ Π½Π΅ Π·Π°Π΄Π°Π΅Ρ ΠΏΡΠ°Π²ΠΈΠ» ΡΠ²ΡΠ·ΡΠ²Π°Π½ΠΈΡ ΡΡΠΈΡ ΡΠ»ΠΎΡΠΎΠ² Ρ ΡΠ°ΠΌΠΎΠΉ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠ΅ΠΉ | |
|
|
16 | * ΠΈ ΠΈΡ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΡΠΌ. Π‘Π°ΠΌΡΠΉ ΠΏΡΠΎΡΡΠΎΠΉ Π²Π°ΡΠΈΠ°Π½Ρ ΡΡΠΎ {@link ArtifactAssemblies}. | |
|
|
13 | * <p>An outgoing variant connects a core {@link Variant} identity with the lazy | |
|
|
14 | * Gradle consumable configuration registered for that variant. It also exposes a | |
|
|
15 | * live container of slot identities. Slot identities are only declarations and do | |
|
|
16 | * not imply that a Gradle outgoing artifact variant or an {@link ArtifactAssembly} | |
|
|
17 | * has been materialized. | |
|
|
17 | 18 | */ |
|
|
18 | 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 | 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 | 32 | NamedDomainObjectProvider<? extends Configuration> getConfiguration(); |
|
|
28 | 33 | |
|
|
34 | /** | |
|
|
35 | * Configures the registered outgoing configuration. | |
|
|
36 | * | |
|
|
37 | * @param action configuration action | |
|
|
38 | */ | |
|
|
29 | 39 | default void configureOutgoing(Action<? super Configuration> action) { |
|
|
30 | 40 | getConfiguration().configure(action); |
|
|
31 | 41 | } |
|
|
32 | 42 | |
|
|
33 | 43 | /** |
|
|
34 | * Π‘Π»ΠΎΡΡ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ, Π΄Π°Π½Π½Π°Ρ ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΡ ΠΆΠΈΠ²Π°Ρ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ | |
|
|
35 | * ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΈ ΠΎΠ± ΠΎΠ±ΡΡΠ²Π»Π΅Π½Π½ΡΡ ΡΠ»ΠΎΡΠ°Ρ , Π½ΠΎ ΡΡΠΈ ΡΠ»ΠΎΡΡ Π½Π΅ | |
|
|
36 | * ΠΎΠ±ΡΠ·Π°Π½Ρ Π±ΡΡΡ ΡΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠΈΡΠΎΠ²Π°Π½Ρ, Ρ.Π΅. ΡΡΠΎ ΡΠΎΠ»ΡΠΊΠΎ Identity. | |
|
|
44 | * Returns the live slot identity container. | |
|
|
45 | * | |
|
|
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 | 50 | * @see {@link ArtifactSlot} |
|
|
39 | 51 | */ |
|
|
40 | 52 | NamedDomainObjectContainer<Slot> getSlots(); |
|
|
41 | 53 | |
|
|
42 | 54 | /** |
|
|
43 | * ΠΡΠ½ΠΎΠ²Π½ΠΎΠΉ Π½Π°Π±ΠΎΡ Π°ΡΡΠ΅ΡΠ°ΠΊΡΠΎΠ² (primary variant) Π΄Π»Ρ ΠΈΡΡ ΠΎΠ΄ΡΡΠ΅ΠΉ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ | |
|
|
55 | * Returns the primary slot property. | |
|
|
44 | 56 | * |
|
|
45 | * <p> | |
|
|
46 | * ΠΡΠ»ΠΈ Π² ΡΠ²ΠΎΠΉΡΡΠ²Π΅ {@link #getSlots()} Π΅ΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΡΠ»ΠΎΠΉ, ΡΠΎ ΠΏΠΎ ΠΊΠΎΠ½Π²Π΅Π½ΡΠΈΠΈ ΠΎΠ½ | |
|
|
47 | * ΡΡΠΈΡΠ°Π΅ΡΡΡ ΡΠ°ΠΊΠΆΠ΅ ΠΎΡΠ½ΠΎΠ²Π½ΡΠΌ. | |
|
|
57 | * <p>If exactly one slot is declared, the single-slot convention uses that slot as | |
|
|
58 | * the primary one. Reading this property finalizes the selected primary slot. | |
|
|
59 | * | |
|
|
60 | * @return primary slot property | |
|
|
48 | 61 | */ |
|
|
49 | 62 | Property<Slot> getPrimarySlot(); |
|
|
50 | 63 | } |
| @@ -7,29 +7,80 import org.gradle.api.InvalidUserDataExc | |||
|
|
7 | 7 | import org.implab.gradle.variants.core.Variant; |
|
|
8 | 8 | |
|
|
9 | 9 | /** |
|
|
10 | * ΠΠΎΠ½ΡΠ΅ΠΊΡΡ ΡΠ°Π±ΠΎΡΡ Ρ Π²Π°ΡΠΈΠ°Π½ΡΠ°ΠΌΠΈ ΠΏΡΠ±Π»ΠΈΠΊΠ°ΡΠΈΠΈ, ΡΡΠ°Π½ΠΎΠ²ΠΈΡΡΡ Π΄ΠΎΡΡΡΠΏΠ½ΡΠΌ ΠΏΠΎΡΠ»Π΅ | |
|
|
11 | * ΡΠΈΠ½Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΌΠΎΠ΄Π΅Π»ΠΈ Π²Π°ΡΠΈΠ°Π½ΡΠΎΠ². Π€Π°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΆΠΈΠ²ΠΎΠΉ ΠΌΠΎΠ΄Π΅Π»ΡΡ | |
|
|
10 | * Live context for declaring and observing variant outgoing publications. | |
|
|
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 | 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 | 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 | 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 | 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 | 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 | 62 | default OutgoingVariant requireOutgoing(Variant variant) { |
|
|
27 | 63 | return findOutgoing(variant) |
|
|
28 | 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 | 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 | 84 | void whenOutgoingSlot(Action<? super OutgoingConfigurationSlotSpec> action); |
|
|
34 | 85 | |
|
|
35 | 86 | |
| @@ -17,7 +17,6 public interface VariantArtifactsSpec { | |||
|
|
17 | 17 | * |
|
|
18 | 18 | * @param name slot name |
|
|
19 | 19 | * @param action slot declaration |
|
|
20 | * @return slot identity | |
|
|
21 | 20 | */ |
|
|
22 | 21 | void slot(String name, Action<? super ArtifactAssemblySpec> action); |
|
|
23 | 22 | |
| @@ -30,7 +29,6 public interface VariantArtifactsSpec { | |||
|
|
30 | 29 | * |
|
|
31 | 30 | * @param name slot name |
|
|
32 | 31 | * @param action slot declaration |
|
|
33 | * @return slot identity | |
|
|
34 | 32 | */ |
|
|
35 | 33 | void primarySlot(String name, Action<? super ArtifactAssemblySpec> action); |
|
|
36 | 34 | |
| @@ -7,8 +7,7 import org.implab.gradle.variants.artifa | |||
|
|
7 | 7 | import org.implab.gradle.variants.artifacts.OutgoingVariant; |
|
|
8 | 8 | |
|
|
9 | 9 | /** |
|
|
10 | * Π‘Π²ΡΠ·ΡΠ²Π°Π΅Ρ ΠΎΠΏΠΈΡΠ°Π½ΠΈΠ΅ ΠΈΡΡ ΠΎΠ΄ΡΡΠΈΡ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΉ gradle ΠΈ ΡΠ±ΠΎΡΠΊΡ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ³ΠΎ ΡΠ»ΠΎΡΠΎΠ² | |
|
|
11 | * ΠΈΠ· {@link ArtifactAssemblies} | |
|
|
10 | * Binds materialized slot assemblies to Gradle outgoing publications. | |
|
|
12 | 11 | */ |
|
|
13 | 12 | @NonNullByDefault |
|
|
14 | 13 | public class ArtifactAssemblyBinder implements Action<OutgoingVariant> { |
| @@ -25,28 +24,29 public class ArtifactAssemblyBinder impl | |||
|
|
25 | 24 | var primarySlotProvider = outgoingVariant.getPrimarySlot(); |
|
|
26 | 25 | var variant = outgoingVariant.getVariant(); |
|
|
27 | 26 | |
|
|
28 | // ΡΠ²ΡΠ·ΡΠ²Π°Π΅ΠΌ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ | |
|
|
27 | // Bind publication state when the owning configuration is materialized. | |
|
|
29 | 28 | outgoingVariant.configureOutgoing(configuration -> { |
|
|
30 | 29 | var primarySlot = primarySlotProvider.get(); |
|
|
31 | 30 | var outgoing = configuration.getOutgoing(); |
|
|
32 | 31 | |
|
|
33 | // ΡΠ²ΡΠ·ΡΠ²Π°Π΅ΠΌ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ Π²Π°ΡΠΈΠ°Π½Ρ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ | |
|
|
32 | // Bind the primary artifact set to the root outgoing configuration. | |
|
|
34 | 33 | resolver.when( |
|
|
35 | 34 | new ArtifactSlot(variant, primarySlot), |
|
|
36 | 35 | assembly -> outgoing.artifact(assembly.getArtifact())); |
|
|
37 | 36 | |
|
|
38 | // Π΄Π»Ρ Π²ΡΠ΅Ρ ΠΎΠ±ΡΡΠ²Π»Π΅Π½Π½ΡΡ ΡΠ»ΠΎΡΠΎΠ² | |
|
|
37 | // Bind non-primary slots to Gradle secondary artifact variants. | |
|
|
39 | 38 | slots.all(slot -> { |
|
|
40 | // ΠΊΡΠΎΠΌΠ΅ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠ³ΠΎ | |
|
|
41 | 39 | if (slot.equals(primarySlot)) |
|
|
42 | 40 | return; |
|
|
43 | 41 | |
|
|
44 | // ΡΠ²ΡΠ·ΡΠ²Π°Π΅ΠΌ Π°ΡΡΠ΅ΡΠ°ΠΊΡΡ | |
|
|
45 | 42 | resolver.when( |
|
|
46 | 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 | 47 | assembly -> outgoing.getVariants() |
|
|
48 |
. |
|
|
|
49 |
|
|
|
|
48 | .create(slot.getName()) | |
|
|
49 | .artifact(assembly.getArtifact())); | |
|
|
50 | 50 | }); |
|
|
51 | 51 | }); |
|
|
52 | 52 | } |
| @@ -17,6 +17,7 import org.gradle.api.tasks.Sync; | |||
|
|
17 | 17 | import org.gradle.api.tasks.TaskContainer; |
|
|
18 | 18 | import org.gradle.language.base.plugins.LifecycleBasePlugin; |
|
|
19 | 19 | import org.implab.gradle.common.core.lang.FilePaths; |
|
|
20 | import org.implab.gradle.variants.artifacts.ArtifactAssembly; | |
|
|
20 | 21 | import org.implab.gradle.variants.artifacts.ArtifactAssemblySpec; |
|
|
21 | 22 | import org.implab.gradle.variants.artifacts.ArtifactSlot; |
|
|
22 | 23 | import org.implab.gradle.variants.sources.CompileUnit; |
| @@ -25,26 +26,17 import org.implab.gradle.variants.source | |||
|
|
25 | 26 | import org.implab.gradle.variants.sources.SourceSetMaterializer; |
|
|
26 | 27 | |
|
|
27 | 28 | /** |
|
|
28 | * ΠΠ΄Π°ΠΏΡΠ΅Ρ ΠΌΠ΅ΠΆΠ΄Ρ ΡΡΠ°Π³ΠΌΠ΅Π½ΡΠ°ΠΌΠΈ Π°ΡΡΠ΅ΡΠ°ΠΊΡΠΎΠ², ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½Π½ΡΠΌΠΈ Π² Π²ΠΈΠ΄Π΅ | |
|
|
29 | * {@link SlotContribution}, | |
|
|
30 | * ΠΈ ArtifactAssemblyRegistry, ΠΊΠΎΡΠΎΡΡΠΉ ΠΎΠΏΠ΅ΡΠΈΡΡΠ΅Ρ ΡΠΆΠ΅ ΡΠΎΠ±ΡΠ°Π½Π½ΡΠΌΠΈ | |
|
|
31 | * {@link ArtifactAssembly}. | |
|
|
29 | * Adapts slot contribution declarations to materialized {@link ArtifactAssembly} | |
|
|
30 | * handles. | |
|
|
32 | 31 | * |
|
|
33 | * ΠΠ°Π½Π½ΡΠΉ ΠΊΠ»Π°ΡΡ ΠΎΡΠ²Π΅ΡΠ°Π΅Ρ Π·Π° ΡΠ±ΠΎΡΠΊΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΡ ΡΡΠ°Π³ΠΌΠ΅Π½ΡΠΎΠ² Π°ΡΡΠ΅ΡΠ°ΠΊΡΠΎΠ² Π² Π΅Π΄ΠΈΠ½ΡΠΉ | |
|
|
34 | * ΠΊΠ°ΡΠ°Π»ΠΎΠ³, ΠΊΠΎΡΠΎΡΡΠΉ Π·Π°ΡΠ΅ΠΌ ΡΠ΅Π³ΠΈΡΡΡΠΈΡΡΠ΅ΡΡΡ Π² ArtifactAssemblyRegistry Π² Π²ΠΈΠ΄Π΅ | |
|
|
35 | * {@link ArtifactAssembly}. Π‘Π±ΠΎΡΠΊΠ° ΠΊΠΎΠ½Π΅ΡΠ½ΠΎΠ³ΠΎ Π°ΡΡΠ΅ΡΠ°ΠΊΡΠ° ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ ΠΏΡΠΈ ΠΏΠΎΠΌΠΎΡΠΈ | |
|
|
36 | * Π·Π°Π΄Π°ΡΠΈ, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΊΠΎΠΏΠΈΡΡΠ΅Ρ Π²ΡΠ΅ Π²Ρ ΠΎΠ΄Π½ΡΠ΅ ΡΠ°ΠΉΠ»Ρ Π² Π²ΡΡ ΠΎΠ΄Π½ΠΎΠΉ ΠΊΠ°ΡΠ°Π»ΠΎΠ³. ΠΠ°Π΄Π°ΡΠ° | |
|
|
37 | * ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ {@link ArtifactSlot} ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ | |
|
|
38 | * {@link SlotAssembly#inputs()} ΠΊΠ°ΠΊ ΠΈΡΡΠΎΡΠ½ΠΈΠΊ Π²Ρ ΠΎΠ΄Π½ΡΡ Π΄Π°Π½Π½ΡΡ . | |
|
|
32 | * <p>The handler creates one {@link Sync} task per {@link ArtifactSlot}. The task | |
|
|
33 | * copies all collected slot inputs into a single output directory. That output | |
|
|
34 | * directory is then registered in {@link ArtifactAssemblyRegistry} as the | |
|
|
35 | * published artifact for the slot. | |
|
|
39 | 36 | * |
|
|
40 | * ΠΠ»Ρ ΡΠ±ΠΎΡΠΊΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΏΠ°ΡΡΠ΅ΡΠ½ Visitor: ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΡΠ°Π³ΠΌΠ΅Π½Ρ Π°ΡΡΠ΅ΡΠ°ΠΊΡΠ° | |
|
|
41 | * ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ Π² Π²ΠΈΠ΄Π΅ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° {@link SlotContribution}, ΠΊΠΎΡΠΎΡΡΠΉ | |
|
|
42 | * ΠΈΠΌΠ΅Π΅Ρ ΠΌΠ΅ΡΠΎΠ΄ accept, ΠΏΡΠΈΠ½ΠΈΠΌΠ°ΡΡΠΈΠΉ Visitor. | |
|
|
43 | * Visitor ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ Π²ΠΎ Π²Π½ΡΡΡΠ΅Π½Π½Π΅ΠΌ ΠΊΠ»Π°ΡΡΠ΅ {@link ContributionVisitor}, ΠΊΠΎΡΠΎΡΡΠΉ | |
|
|
44 | * Π·Π½Π°Π΅Ρ, ΠΊΠ°ΠΊ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠΈΠΏ ΡΡΠ°Π³ΠΌΠ΅Π½ΡΠ° ΠΈ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ Π΅Π³ΠΎ Π² ΡΠ±ΠΎΡΠΊΡ. | |
|
|
45 | * ΠΠ»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ {@link SlotContribution} ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ ΠΊΠ»ΡΡ {@link SlotInputKey}, | |
|
|
46 | * ΠΊΠΎΡΠΎΡΡΠΉ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ Π΄Π΅Π΄ΡΠΏΠ»ΠΈΠΊΠ°ΡΠΈΠΈ: Π΅ΡΠ»ΠΈ ΡΡΠ°Π³ΠΌΠ΅Π½Ρ Ρ ΡΠ°ΠΊΠΈΠΌ ΠΆΠ΅ ΠΊΠ»ΡΡΠΎΠΌ ΡΠΆΠ΅ | |
|
|
47 | * Π±ΡΠ» Π΄ΠΎΠ±Π°Π²Π»Π΅Π½, ΡΠΎ ΠΎΠ½ ΠΈΠ³Π½ΠΎΡΠΈΡΡΠ΅ΡΡΡ. | |
|
|
37 | * <p>Input collection uses {@link SlotContributionVisitor}. Each contribution is | |
|
|
38 | * converted to a {@link SlotInputKey}; duplicate keys are ignored so that repeated | |
|
|
39 | * topology-based selections do not add the same input twice. | |
|
|
48 | 40 | */ |
|
|
49 | 41 | @NonNullByDefault |
|
|
50 | 42 | public class ArtifactAssemblyHandler { |
| @@ -97,9 +89,7 public class ArtifactAssemblyHandler { | |||
|
|
97 | 89 | } |
|
|
98 | 90 | |
|
|
99 | 91 | /** |
|
|
100 | * Π‘ΠΎΠ·Π΄Π°Π΅Ρ ΡΠ±ΠΎΡΠΊΡ Π΄Π»Ρ ΡΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ ΡΠ»ΠΎΡΠ° Π°ΡΡΠ΅ΡΠ°ΠΊΡΠ°, ΡΠ±ΠΎΡΠΊΠ° ΡΠ΅Π³ΠΈΡΡΡΠΈΡΡΠ΅ΡΡΡ Π² | |
|
|
101 | * ArtifactAssemblyRegistry, Π΅ΡΠ»ΠΈ Π΄Π»Ρ ΡΠ»ΠΎΡΠ° ΡΠ±ΠΎΡΠΊΠ° ΡΠΆΠ΅ Π±ΡΠ»Π° Π·Π°ΡΠ΅Π³ΠΈΡΡΡΠΈΡΠΎΠ²Π°Π½Π° | |
|
|
102 | * ΠΊΠ΅ΠΌ-ΡΠΎ Π΅ΡΠ΅, ΡΠΎ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ ΠΎΡΠΈΠ±ΠΊΠ°. | |
|
|
92 | * Creates the assembly task for the given slot and registers its output artifact. | |
|
|
103 | 93 | */ |
|
|
104 | 94 | private SlotAssembly createSlotAssembly(ArtifactSlot artifactSlot) { |
|
|
105 | 95 | var assembly = new SlotAssembly(); |
| @@ -135,13 +125,7 public class ArtifactAssemblyHandler { | |||
|
|
135 | 125 | } |
|
|
136 | 126 | |
|
|
137 | 127 | /** |
|
|
138 | * Π‘ΠΎΠ±ΠΈΡΠ°Π΅Ρ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠ΅ ΡΡΠ°Π³ΠΌΠ΅Π½ΡΡ Π°ΡΡΠ΅ΡΠ°ΠΊΡΠΎΠ² Π² Π΅Π΄ΠΈΠ½ΡΠΉ ΠΈΡΡΠΎΡΠ½ΠΈΠΊ | |
|
|
139 | * {@link ConfigurableFileCollection}. | |
|
|
140 | * ΠΠ»Ρ ΡΡΠ°Π³ΠΌΠ΅Π½ΡΠΎΠ² {@link SlotContribution} ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌ Π΄Π΅Π΄ΡΠΏΠ»ΠΈΠΊΠ°ΡΠΈΠΈ: | |
|
|
141 | * Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ | |
|
|
142 | * Π²ΠΎΠ΄ΡΡΠ΅Π³ΠΎ ΡΡΠ°Π³ΠΌΠ΅Π½ΡΠ° ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ ΠΊΠ»ΡΡ {@link SlotInputKey} ΠΈ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡΡΡ | |
|
|
143 | * ΡΡΠ°Π³ΠΌΠ΅Π½ΡΡ ΡΠΎΠ»ΡΠΊΠΎ | |
|
|
144 | * Ρ ΡΠ½ΠΈΠΊΠ°Π»ΡΠ½ΡΠΌ ΠΊΠ»ΡΡΠΎΠΌ, ΠΏΠΎΠ²ΡΠΎΡΡ ΠΈΠ³Π½ΠΎΡΠΈΡΡΡΡΡΡ. | |
|
|
128 | * Collects slot contributions into one {@link ConfigurableFileCollection}. | |
|
|
145 | 129 | */ |
|
|
146 | 130 | private class ContributionVisitor implements SlotContributionVisitor { |
|
|
147 | 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 | 188 | class SlotAssembly { |
|
|
205 | 189 | private final ConfigurableFileCollection inputs = objects.fileCollection(); |
|
|
206 | 190 | private final Set<SlotInputKey> seen = new HashSet<>(); |
| @@ -15,10 +15,12 import org.implab.gradle.variants.core.R | |||
|
|
15 | 15 | import org.implab.gradle.variants.artifacts.OutputSelectionSpec; |
|
|
16 | 16 | |
|
|
17 | 17 | /** |
|
|
18 | * Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ DSL ΠΌΠΎΠ΄Π΅Π»ΠΈ, ΡΡΡΠΎΠΈΡ Π½Π°Π±ΠΎΡ {@link SlotContribution}. ΠΡΠΈ ΠΏΠΎΡΡΡΠΎΠ΅Π½ΠΈΠΈ Π½Π°Π±ΠΎΡΠ° | |
|
|
19 | * ΠΏΡΠ°Π²ΠΈΠ»Π° ΠΈ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎΡΡΡ Π½Π΅ ΠΏΡΠΎΠ²Π΅ΡΡΡΡΡΡ. ΠΠΎ ΠΎΠΊΠΎΠ½ΡΠ°Π½ΠΈΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΊΠ»ΠΈΠ΅Π½Ρ | |
|
|
20 | * Π²ΡΠ·ΡΠ²Π°Π΅Ρ ΠΌΠ΅ΡΠΎΠ΄ {@link #process(Consumer)} Π΄Π»Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠΎΠ². | |
|
|
18 | * Default DSL facade for collecting {@link SlotContribution} declarations. | |
|
|
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 | 25 | @NonNullByDefault |
|
|
24 | 26 | final class DefaultArtifactAssemblySpec implements ArtifactAssemblySpec { |
| @@ -4,11 +4,13 import org.eclipse.jdt.annotation.NonNul | |||
|
|
4 | 4 | import org.gradle.api.Action; |
|
|
5 | 5 | import org.gradle.api.artifacts.Configuration; |
|
|
6 | 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 | 9 | import org.implab.gradle.variants.artifacts.ArtifactSlot; |
|
|
9 | 10 | import org.implab.gradle.variants.artifacts.OutgoingConfigurationSlotSpec; |
|
|
10 | 11 | import org.implab.gradle.variants.artifacts.OutgoingConfigurationSpec; |
|
|
11 | 12 | import org.implab.gradle.variants.artifacts.OutgoingVariant; |
|
|
13 | import org.implab.gradle.variants.artifacts.Slot; | |
|
|
12 | 14 | import org.implab.gradle.variants.core.Variant; |
|
|
13 | 15 | |
|
|
14 | 16 | /** |
| @@ -32,17 +34,18 public class MaterializationPolicyHandle | |||
|
|
32 | 34 | |
|
|
33 | 35 | private final ReplayableQueue<OutgoingConfigurationSpec> variantMaterialization = new ReplayableQueue<>(); |
|
|
34 | 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 | 43 | @Override |
|
|
40 | 44 | public void execute(OutgoingVariant outgoingVariant) { |
|
|
41 | var slots = outgoingVariant.getSlots(); | |
|
|
42 | 45 | var primarySlotProvider = outgoingVariant.getPrimarySlot(); |
|
|
43 | 46 | var variant = outgoingVariant.getVariant(); |
|
|
44 | 47 | |
|
|
45 | // ΡΠ²ΡΠ·ΡΠ²Π°Π΅ΠΌ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ | |
|
|
48 | // Materialization hooks are attached to the owning outgoing configuration. | |
|
|
46 | 49 | outgoingVariant.configureOutgoing(configuration -> { |
|
|
47 | 50 | var primarySlot = primarySlotProvider.get(); |
|
|
48 | 51 | var outgoing = configuration.getOutgoing(); |
| @@ -51,11 +54,13 public class MaterializationPolicyHandle | |||
|
|
51 | 54 | |
|
|
52 | 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 | 61 | if (slot.equals(primarySlot)) |
|
|
56 | 62 | return; |
|
|
57 | 63 | |
|
|
58 | var variantConfiguration = outgoing.getVariants().getByName(slot.getName()); | |
|
|
59 | 64 | slotMaterialized(new ArtifactSlot(variant, slot), false, variantConfiguration.getAttributes()); |
|
|
60 | 65 | }); |
|
|
61 | 66 | }); |
| @@ -18,7 +18,7 public class SingleSlotConvention implem | |||
|
|
18 | 18 | var slots = outgoingVariant.getSlots(); |
|
|
19 | 19 | |
|
|
20 | 20 | outgoingVariant.getPrimarySlot().convention( |
|
|
21 | // Π΅ΡΠ»ΠΈ Π΅ΡΡΡ ΡΠΎΠ²Π½ΠΎ ΠΎΠ΄ΠΈΠ½ ΡΠ»ΠΎΡ, ΡΠΎ ΠΎΠ½ ΡΡΠΈΡΠ°Π΅ΡΡΡ primary | |
|
|
21 | // If exactly one slot is declared, it becomes the primary slot. | |
|
|
22 | 22 | providers.provider(() -> { |
|
|
23 | 23 | if (slots.size() == 0) |
|
|
24 | 24 | throw new InvalidUserDataException("No slots declared for " + outgoingVariant.getVariant()); |
| @@ -33,9 +33,8 | |||
|
|
33 | 33 | * } |
|
|
34 | 34 | * }</pre> |
|
|
35 | 35 | * |
|
|
36 | * <p>After finalization, slot identities can be observed through | |
|
|
37 | * {@link org.implab.gradle.variants.artifacts.OutgoingVariantsContext#getSlots()}, while slot bodies are | |
|
|
38 | * obtained on demand through | |
|
|
36 | * <p>After finalization, {@link org.implab.gradle.variants.artifacts.OutgoingVariant} exposes declared slot | |
|
|
37 | * identities through {@code getSlots()}, while slot bodies are obtained on demand through | |
|
|
39 | 38 | * {@link org.implab.gradle.variants.artifacts.OutgoingVariantsContext#getAssemblies()}. |
|
|
40 | 39 | */ |
|
|
41 | 40 | package org.implab.gradle.variants.artifacts; |
| @@ -103,6 +103,74 class VariantArtifactsPluginFunctionalTe | |||
|
|
103 | 103 | } |
|
|
104 | 104 | |
|
|
105 | 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 | 174 | void materializesPrimaryAndSecondarySlotsAndInvokesOutgoingHooks() throws Exception { |
|
|
107 | 175 | writeSettings("variant-artifacts-slots"); |
|
|
108 | 176 | writeFile("inputs/base.js", "console.log('base')\n"); |
| @@ -207,6 +275,66 class VariantArtifactsPluginFunctionalTe | |||
|
|
207 | 275 | } |
|
|
208 | 276 | |
|
|
209 | 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 | 338 | void allowsSingleSlotVariantWithoutExplicitPrimarySlot() throws Exception { |
|
|
211 | 339 | writeSettings("variant-artifacts-single-slot"); |
|
|
212 | 340 | writeBuildFile(""" |
General Comments 0
You need to be logged in to leave comments.
Login now
