##// END OF EJS Templates
WIP Added ArtifactAssemblyBridge to wire variants with slot assemblies
cin -
r49:e7554f6ac360 default
parent child
Show More
@@ -0,0 +1,54
1 package org.implab.gradle.variants.artifacts.internal;
2
3 import org.eclipse.jdt.annotation.NonNullByDefault;
4 import org.gradle.api.Action;
5 import org.implab.gradle.variants.artifacts.ArtifactAssemblies;
6 import org.implab.gradle.variants.artifacts.ArtifactSlot;
7 import org.implab.gradle.variants.artifacts.OutgoingVariant;
8
9 /**
10 * БвязываСт описаниС исходящих ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΉ gradle ΠΈ сборку содСрТимого слотов
11 * ΠΈΠ· {@link ArtifactAssemblies}
12 */
13 @NonNullByDefault
14 public class ArtifactAssemblyBridge implements Action<OutgoingVariant> {
15
16 private final ArtifactAssemblies resolver;
17
18 public ArtifactAssemblyBridge(ArtifactAssemblies resolver) {
19 this.resolver = resolver;
20 }
21
22 @Override
23 public void execute(OutgoingVariant outgoingVariant) {
24 var slots = outgoingVariant.getSlots();
25 var primarySlotProvider = outgoingVariant.getPrimarySlot();
26 var variant = outgoingVariant.getVariant();
27
28 // связываСм ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ
29 outgoingVariant.configure(configuration -> {
30 var primarySlot = primarySlotProvider.get();
31 var outgoing = configuration.getOutgoing();
32
33 // связываСм основной Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ
34 resolver.when(
35 new ArtifactSlot(variant, primarySlot),
36 assembly -> outgoing.artifact(assembly.getArtifact()));
37
38 // для всСх ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Π½Ρ‹Ρ… слотов
39 slots.all(slot -> {
40 // ΠΊΡ€ΠΎΠΌΠ΅ основного
41 if (slot.equals(primarySlot))
42 return;
43
44 // связываСм Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚Ρ‹
45 resolver.when(
46 new ArtifactSlot(variant, slot),
47 assembly -> outgoing.getVariants()
48 .register(slot.getName())
49 .configure(cv -> cv.artifact(assembly.getArtifact())));
50 });
51 });
52 }
53
54 }
@@ -0,0 +1,55
1 package org.implab.gradle.variants.artifacts.internal;
2
3 import java.util.Collection;
4 import java.util.Set;
5 import java.util.function.Consumer;
6 import java.util.function.Function;
7
8 import org.implab.gradle.variants.artifacts.ArtifactSlot;
9 import org.implab.gradle.variants.core.VariantsView;
10 import org.implab.gradle.variants.sources.CompileUnit;
11 import org.implab.gradle.variants.sources.VariantSourcesContext;
12
13 public class SlotInputsAssembler implements SlotContributionVisitor {
14
15 VariantsView variantView;
16 VariantSourcesContext sources;
17 ArtifactSlot artifactSlot;
18
19 Set<SlotInputKey> seen;
20
21 @Override
22 public void visit(DirectContribution contribution) {
23 contribute(
24 SlotInputKey.newUniqueKey("Direct input for " + artifactSlot),
25 contribution.input());
26 }
27
28 @Override
29 public void visit(VariantOutputsContribution contribution) {
30 sources.getCompileUnits().getUnitsForVariant(artifactSlot.variant()).stream()
31 }
32
33 @Override
34 public void visit(RoleOutputsContribution contribution) {
35 // TODO Auto-generated method stub
36 throw new UnsupportedOperationException("Unimplemented method 'visit'");
37 }
38
39 @Override
40 public void visit(LayerOutputsContribution contribution) {
41 // TODO Auto-generated method stub
42 throw new UnsupportedOperationException("Unimplemented method 'visit'");
43 }
44
45 private void contribute(SlotInputKey key, Object input) {
46
47 }
48
49 private Function<CompileUnit, Object> resolveOutputs(Collection<? extends String> outputs) {
50 return unit -> {
51
52 };
53 }
54
55 }
@@ -1,31 +1,45
1 # design notes
1 # design notes
2
2
3 ## core model
3 ## core model
4
4
5 - OutgoingRegistry (Variant)
5 - OutgoingRegistry (Variant)
6 исходящая конфигурация
6 исходящая конфигурация
7 - [provider] configuration
7 - [provider] configuration
8 - [container, live] slots
8 - [container, live] slots
9 Π½Π°Π±ΠΎΡ€ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ² (слотов)
9 Π½Π°Π±ΠΎΡ€ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ² (слотов)
10 - [property] primarySlot
10 - [property] primarySlot
11 - AssemblyRegistry (Varaint, Slot)
11 - AssemblyRegistry (Varaint, Slot)
12 содСрТимоС слота ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ послС появлСния слота Π² OutgoingRegistry
12 содСрТимоС слота ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ послС появлСния слота Π² OutgoingRegistry
13 - assembleTask
13 - assembleTask
14 - inputs
14 - inputs
15 - compile unit output (CompileUnit, String)
15 - compile unit output (CompileUnit, String)
16 - direct object (task, file collection, etc.)
16 - direct object (task, file collection, etc.)
17 - artifact: directory
17 - artifact: directory
18 - customTask
18 - customTask
19 - artifact: FileSystemLocation
19 - artifact: FileSystemLocation
20
20
21 ## extension
21 ## extension
22
22
23 - adapter
23 - adapter
24 - whenFinalized
24 - whenFinalized
25 - dsl
25 - dsl
26 - variant(name)
26 - variant(name)
27 - slot(name)
27 - slot(name)
28 - from***
28 - from***
29 - whenFinalized
29 - whenFinalized
30 - whenOutgoingConfiguration
30 - whenOutgoingConfiguration
31 - whenOutgoingSlot
31 - whenOutgoingSlot
32
33 outgoing = outgoings.maybeCreate(variant)
34
35 slot = outgoings.slots.maybeCreate(slotName)
36 assembly = assemblies.register(variantSlot, task, mapOutput)
37 outgoing.configure(configuration -> {
38 slots.all(slot -> {
39 assemblies.when(variant, slot) { assembly ->
40 configuration.variants.create(slot.name) {
41 artifact(assembly.artifact)
42 }
43 }
44 });
45 }); No newline at end of file
@@ -1,71 +1,75
1 package org.implab.gradle.variants;
1 package org.implab.gradle.variants;
2
2
3 import org.gradle.api.Action;
3 import org.gradle.api.Action;
4 import org.gradle.api.Plugin;
4 import org.gradle.api.Plugin;
5 import org.gradle.api.Project;
5 import org.gradle.api.Project;
6 import org.implab.gradle.common.core.lang.Deferred;
6 import org.implab.gradle.common.core.lang.Deferred;
7 import org.implab.gradle.variants.artifacts.ArtifactAssemblyRegistry;
7 import org.implab.gradle.variants.artifacts.ArtifactAssemblyRegistry;
8 import org.implab.gradle.variants.artifacts.OutgoingArtifactSlotSpec;
9 import org.implab.gradle.variants.artifacts.OutgoingConfigurationSpec;
8 import org.implab.gradle.variants.artifacts.OutgoingConfigurationSpec;
10 import org.implab.gradle.variants.artifacts.VariantArtifactsContext;
9 import org.implab.gradle.variants.artifacts.OutgoingVariantsContext;
11 import org.implab.gradle.variants.artifacts.VariantArtifactsExtension;
10 import org.implab.gradle.variants.artifacts.VariantArtifactsExtension;
12 import org.implab.gradle.variants.artifacts.VariantArtifactsSpec;
11 import org.implab.gradle.variants.artifacts.VariantArtifactsSpec;
12 import org.implab.gradle.variants.artifacts.internal.ArtifactAssemblyBridge;
13 import org.implab.gradle.variants.artifacts.internal.OutgoingRegistry;
13 import org.implab.gradle.variants.artifacts.internal.OutgoingRegistry;
14 import org.implab.gradle.variants.core.Variant;
14 import org.implab.gradle.variants.core.Variant;
15 import org.implab.gradle.variants.core.VariantsExtension;
15 import org.implab.gradle.variants.core.VariantsExtension;
16
16
17 public abstract class VariantArtifactsPlugin implements Plugin<Project> {
17 public abstract class VariantArtifactsPlugin implements Plugin<Project> {
18
18
19 @Override
19 @Override
20 public void apply(Project target) {
20 public void apply(Project target) {
21 var extensions = target.getExtensions();
21 var extensions = target.getExtensions();
22 var objects = target.getObjects();
22 var objects = target.getObjects();
23 var providers = target.getProviders();
23 var providers = target.getProviders();
24 var configurations = target.getConfigurations();
24 var configurations = target.getConfigurations();
25 var tasks = target.getTasks();
25 var tasks = target.getTasks();
26
26
27 // Apply the main VariantsPlugin to ensure the core variant model is available.
27 // Apply the main VariantsPlugin to ensure the core variant model is available.
28 target.getPlugins().apply(VariantsPlugin.class);
28 target.getPlugins().apply(VariantsPlugin.class);
29 // Access the VariantsExtension to configure variant sources.
29 // Access the VariantsExtension to configure variant sources.
30 var variantsExtension = extensions.getByType(VariantsExtension.class);
30 var variantsExtension = extensions.getByType(VariantsExtension.class);
31
31
32 var outgoing = new OutgoingRegistry(configurations, objects, providers);
32 var outgoing = new OutgoingRegistry(configurations, objects, providers);
33 var assemblies = new ArtifactAssemblyRegistry(objects, tasks);
33 var assemblies = new ArtifactAssemblyRegistry(objects, tasks);
34
34
35 var deferred = new Deferred<VariantArtifactsContext>();
35 var assembliesBridge = new ArtifactAssemblyBridge(assemblies);
36
37 var deferred = new Deferred<OutgoingVariantsContext>();
38
39 deferred.whenResolved(context -> context.all(assembliesBridge));
36
40
37 variantsExtension.whenFinalized(variants -> {
41 variantsExtension.whenFinalized(variants -> {
38 deferred.resolve(new VariantArtifactsRegistry(variants));
42
39 });
43 });
40
44
41 var variantArtifacts = new VariantArtifactsExtension() {
45 var variantArtifacts = new VariantArtifactsExtension() {
42
46
43 @Override
47 @Override
44 public void variant(String variantName, Action<? super VariantArtifactsSpec> action) {
48 public void variant(String variantName, Action<? super VariantArtifactsSpec> action) {
45 deferred.whenResolved(context -> registry.configureVariant(
49 deferred.whenResolved(context -> registry.configureVariant(
46 objects.named(Variant.class, variantName), action));
50 objects.named(Variant.class, variantName), action));
47 }
51 }
48
52
49 @Override
53 @Override
50 public void whenFinalized(Action<? super VariantArtifactsContext> action) {
54 public void whenFinalized(Action<? super OutgoingVariantsContext> action) {
51 deferred.whenResolved(registry -> action.execute(registry.variantsContext()));
55 deferred.whenResolved(registry -> action.execute(registry.variantsContext()));
52 }
56 }
53
57
54 @Override
58 @Override
55 public void whenOutgoingVariant(Action<? super OutgoingConfigurationSpec> action) {
59 public void whenOutgoingVariant(Action<? super OutgoingConfigurationSpec> action) {
56 deferred.whenResolved(registry -> registry.configureOutgoing(action));
60 deferred.whenResolved(registry -> registry.configureOutgoing(action));
57
61
58 }
62 }
59
63
60 @Override
64 @Override
61 public void whenOutgoingSlot(Action<? super OutgoingArtifactSlotSpec> action) {
65 public void whenOutgoingSlot(Action<? super OutgoingArtifactSlotSpec> action) {
62 deferred.whenResolved(registry -> registry.configureOutgoingSlot(action));
66 deferred.whenResolved(registry -> registry.configureOutgoingSlot(action));
63 }
67 }
64
68
65 };
69 };
66
70
67 extensions.add(VariantArtifactsExtension.class, "variantArtifacts", variantArtifacts);
71 extensions.add(VariantArtifactsExtension.class, "variantArtifacts", variantArtifacts);
68
72
69 }
73 }
70
74
71 }
75 }
@@ -1,33 +1,54
1 package org.implab.gradle.variants.artifacts;
1 package org.implab.gradle.variants.artifacts;
2
2
3 import java.util.Optional;
3 import java.util.Optional;
4
4
5 import org.eclipse.jdt.annotation.NonNullByDefault;
5 import org.eclipse.jdt.annotation.NonNullByDefault;
6 import org.gradle.api.Action;
6 import org.gradle.api.InvalidUserDataException;
7 import org.gradle.api.InvalidUserDataException;
7
8
8 /**
9 /**
9 * Resolves stateful slot assemblies from cheap slot identities.
10 * Resolves stateful slot assemblies from cheap slot identities.
10 *
11 *
11 * <p>
12 * <p>
12 * The returned assembly is a materialized build-model handle. It may expose
13 * The returned assembly is a materialized build-model handle. It may expose
13 * lazy Gradle providers, but
14 * lazy Gradle providers, but
14 * it is no longer an identity object suitable for replayable discovery.
15 * it is no longer an identity object suitable for replayable discovery.
15 */
16 */
16 @NonNullByDefault
17 @NonNullByDefault
17 public interface ArtifactAssemblies {
18 public interface ArtifactAssemblies {
18 /**
19 /**
19 * Resolves the assembly for the given slot.
20 * Resolves the assembly for the given slot.
20 *
21 *
21 * <p>
22 * <p>
22 * This call materializes the build-facing body of the slot from its identity.
23 * This call materializes the build-facing body of the slot from its identity.
23 *
24 *
24 * @param slot slot identity inside a variant outgoing contract
25 * @param slot slot identity inside a variant outgoing contract
25 * @return assembly handle for the slot
26 * @return assembly handle for the slot
26 */
27 */
27 default ArtifactAssembly require(ArtifactSlot slot) {
28 default ArtifactAssembly require(ArtifactSlot slot) {
28 return find(slot)
29 return find(slot)
29 .orElseThrow(() -> new InvalidUserDataException("Artifact assembly '" + slot + "' isn't registered"));
30 .orElseThrow(() -> new InvalidUserDataException("Artifact assembly '" + slot + "' isn't registered"));
30 }
31 }
31
32
33 /**
34 * РСгистрируСт ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Π½Π° ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹ΠΉ слот. Если слот Π΅Ρ‰Π΅ Π½Π΅ зарСгистрирован,
35 * Ρ‚ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Π±ΡƒΠ΄Π΅Ρ‚ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ ΠΈ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Π²Π°Π½ ΠΏΡ€ΠΈ рСгистрации слота.
36 * ΠŸΠΎΡ€ΡΠ΄ΠΎΠΊ ΠΈ Ρ‚ΠΎΡ‡Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ‹Π·ΠΎΠ²Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ² Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½.
37 *
38 * @param slot Π‘Π»ΠΎΡ‚ Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½ΡƒΠΆΠ½ΠΎ Π·Π°Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ
39 * @param action ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ
40 */
41 void when(ArtifactSlot slot, Action<? super ArtifactAssembly> action);
42
43 /**
44 * РСгистрируСт Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Π²Π°Π½ для всСх слотов.
45 * ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Π²Π°Π½ ΠΊΠ°ΠΊ для ΡƒΠΆΠ΅ зарСгистрированных слотов Ρ‚Π°ΠΊ ΠΈ для Ρ‚Π΅Ρ…,
46 * ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ зарСгистрированы Π² Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΌ.
47 *
48 * @param action ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ
49 */
50 void all(Action<? super ArtifactAssembly> action);
51
52 /** Π˜Ρ‰Π΅Ρ‚ зарСгистрированный слот */
32 Optional<ArtifactAssembly> find(ArtifactSlot slot);
53 Optional<ArtifactAssembly> find(ArtifactSlot slot);
33 }
54 }
@@ -1,99 +1,124
1 package org.implab.gradle.variants.artifacts;
1 package org.implab.gradle.variants.artifacts;
2
2
3 import java.util.LinkedHashMap;
3 import java.util.LinkedHashMap;
4 import java.util.Map;
4 import java.util.Map;
5 import java.util.Optional;
5 import java.util.Optional;
6 import java.util.function.Function;
6 import java.util.function.Function;
7
7
8 import org.eclipse.jdt.annotation.NonNullByDefault;
8 import org.eclipse.jdt.annotation.NonNullByDefault;
9 import org.gradle.api.Action;
9 import org.gradle.api.InvalidUserDataException;
10 import org.gradle.api.InvalidUserDataException;
10 import org.gradle.api.Task;
11 import org.gradle.api.Task;
11 import org.gradle.api.file.Directory;
12 import org.gradle.api.file.Directory;
12 import org.gradle.api.file.FileCollection;
13 import org.gradle.api.file.FileCollection;
13 import org.gradle.api.file.FileSystemLocation;
14 import org.gradle.api.file.FileSystemLocation;
14 import org.gradle.api.model.ObjectFactory;
15 import org.gradle.api.model.ObjectFactory;
15 import org.gradle.api.provider.Provider;
16 import org.gradle.api.provider.Provider;
16 import org.gradle.api.tasks.Copy;
17 import org.gradle.api.tasks.Copy;
17 import org.gradle.api.tasks.TaskContainer;
18 import org.gradle.api.tasks.TaskContainer;
18 import org.gradle.api.tasks.TaskProvider;
19 import org.gradle.api.tasks.TaskProvider;
19 import org.gradle.language.base.plugins.LifecycleBasePlugin;
20 import org.gradle.language.base.plugins.LifecycleBasePlugin;
21 import org.implab.gradle.common.core.lang.Deferred;
22 import org.implab.gradle.internal.ReplayableQueue;
20
23
21 @NonNullByDefault
24 @NonNullByDefault
22 public class ArtifactAssemblyRegistry implements ArtifactAssemblies {
25 public class ArtifactAssemblyRegistry implements ArtifactAssemblies {
23 private final ObjectFactory objects;
26 private final ObjectFactory objects;
24 private final TaskContainer tasks;
27 private final TaskContainer tasks;
25 private final Map<ArtifactSlot, ArtifactAssembly> assemblies = new LinkedHashMap<>();
28 private final Map<ArtifactSlot, Deferred<ArtifactAssembly>> assembliesBySlots = new LinkedHashMap<>();
29 private final ReplayableQueue<ArtifactAssembly> assemblies = new ReplayableQueue<>();
26
30
27 public ArtifactAssemblyRegistry(ObjectFactory objects, TaskContainer tasks) {
31 public ArtifactAssemblyRegistry(ObjectFactory objects, TaskContainer tasks) {
28 this.objects = objects;
32 this.objects = objects;
29 this.tasks = tasks;
33 this.tasks = tasks;
30 }
34 }
31
35
32 public ArtifactAssembly register(
36 public ArtifactAssembly register(
33 ArtifactSlot slot,
37 ArtifactSlot slot,
34 String taskName,
38 String taskName,
35 Provider<Directory> outputDirectory,
39 Provider<Directory> outputDirectory,
36 FileCollection sources) {
40 FileCollection sources) {
37
41
38 var task = tasks.register(taskName, Copy.class, copy -> {
42 var task = tasks.register(taskName, Copy.class, copy -> {
39 copy.setGroup(LifecycleBasePlugin.BUILD_GROUP);
43 copy.setGroup(LifecycleBasePlugin.BUILD_GROUP);
40 copy.into(outputDirectory);
44 copy.into(outputDirectory);
41 copy.from(sources);
45 copy.from(sources);
42 });
46 });
43
47
44 return register(slot, task, t -> outputDirectory);
48 return register(slot, task, t -> outputDirectory);
45 }
49 }
46
50
47 public <T extends Task> ArtifactAssembly register(
51 public <T extends Task> ArtifactAssembly register(
48 ArtifactSlot slot,
52 ArtifactSlot slot,
49 TaskProvider<T> task,
53 TaskProvider<T> task,
50 Function<? super T, ? extends Provider<? extends FileSystemLocation>> mapOutputDirectory) {
54 Function<? super T, ? extends Provider<? extends FileSystemLocation>> mapOutputArtifact) {
51 if (assemblies.containsKey(slot)) {
55
56 var deferred = getDeferred(slot);
57 if (deferred.resolved()) {
52 throw new InvalidUserDataException("Artifact assembly '" + slot + "' is already registered");
58 throw new InvalidUserDataException("Artifact assembly '" + slot + "' is already registered");
53 }
59 }
54 var outputArtifact = task.flatMap(t -> mapOutputDirectory.apply(t));
60 var outputArtifact = task.flatMap(mapOutputArtifact::apply);
55
61
56 var output = objects.fileCollection()
62 var output = objects.fileCollection()
57 .from(outputArtifact)
63 .from(outputArtifact)
58 .builtBy(task);
64 .builtBy(task);
59
65
60 var assembly = new Assembly(outputArtifact, task, output);
66 var assembly = new Assembly(outputArtifact, task, output);
61 assemblies.put(slot, assembly);
67 deferred.resolve(assembly);
68 assemblies.add(assembly);
62 return assembly;
69 return assembly;
63 }
70 }
64
71
65 @Override
72 @Override
66 public Optional<ArtifactAssembly> find(ArtifactSlot slot) {
73 public Optional<ArtifactAssembly> find(ArtifactSlot slot) {
67 return Optional.ofNullable(assemblies.get(slot));
74 // to prevent creation of map entries on lookup use the map directly
75 var deferred = assembliesBySlots.get(slot);
76 return deferred != null && deferred.resolved()
77 ? Optional.of(deferred.value())
78 : Optional.empty();
79 }
80
81 @Override
82 public void when(ArtifactSlot slot, Action<? super ArtifactAssembly> action) {
83 getDeferred(slot).whenResolved(action::execute);
84 }
85
86 @Override
87 public void all(Action<? super ArtifactAssembly> action) {
88 assemblies.forEach(action::execute);
89 }
90
91 private Deferred<ArtifactAssembly> getDeferred(ArtifactSlot slot) {
92 return assembliesBySlots.computeIfAbsent(slot, k -> new Deferred<>());
68 }
93 }
69
94
70 static class Assembly implements ArtifactAssembly {
95 static class Assembly implements ArtifactAssembly {
71
96
72 private final Provider<? extends FileSystemLocation> artifact;
97 private final Provider<? extends FileSystemLocation> artifact;
73 private final TaskProvider<? extends Task> task;
98 private final TaskProvider<? extends Task> task;
74 private final FileCollection fileCollection;
99 private final FileCollection fileCollection;
75
100
76 Assembly(Provider<? extends FileSystemLocation> artifact, TaskProvider<? extends Task> task,
101 Assembly(Provider<? extends FileSystemLocation> artifact, TaskProvider<? extends Task> task,
77 FileCollection fileCollection) {
102 FileCollection fileCollection) {
78 this.artifact = artifact;
103 this.artifact = artifact;
79 this.task = task;
104 this.task = task;
80 this.fileCollection = fileCollection;
105 this.fileCollection = fileCollection;
81 }
106 }
82
107
83 @Override
108 @Override
84 public Provider<? extends FileSystemLocation> getArtifact() {
109 public Provider<? extends FileSystemLocation> getArtifact() {
85 return artifact;
110 return artifact;
86 }
111 }
87
112
88 @Override
113 @Override
89 public TaskProvider<? extends Task> getAssemblyTask() {
114 public TaskProvider<? extends Task> getAssemblyTask() {
90 return task;
115 return task;
91 }
116 }
92
117
93 @Override
118 @Override
94 public FileCollection getFileCollection() {
119 public FileCollection getFileCollection() {
95 return fileCollection;
120 return fileCollection;
96 }
121 }
97
122
98 }
123 }
99 }
124 }
@@ -1,59 +1,59
1 package org.implab.gradle.variants.artifacts;
1 package org.implab.gradle.variants.artifacts;
2
2
3 import org.gradle.api.Action;
3 import org.gradle.api.Action;
4 import org.gradle.api.Task;
4 import org.gradle.api.Task;
5 import org.gradle.api.attributes.AttributeContainer;
5 import org.gradle.api.attributes.AttributeContainer;
6 import groovy.lang.Closure;
6 import groovy.lang.Closure;
7 import org.implab.gradle.common.core.lang.Closures;
7 import org.implab.gradle.common.core.lang.Closures;
8
8
9 /**
9 /**
10 * Materialized outgoing publication state of a single slot.
10 * Materialized outgoing publication state of a single slot.
11 *
11 *
12 * <p>This type is a DSL facade to represent already created publication-facing state. Slot-specific
12 * <p>This type is a DSL facade to represent already created publication-facing state. Slot-specific
13 * publication tweaks should be applied here rather than through {@link OutgoingConfigurationSpec}, which
13 * publication tweaks should be applied here rather than through {@link OutgoingConfigurationSpec}, which
14 * is limited to the root outgoing configuration of the variant.
14 * is limited to the root outgoing configuration of the variant.
15 */
15 */
16 public interface OutgoingArtifactSlotSpec {
16 public interface OutgoingConfigurationSlotSpec {
17 /**
17 /**
18 * Returns the published slot identity.
18 * Returns the published slot identity.
19 *
19 *
20 * @return slot identity
20 * @return slot identity
21 */
21 */
22 ArtifactSlot getArtifactSlot();
22 ArtifactSlot getArtifactSlot();
23
23
24 /**
24 /**
25 * Returns the assembly backing the published slot.
25 * Returns the assembly backing the published slot.
26 *
26 *
27 * @return slot assembly
27 * @return slot assembly
28 */
28 */
29 ArtifactAssembly getAssembly();
29 ArtifactAssembly getAssembly();
30
30
31 /**
31 /**
32 * Returns whether this slot is the primary outgoing artifact set of the variant.
32 * Returns whether this slot is the primary outgoing artifact set of the variant.
33 *
33 *
34 * @return {@code true} for the primary slot
34 * @return {@code true} for the primary slot
35 */
35 */
36 boolean isPrimary();
36 boolean isPrimary();
37
37
38 /**
38 /**
39 * Configures the task producing the slot artifact.
39 * Configures the task producing the slot artifact.
40 *
40 *
41 * @param action task configuration action
41 * @param action task configuration action
42 */
42 */
43 void assemblyTask(Action<? super Task> action);
43 void assemblyTask(Action<? super Task> action);
44
44
45 default void assemblyTask(Closure<?> closure) {
45 default void assemblyTask(Closure<?> closure) {
46 assemblyTask(Closures.action(closure));
46 assemblyTask(Closures.action(closure));
47 }
47 }
48
48
49 /**
49 /**
50 * Configures attributes of this slot publication.
50 * Configures attributes of this slot publication.
51 *
51 *
52 * @param action artifact attribute configuration action
52 * @param action artifact attribute configuration action
53 */
53 */
54 void artifactAttributes(Action<? super AttributeContainer> action);
54 void artifactAttributes(Action<? super AttributeContainer> action);
55
55
56 default void artifactAttributes(Closure<?> closure) {
56 default void artifactAttributes(Closure<?> closure) {
57 artifactAttributes(Closures.action(closure));
57 artifactAttributes(Closures.action(closure));
58 }
58 }
59 }
59 }
@@ -1,38 +1,50
1 package org.implab.gradle.variants.artifacts;
1 package org.implab.gradle.variants.artifacts;
2
2
3 import org.gradle.api.Action;
3 import org.gradle.api.NamedDomainObjectContainer;
4 import org.gradle.api.NamedDomainObjectContainer;
4 import org.gradle.api.NamedDomainObjectProvider;
5 import org.gradle.api.NamedDomainObjectProvider;
5 import org.gradle.api.artifacts.Configuration;
6 import org.gradle.api.artifacts.Configuration;
6 import org.gradle.api.provider.Property;
7 import org.gradle.api.provider.Property;
7 import org.implab.gradle.variants.core.Variant;
8 import org.implab.gradle.variants.core.Variant;
8
9
9 /** ΠžΠΏΠΈΡΡ‹Π²Π°Π΅Ρ‚ ΠΈΡΡ…ΠΎΠ΄ΡΡ‰ΡƒΡŽ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π° */
10 /**
10 public interface OutgoingConfiguration {
11 * ΠžΠΏΠΈΡΡ‹Π²Π°Π΅Ρ‚ ΠΈΡΡ…ΠΎΠ΄ΡΡ‰ΡƒΡŽ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π°
12 *
13 * Π—Π°Π΄Π°Π΅Ρ‚ связь ΠΌΠ΅ΠΆΠ΄Ρƒ модСлью Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ² ΠΈ модСлью ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΉ gradle Ρ‡Π΅Ρ€Π΅Π·
14 * свойство {@link #getConfiguration()}. Π’Π°ΠΊΠΆΠ΅ Π·Π°Π΄Π°Π΅Ρ‚ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΡƒΡŽ ось слотов
15 * ΠΏΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΠΈ, Π½ΠΎ Π½Π΅ Π·Π°Π΄Π°Π΅Ρ‚ ΠΏΡ€Π°Π²ΠΈΠ» связывания этих слотов с самой ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠ΅ΠΉ
16 * ΠΈ ΠΈΡ… содСрТимым. Π‘Π°ΠΌΡ‹ΠΉ простой Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ это {@link ArtifactAssemblies}.
17 */
18 public interface OutgoingVariant {
11 /**
19 /**
12 * Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹ΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ для ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ строится Outgoing конфигурация
20 * Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹ΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ для ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ строится Outgoing конфигурация
13 */
21 */
14 Variant getVariant();
22 Variant getVariant();
15
23
16 /**
24 /**
17 * ΠŸΡ€ΠΎΠ²Π°ΠΉΠ΄Π΅Ρ€ зарСгистрированной ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ
25 * ΠŸΡ€ΠΎΠ²Π°ΠΉΠ΄Π΅Ρ€ зарСгистрированной ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ
18 */
26 */
19 NamedDomainObjectProvider<Configuration> getOutgoingConfiguration();
27 NamedDomainObjectProvider<Configuration> getConfiguration();
28
29 default void configure(Action<? super Configuration> action) {
30 getConfiguration().configure(action);
31 }
20
32
21 /**
33 /**
22 * Π‘Π»ΠΎΡ‚Ρ‹ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ, данная коллСкция Тивая, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для
34 * Π‘Π»ΠΎΡ‚Ρ‹ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ, данная коллСкция Тивая, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для
23 * получСния ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎΠ± ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Π½Ρ‹Ρ… слотах, Π½ΠΎ эти слоты Π½Π΅
35 * получСния ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎΠ± ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Π½Ρ‹Ρ… слотах, Π½ΠΎ эти слоты Π½Π΅
24 * обязаны Π±Ρ‹Ρ‚ΡŒ сконфигурированы, Ρ‚.Π΅. это Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Identity.
36 * обязаны Π±Ρ‹Ρ‚ΡŒ сконфигурированы, Ρ‚.Π΅. это Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Identity.
25 *
37 *
26 * @see {@link ArtifactSlot}
38 * @see {@link ArtifactSlot}
27 */
39 */
28 NamedDomainObjectContainer<Slot> getSlots();
40 NamedDomainObjectContainer<Slot> getSlots();
29
41
30 /**
42 /**
31 * Основной Π½Π°Π±ΠΎΡ€ Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚ΠΎΠ² (primary variant) для исходящСй ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ
43 * Основной Π½Π°Π±ΠΎΡ€ Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚ΠΎΠ² (primary variant) для исходящСй ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ
32 *
44 *
33 * <p>
45 * <p>
34 * Если Π² свойствС {@link #getSlots()} Π΅ΡΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ слой, Ρ‚ΠΎ ΠΏΠΎ ΠΊΠΎΠ½Π²Π΅Π½Ρ†ΠΈΠΈ ΠΎΠ½
46 * Если Π² свойствС {@link #getSlots()} Π΅ΡΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ слой, Ρ‚ΠΎ ΠΏΠΎ ΠΊΠΎΠ½Π²Π΅Π½Ρ†ΠΈΠΈ ΠΎΠ½
35 * считаСтся Ρ‚Π°ΠΊΠΆΠ΅ основным.
47 * считаСтся Ρ‚Π°ΠΊΠΆΠ΅ основным.
36 */
48 */
37 Property<Slot> getPrimarySlot();
49 Property<Slot> getPrimarySlot();
38 }
50 }
@@ -1,38 +1,38
1 package org.implab.gradle.variants.artifacts;
1 package org.implab.gradle.variants.artifacts;
2
2
3 import java.util.Optional;
3 import java.util.Optional;
4
4
5 import org.gradle.api.Action;
5 import org.gradle.api.Action;
6 import org.gradle.api.InvalidUserDataException;
6 import org.gradle.api.InvalidUserDataException;
7 import org.implab.gradle.variants.core.Variant;
7 import org.implab.gradle.variants.core.Variant;
8 import org.implab.gradle.variants.core.VariantsView;
8 import org.implab.gradle.variants.core.VariantsView;
9
9
10 /**
10 /**
11 * ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π°ΠΌΠΈ ΠΏΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΠΈ, становится доступным послС
11 * ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π°ΠΌΠΈ ΠΏΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΠΈ, становится доступным послС
12 * Ρ„ΠΈΠ½Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΌΠΎΠ΄Π΅Π»ΠΈ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ². ЀактичСски являСтся ΠΆΠΈΠ²ΠΎΠΉ модСлью
12 * Ρ„ΠΈΠ½Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΌΠΎΠ΄Π΅Π»ΠΈ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ². ЀактичСски являСтся ΠΆΠΈΠ²ΠΎΠΉ модСлью
13 */
13 */
14 public interface VariantArtifactsContext {
14 public interface OutgoingVariantsContext {
15
15
16 /**
16 /**
17 * ЗафиксированноС прСдставлСниС ΠΎ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π°Ρ… Π½Π° основС ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚
17 * ЗафиксированноС прСдставлСниС ΠΎ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π°Ρ… Π½Π° основС ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚
18 * ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚Ρ‹ ΠΈ исходящиС ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ
18 * ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚Ρ‹ ΠΈ исходящиС ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ
19 */
19 */
20 VariantsView getVariants();
20 VariantsView getVariants();
21
21
22 ArtifactAssemblies getAssemblies();
22 ArtifactAssemblies getAssemblies();
23
23
24 /**
24 /**
25 * Replayable hook для всСх ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Π½Ρ‹Ρ… ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΉ
25 * Replayable hook для всСх ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Π½Ρ‹Ρ… ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΉ
26 */
26 */
27 void all(Action<? super OutgoingConfiguration> action);
27 void all(Action<? super OutgoingVariant> action);
28
28
29 Optional<OutgoingConfiguration> findOutgoing(Variant variant);
29 Optional<OutgoingVariant> findOutgoing(Variant variant);
30
30
31 default OutgoingConfiguration requireOutgoing(Variant variant) {
31 default OutgoingVariant requireOutgoing(Variant variant) {
32 return findOutgoing(variant)
32 return findOutgoing(variant)
33 .orElseThrow(() -> new InvalidUserDataException("Outgoing variant '" + variant + "' isn't registered"));
33 .orElseThrow(() -> new InvalidUserDataException("Outgoing variant '" + variant + "' isn't registered"));
34 }
34 }
35
35
36 ArtifactAssemblyRules slotRules(ArtifactSlot slot);
36 ArtifactAssemblyRules slotRules(ArtifactSlot slot);
37
37
38 }
38 }
@@ -1,59 +1,59
1 package org.implab.gradle.variants.artifacts;
1 package org.implab.gradle.variants.artifacts;
2
2
3 import org.gradle.api.Action;
3 import org.gradle.api.Action;
4 import org.implab.gradle.common.core.lang.Closures;
4 import org.implab.gradle.common.core.lang.Closures;
5
5
6 import groovy.lang.Closure;
6 import groovy.lang.Closure;
7
7
8 /**
8 /**
9 * Project-level DSL entry point for declaring outgoing artifacts per variant.
9 * Project-level DSL entry point for declaring outgoing artifacts per variant.
10 *
10 *
11 * <p>A variant represents one external outgoing contract. Slots declared inside a variant represent
11 * <p>A variant represents one external outgoing contract. Slots declared inside a variant represent
12 * artifact sets within that contract. One slot is expected to materialize to one published artifact.
12 * artifact sets within that contract. One slot is expected to materialize to one published artifact.
13 */
13 */
14 public interface VariantArtifactsExtension {
14 public interface VariantArtifactsExtension {
15 /**
15 /**
16 * Configures artifact slots of the named variant.
16 * Configures artifact slots of the named variant.
17 *
17 *
18 * @param variantName variant name
18 * @param variantName variant name
19 * @param action variant artifact declaration
19 * @param action variant artifact declaration
20 */
20 */
21 void variant(String variantName, Action<? super VariantArtifactsSpec> action);
21 void variant(String variantName, Action<? super VariantArtifactsSpec> action);
22
22
23 default void variant(String variantName, Closure<?> closure) {
23 default void variant(String variantName, Closure<?> closure) {
24 variant(variantName, Closures.action(closure));
24 variant(variantName, Closures.action(closure));
25 }
25 }
26
26
27 /**
27 /**
28 * Registers a callback invoked with the finalized artifact model.
28 * Registers a callback invoked with the finalized artifact model.
29 *
29 *
30 * @param action finalized-model callback
30 * @param action finalized-model callback
31 */
31 */
32 void whenFinalized(Action<? super VariantArtifactsContext> action);
32 void whenFinalized(Action<? super OutgoingVariantsContext> action);
33
33
34 default void whenFinalized(Closure<?> closure) {
34 default void whenFinalized(Closure<?> closure) {
35 whenFinalized(Closures.action(closure));
35 whenFinalized(Closures.action(closure));
36 }
36 }
37
37
38 /**
38 /**
39 * Registers a callback invoked for each materialized root outgoing configuration.
39 * Registers a callback invoked for each materialized root outgoing configuration.
40 *
40 *
41 * @param action variant-level outgoing configuration callback
41 * @param action variant-level outgoing configuration callback
42 */
42 */
43 void whenOutgoingVariant(Action<? super OutgoingConfigurationSpec> action);
43 void whenOutgoingVariant(Action<? super OutgoingConfigurationSpec> action);
44
44
45 default void whenOutgoingVariant(Closure<?> closure) {
45 default void whenOutgoingVariant(Closure<?> closure) {
46 whenOutgoingVariant(Closures.action(closure));
46 whenOutgoingVariant(Closures.action(closure));
47 }
47 }
48
48
49 /**
49 /**
50 * Registers a callback invoked for each materialized outgoing slot publication.
50 * Registers a callback invoked for each materialized outgoing slot publication.
51 *
51 *
52 * @param action slot-level outgoing publication callback
52 * @param action slot-level outgoing publication callback
53 */
53 */
54 void whenOutgoingSlot(Action<? super OutgoingArtifactSlotSpec> action);
54 void whenOutgoingSlot(Action<? super OutgoingConfigurationSlotSpec> action);
55
55
56 default void whenOutgoingSlot(Closure<?> closure) {
56 default void whenOutgoingSlot(Closure<?> closure) {
57 whenOutgoingSlot(Closures.action(closure));
57 whenOutgoingSlot(Closures.action(closure));
58 }
58 }
59 }
59 }
@@ -1,62 +1,62
1 package org.implab.gradle.variants.artifacts.internal;
1 package org.implab.gradle.variants.artifacts.internal;
2
2
3 import org.gradle.api.NamedDomainObjectContainer;
3 import org.gradle.api.NamedDomainObjectContainer;
4 import org.gradle.api.NamedDomainObjectProvider;
4 import org.gradle.api.NamedDomainObjectProvider;
5 import org.gradle.api.artifacts.Configuration;
5 import org.gradle.api.artifacts.Configuration;
6 import org.gradle.api.model.ObjectFactory;
6 import org.gradle.api.model.ObjectFactory;
7 import org.gradle.api.provider.Property;
7 import org.gradle.api.provider.Property;
8 import org.gradle.api.provider.ProviderFactory;
8 import org.gradle.api.provider.ProviderFactory;
9 import org.gradle.api.provider.Provider;
9 import org.gradle.api.provider.Provider;
10 import org.implab.gradle.variants.artifacts.OutgoingConfiguration;
10 import org.implab.gradle.variants.artifacts.OutgoingVariant;
11 import org.implab.gradle.variants.artifacts.Slot;
11 import org.implab.gradle.variants.artifacts.Slot;
12 import org.implab.gradle.variants.core.Variant;
12 import org.implab.gradle.variants.core.Variant;
13
13
14 class DefaultOutgoingConfiguration implements OutgoingConfiguration {
14 class DefaultOutgoingConfiguration implements OutgoingVariant {
15
15
16 private final Variant variant;
16 private final Variant variant;
17
17
18 private final NamedDomainObjectProvider<Configuration> configurationProvider;
18 private final NamedDomainObjectProvider<Configuration> configurationProvider;
19
19
20 private final NamedDomainObjectContainer<Slot> slots;
20 private final NamedDomainObjectContainer<Slot> slots;
21
21
22 private final Property<Slot> primarySlot;
22 private final Property<Slot> primarySlot;
23
23
24 public DefaultOutgoingConfiguration(
24 public DefaultOutgoingConfiguration(
25 Variant variant,
25 Variant variant,
26 NamedDomainObjectProvider<Configuration> configurationProvider,
26 NamedDomainObjectProvider<Configuration> configurationProvider,
27 ObjectFactory objectFactory,
27 ObjectFactory objectFactory,
28 ProviderFactory providerFactory) {
28 ProviderFactory providerFactory) {
29 this.variant = variant;
29 this.variant = variant;
30 this.configurationProvider = configurationProvider;
30 this.configurationProvider = configurationProvider;
31 this.slots = objectFactory.domainObjectContainer(Slot.class);
31 this.slots = objectFactory.domainObjectContainer(Slot.class);
32 this.primarySlot = objectFactory.property(Slot.class)
32 this.primarySlot = objectFactory.property(Slot.class)
33 .convention(providerFactory
33 .convention(providerFactory
34 .provider(this::primarySlotConvention)
34 .provider(this::primarySlotConvention)
35 .flatMap(x -> x));
35 .flatMap(x -> x));
36 }
36 }
37
37
38 @Override
38 @Override
39 public Property<Slot> getPrimarySlot() {
39 public Property<Slot> getPrimarySlot() {
40 return primarySlot;
40 return primarySlot;
41 }
41 }
42
42
43 @Override
43 @Override
44 public Variant getVariant() {
44 public Variant getVariant() {
45 return variant;
45 return variant;
46 }
46 }
47
47
48 @Override
48 @Override
49 public NamedDomainObjectProvider<Configuration> getOutgoingConfiguration() {
49 public NamedDomainObjectProvider<Configuration> getConfiguration() {
50 return configurationProvider;
50 return configurationProvider;
51 }
51 }
52
52
53 @Override
53 @Override
54 public NamedDomainObjectContainer<Slot> getSlots() {
54 public NamedDomainObjectContainer<Slot> getSlots() {
55 return slots;
55 return slots;
56 }
56 }
57
57
58 private Provider<Slot> primarySlotConvention() {
58 private Provider<Slot> primarySlotConvention() {
59 return slots.size() == 1 ? slots.named(slots.getNames().first()) : null;
59 return slots.size() == 1 ? slots.named(slots.getNames().first()) : null;
60 }
60 }
61
61
62 }
62 }
@@ -1,45 +1,56
1 package org.implab.gradle.variants.artifacts.internal;
1 package org.implab.gradle.variants.artifacts.internal;
2
2
3 import java.util.LinkedHashMap;
3 import java.util.LinkedHashMap;
4 import java.util.LinkedList;
5 import java.util.List;
4 import java.util.Map;
6 import java.util.Map;
5 import java.util.Optional;
7 import java.util.Optional;
8 import java.util.function.Consumer;
6
9
7 import org.gradle.api.artifacts.ConfigurationContainer;
10 import org.gradle.api.artifacts.ConfigurationContainer;
8 import org.gradle.api.model.ObjectFactory;
11 import org.gradle.api.model.ObjectFactory;
9 import org.gradle.api.provider.ProviderFactory;
12 import org.gradle.api.provider.ProviderFactory;
10 import org.implab.gradle.variants.artifacts.OutgoingConfiguration;
13 import org.implab.gradle.variants.artifacts.OutgoingVariant;
11 import org.implab.gradle.variants.core.Variant;
14 import org.implab.gradle.variants.core.Variant;
12
15
13 public class OutgoingRegistry {
16 public class OutgoingRegistry {
14 private final Map<Variant, DefaultOutgoingConfiguration> outgoingByVariant = new LinkedHashMap<>();
17 private final Map<Variant, DefaultOutgoingConfiguration> outgoingByVariant = new LinkedHashMap<>();
18 private final List<Consumer<? super DefaultOutgoingConfiguration>> hooks = new LinkedList<>();
15
19
16 private final ConfigurationContainer configurations;
20 private final ConfigurationContainer configurations;
17 private final ObjectFactory objects;
21 private final ObjectFactory objects;
18 private final ProviderFactory providers;
22 private final ProviderFactory providers;
19
23
20 public OutgoingRegistry(ConfigurationContainer configurations, ObjectFactory objects, ProviderFactory providers) {
24 public OutgoingRegistry(ConfigurationContainer configurations, ObjectFactory objects, ProviderFactory providers) {
21 this.configurations = configurations;
25 this.configurations = configurations;
22 this.objects = objects;
26 this.objects = objects;
23 this.providers = providers;
27 this.providers = providers;
24 }
28 }
25
29
26 public Optional<OutgoingConfiguration> findOutgoing(Variant variant) {
30 public Optional<OutgoingVariant> findOutgoing(Variant variant) {
27 return Optional.ofNullable(outgoingByVariant.get(variant));
31 return Optional.ofNullable(outgoingByVariant.get(variant));
28 }
32 }
29
33
30 public OutgoingConfiguration maybeCreate(Variant variant) {
34 public OutgoingVariant maybeCreate(Variant variant) {
31 return outgoingByVariant.computeIfAbsent(variant, this::newOutgoingConfiguration);
35 var outgoing = outgoingByVariant.computeIfAbsent(variant, this::newOutgoingConfiguration);
36 hooks.forEach(hook -> hook.accept(outgoing));
37 return outgoing;
38 }
39
40 public void all(Consumer<? super OutgoingVariant> action) {
41 outgoingByVariant.values().forEach(action);
42 hooks.add(action);
32 }
43 }
33
44
34 private DefaultOutgoingConfiguration newOutgoingConfiguration(Variant variant) {
45 private DefaultOutgoingConfiguration newOutgoingConfiguration(Variant variant) {
35 var configuration = configurations.register(outgoingConfigurationName(variant));
46 var configuration = configurations.register(outgoingConfigurationName(variant));
36
47
37 return new DefaultOutgoingConfiguration(variant, configuration, objects, providers);
48 return new DefaultOutgoingConfiguration(variant, configuration, objects, providers);
38 }
49 }
39
50
40 String outgoingConfigurationName(Variant variant) {
51 private String outgoingConfigurationName(Variant variant) {
41 return variant.getName() + "Elements";
52 return variant.getName() + "Elements";
42 }
53 }
43
54
44
55
45 }
56 }
@@ -1,41 +1,41
1 /**
1 /**
2 * Variant-scoped outgoing artifacts.
2 * Variant-scoped outgoing artifacts.
3 *
3 *
4 * <p>This package models the external artifact contract of a project in terms of variant-local slots.
4 * <p>This package models the external artifact contract of a project in terms of variant-local slots.
5 * A variant represents one outgoing contract, while a slot represents one artifact set inside that
5 * A variant represents one outgoing contract, while a slot represents one artifact set inside that
6 * contract.
6 * contract.
7 *
7 *
8 * <p>The model intentionally separates cheap identity objects from stateful build objects:
8 * <p>The model intentionally separates cheap identity objects from stateful build objects:
9 *
9 *
10 * <ul>
10 * <ul>
11 * <li>{@link org.implab.gradle.variants.artifacts.ArtifactSlot} identifies a published slot inside a
11 * <li>{@link org.implab.gradle.variants.artifacts.ArtifactSlot} identifies a published slot inside a
12 * variant;</li>
12 * variant;</li>
13 * <li>{@link org.implab.gradle.variants.artifacts.ArtifactAssembly} is the lazily materialized body of
13 * <li>{@link org.implab.gradle.variants.artifacts.ArtifactAssembly} is the lazily materialized body of
14 * that slot.</li>
14 * that slot.</li>
15 * </ul>
15 * </ul>
16 *
16 *
17 * <p>Each slot is expected to materialize to exactly one published artifact: either one file or one
17 * <p>Each slot is expected to materialize to exactly one published artifact: either one file or one
18 * directory. Internal build topology such as roles may participate in slot assembly rules, but does not
18 * directory. Internal build topology such as roles may participate in slot assembly rules, but does not
19 * belong to external artifact identity.
19 * belong to external artifact identity.
20 *
20 *
21 * <p>Typical usage:
21 * <p>Typical usage:
22 *
22 *
23 * <pre>{@code
23 * <pre>{@code
24 * variantArtifacts {
24 * variantArtifacts {
25 * variant("browser") {
25 * variant("browser") {
26 * primarySlot("runtime") {
26 * primarySlot("runtime") {
27 * fromRole("main") { output("js") }
27 * fromRole("main") { output("js") }
28 * }
28 * }
29 * slot("sources") {
29 * slot("sources") {
30 * fromLayer("main") { output("sources") }
30 * fromLayer("main") { output("sources") }
31 * }
31 * }
32 * }
32 * }
33 * }
33 * }
34 * }</pre>
34 * }</pre>
35 *
35 *
36 * <p>After finalization, slot identities can be observed through
36 * <p>After finalization, slot identities can be observed through
37 * {@link org.implab.gradle.variants.artifacts.VariantArtifactsContext#getSlots()}, while slot bodies are
37 * {@link org.implab.gradle.variants.artifacts.OutgoingVariantsContext#getSlots()}, while slot bodies are
38 * obtained on demand through
38 * obtained on demand through
39 * {@link org.implab.gradle.variants.artifacts.VariantArtifactsContext#getAssemblies()}.
39 * {@link org.implab.gradle.variants.artifacts.OutgoingVariantsContext#getAssemblies()}.
40 */
40 */
41 package org.implab.gradle.variants.artifacts;
41 package org.implab.gradle.variants.artifacts;
General Comments 0
You need to be logged in to leave comments. Login now