| @@ -0,0 +1,31 | |||||
|
|
1 | # design notes | |||
|
|
2 | ||||
|
|
3 | ## core model | |||
|
|
4 | ||||
|
|
5 | - OutgoingRegistry (Variant) | |||
|
|
6 | исходящая конфигурация | |||
|
|
7 | - [provider] configuration | |||
|
|
8 | - [container, live] slots | |||
|
|
9 | набор вариантов (слотов) | |||
|
|
10 | - [property] primarySlot | |||
|
|
11 | - AssemblyRegistry (Varaint, Slot) | |||
|
|
12 | содержимое слота может быть добавлено после появления слота в OutgoingRegistry | |||
|
|
13 | - assembleTask | |||
|
|
14 | - inputs | |||
|
|
15 | - compile unit output (CompileUnit, String) | |||
|
|
16 | - direct object (task, file collection, etc.) | |||
|
|
17 | - artifact: directory | |||
|
|
18 | - customTask | |||
|
|
19 | - artifact: FileSystemLocation | |||
|
|
20 | ||||
|
|
21 | ## extension | |||
|
|
22 | ||||
|
|
23 | - adapter | |||
|
|
24 | - whenFinalized | |||
|
|
25 | - dsl | |||
|
|
26 | - variant(name) | |||
|
|
27 | - slot(name) | |||
|
|
28 | - from*** | |||
|
|
29 | - whenFinalized | |||
|
|
30 | - whenOutgoingConfiguration | |||
|
|
31 | - whenOutgoingSlot | |||
| @@ -0,0 +1,99 | |||||
|
|
1 | package org.implab.gradle.variants.artifacts; | |||
|
|
2 | ||||
|
|
3 | import java.util.LinkedHashMap; | |||
|
|
4 | import java.util.Map; | |||
|
|
5 | import java.util.Optional; | |||
|
|
6 | import java.util.function.Function; | |||
|
|
7 | ||||
|
|
8 | import org.eclipse.jdt.annotation.NonNullByDefault; | |||
|
|
9 | import org.gradle.api.InvalidUserDataException; | |||
|
|
10 | import org.gradle.api.Task; | |||
|
|
11 | import org.gradle.api.file.Directory; | |||
|
|
12 | import org.gradle.api.file.FileCollection; | |||
|
|
13 | import org.gradle.api.file.FileSystemLocation; | |||
|
|
14 | import org.gradle.api.model.ObjectFactory; | |||
|
|
15 | import org.gradle.api.provider.Provider; | |||
|
|
16 | import org.gradle.api.tasks.Copy; | |||
|
|
17 | import org.gradle.api.tasks.TaskContainer; | |||
|
|
18 | import org.gradle.api.tasks.TaskProvider; | |||
|
|
19 | import org.gradle.language.base.plugins.LifecycleBasePlugin; | |||
|
|
20 | ||||
|
|
21 | @NonNullByDefault | |||
|
|
22 | public class ArtifactAssemblyRegistry implements ArtifactAssemblies { | |||
|
|
23 | private final ObjectFactory objects; | |||
|
|
24 | private final TaskContainer tasks; | |||
|
|
25 | private final Map<ArtifactSlot, ArtifactAssembly> assemblies = new LinkedHashMap<>(); | |||
|
|
26 | ||||
|
|
27 | public ArtifactAssemblyRegistry(ObjectFactory objects, TaskContainer tasks) { | |||
|
|
28 | this.objects = objects; | |||
|
|
29 | this.tasks = tasks; | |||
|
|
30 | } | |||
|
|
31 | ||||
|
|
32 | public ArtifactAssembly register( | |||
|
|
33 | ArtifactSlot slot, | |||
|
|
34 | String taskName, | |||
|
|
35 | Provider<Directory> outputDirectory, | |||
|
|
36 | FileCollection sources) { | |||
|
|
37 | ||||
|
|
38 | var task = tasks.register(taskName, Copy.class, copy -> { | |||
|
|
39 | copy.setGroup(LifecycleBasePlugin.BUILD_GROUP); | |||
|
|
40 | copy.into(outputDirectory); | |||
|
|
41 | copy.from(sources); | |||
|
|
42 | }); | |||
|
|
43 | ||||
|
|
44 | return register(slot, task, t -> outputDirectory); | |||
|
|
45 | } | |||
|
|
46 | ||||
|
|
47 | public <T extends Task> ArtifactAssembly register( | |||
|
|
48 | ArtifactSlot slot, | |||
|
|
49 | TaskProvider<T> task, | |||
|
|
50 | Function<? super T, ? extends Provider<? extends FileSystemLocation>> mapOutputDirectory) { | |||
|
|
51 | if (assemblies.containsKey(slot)) { | |||
|
|
52 | throw new InvalidUserDataException("Artifact assembly '" + slot + "' is already registered"); | |||
|
|
53 | } | |||
|
|
54 | var outputArtifact = task.flatMap(t -> mapOutputDirectory.apply(t)); | |||
|
|
55 | ||||
|
|
56 | var output = objects.fileCollection() | |||
|
|
57 | .from(outputArtifact) | |||
|
|
58 | .builtBy(task); | |||
|
|
59 | ||||
|
|
60 | var assembly = new Assembly(outputArtifact, task, output); | |||
|
|
61 | assemblies.put(slot, assembly); | |||
|
|
62 | return assembly; | |||
|
|
63 | } | |||
|
|
64 | ||||
|
|
65 | @Override | |||
|
|
66 | public Optional<ArtifactAssembly> find(ArtifactSlot slot) { | |||
|
|
67 | return Optional.ofNullable(assemblies.get(slot)); | |||
|
|
68 | } | |||
|
|
69 | ||||
|
|
70 | static class Assembly implements ArtifactAssembly { | |||
|
|
71 | ||||
|
|
72 | private final Provider<? extends FileSystemLocation> artifact; | |||
|
|
73 | private final TaskProvider<? extends Task> task; | |||
|
|
74 | private final FileCollection fileCollection; | |||
|
|
75 | ||||
|
|
76 | Assembly(Provider<? extends FileSystemLocation> artifact, TaskProvider<? extends Task> task, | |||
|
|
77 | FileCollection fileCollection) { | |||
|
|
78 | this.artifact = artifact; | |||
|
|
79 | this.task = task; | |||
|
|
80 | this.fileCollection = fileCollection; | |||
|
|
81 | } | |||
|
|
82 | ||||
|
|
83 | @Override | |||
|
|
84 | public Provider<? extends FileSystemLocation> getArtifact() { | |||
|
|
85 | return artifact; | |||
|
|
86 | } | |||
|
|
87 | ||||
|
|
88 | @Override | |||
|
|
89 | public TaskProvider<? extends Task> getAssemblyTask() { | |||
|
|
90 | return task; | |||
|
|
91 | } | |||
|
|
92 | ||||
|
|
93 | @Override | |||
|
|
94 | public FileCollection getFileCollection() { | |||
|
|
95 | return fileCollection; | |||
|
|
96 | } | |||
|
|
97 | ||||
|
|
98 | } | |||
|
|
99 | } | |||
| @@ -0,0 +1,45 | |||||
|
|
1 | package org.implab.gradle.variants.artifacts.internal; | |||
|
|
2 | ||||
|
|
3 | import java.util.LinkedHashMap; | |||
|
|
4 | import java.util.Map; | |||
|
|
5 | import java.util.Optional; | |||
|
|
6 | ||||
|
|
7 | import org.gradle.api.artifacts.ConfigurationContainer; | |||
|
|
8 | import org.gradle.api.model.ObjectFactory; | |||
|
|
9 | import org.gradle.api.provider.ProviderFactory; | |||
|
|
10 | import org.implab.gradle.variants.artifacts.OutgoingConfiguration; | |||
|
|
11 | import org.implab.gradle.variants.core.Variant; | |||
|
|
12 | ||||
|
|
13 | public class OutgoingRegistry { | |||
|
|
14 | private final Map<Variant, DefaultOutgoingConfiguration> outgoingByVariant = new LinkedHashMap<>(); | |||
|
|
15 | ||||
|
|
16 | private final ConfigurationContainer configurations; | |||
|
|
17 | private final ObjectFactory objects; | |||
|
|
18 | private final ProviderFactory providers; | |||
|
|
19 | ||||
|
|
20 | public OutgoingRegistry(ConfigurationContainer configurations, ObjectFactory objects, ProviderFactory providers) { | |||
|
|
21 | this.configurations = configurations; | |||
|
|
22 | this.objects = objects; | |||
|
|
23 | this.providers = providers; | |||
|
|
24 | } | |||
|
|
25 | ||||
|
|
26 | public Optional<OutgoingConfiguration> findOutgoing(Variant variant) { | |||
|
|
27 | return Optional.ofNullable(outgoingByVariant.get(variant)); | |||
|
|
28 | } | |||
|
|
29 | ||||
|
|
30 | public OutgoingConfiguration maybeCreate(Variant variant) { | |||
|
|
31 | return outgoingByVariant.computeIfAbsent(variant, this::newOutgoingConfiguration); | |||
|
|
32 | } | |||
|
|
33 | ||||
|
|
34 | private DefaultOutgoingConfiguration newOutgoingConfiguration(Variant variant) { | |||
|
|
35 | var configuration = configurations.register(outgoingConfigurationName(variant)); | |||
|
|
36 | ||||
|
|
37 | return new DefaultOutgoingConfiguration(variant, configuration, objects, providers); | |||
|
|
38 | } | |||
|
|
39 | ||||
|
|
40 | String outgoingConfigurationName(Variant variant) { | |||
|
|
41 | return variant.getName() + "Elements"; | |||
|
|
42 | } | |||
|
|
43 | ||||
|
|
44 | ||||
|
|
45 | } | |||
| @@ -1,64 +1,71 | |||||
| 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.OutgoingArtifactSlotSpec; |
|
8 | import org.implab.gradle.variants.artifacts.OutgoingArtifactSlotSpec; | |
| 8 | import org.implab.gradle.variants.artifacts.OutgoingConfigurationSpec; |
|
9 | import org.implab.gradle.variants.artifacts.OutgoingConfigurationSpec; | |
| 9 | import org.implab.gradle.variants.artifacts.VariantArtifactsContext; |
|
10 | import org.implab.gradle.variants.artifacts.VariantArtifactsContext; | |
| 10 | import org.implab.gradle.variants.artifacts.VariantArtifactsExtension; |
|
11 | import org.implab.gradle.variants.artifacts.VariantArtifactsExtension; | |
| 11 | import org.implab.gradle.variants.artifacts.VariantArtifactsSpec; |
|
12 | import org.implab.gradle.variants.artifacts.VariantArtifactsSpec; | |
| 12 |
import org.implab.gradle.variants.artifacts.internal. |
|
13 | import org.implab.gradle.variants.artifacts.internal.OutgoingRegistry; | |
| 13 | import org.implab.gradle.variants.core.Variant; |
|
14 | import org.implab.gradle.variants.core.Variant; | |
| 14 | import org.implab.gradle.variants.core.VariantsExtension; |
|
15 | import org.implab.gradle.variants.core.VariantsExtension; | |
| 15 |
|
16 | |||
| 16 | public abstract class VariantArtifactsPlugin implements Plugin<Project> { |
|
17 | public abstract class VariantArtifactsPlugin implements Plugin<Project> { | |
| 17 |
|
18 | |||
| 18 | @Override |
|
19 | @Override | |
| 19 | public void apply(Project target) { |
|
20 | public void apply(Project target) { | |
| 20 | var extensions = target.getExtensions(); |
|
21 | var extensions = target.getExtensions(); | |
| 21 | var objects = target.getObjects(); |
|
22 | var objects = target.getObjects(); | |
|
|
23 | var providers = target.getProviders(); | |||
|
|
24 | var configurations = target.getConfigurations(); | |||
|
|
25 | var tasks = target.getTasks(); | |||
| 22 |
|
26 | |||
| 23 | // 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. | |
| 24 | target.getPlugins().apply(VariantsPlugin.class); |
|
28 | target.getPlugins().apply(VariantsPlugin.class); | |
| 25 | // Access the VariantsExtension to configure variant sources. |
|
29 | // Access the VariantsExtension to configure variant sources. | |
| 26 | var variantsExtension = extensions.getByType(VariantsExtension.class); |
|
30 | var variantsExtension = extensions.getByType(VariantsExtension.class); | |
| 27 |
|
31 | |||
| 28 | var deferred = new Deferred<VariantArtifactsRegistry>(); |
|
32 | var outgoing = new OutgoingRegistry(configurations, objects, providers); | |
|
|
33 | var assemblies = new ArtifactAssemblyRegistry(objects, tasks); | |||
|
|
34 | ||||
|
|
35 | var deferred = new Deferred<VariantArtifactsContext>(); | |||
| 29 |
|
36 | |||
| 30 | variantsExtension.whenFinalized(variants -> { |
|
37 | variantsExtension.whenFinalized(variants -> { | |
| 31 | deferred.resolve(new VariantArtifactsRegistry(variants)); |
|
38 | deferred.resolve(new VariantArtifactsRegistry(variants)); | |
| 32 | }); |
|
39 | }); | |
| 33 |
|
40 | |||
| 34 | var variantArtifacts = new VariantArtifactsExtension() { |
|
41 | var variantArtifacts = new VariantArtifactsExtension() { | |
| 35 |
|
42 | |||
| 36 | @Override |
|
43 | @Override | |
| 37 | public void variant(String variantName, Action<? super VariantArtifactsSpec> action) { |
|
44 | public void variant(String variantName, Action<? super VariantArtifactsSpec> action) { | |
| 38 |
deferred.whenResolved( |
|
45 | deferred.whenResolved(context -> registry.configureVariant( | |
| 39 | objects.named(Variant.class, variantName), action)); |
|
46 | objects.named(Variant.class, variantName), action)); | |
| 40 | } |
|
47 | } | |
| 41 |
|
48 | |||
| 42 | @Override |
|
49 | @Override | |
| 43 | public void whenFinalized(Action<? super VariantArtifactsContext> action) { |
|
50 | public void whenFinalized(Action<? super VariantArtifactsContext> action) { | |
| 44 | deferred.whenResolved(registry -> action.execute(registry.variantsContext())); |
|
51 | deferred.whenResolved(registry -> action.execute(registry.variantsContext())); | |
| 45 | } |
|
52 | } | |
| 46 |
|
53 | |||
| 47 | @Override |
|
54 | @Override | |
| 48 | public void whenOutgoingVariant(Action<? super OutgoingConfigurationSpec> action) { |
|
55 | public void whenOutgoingVariant(Action<? super OutgoingConfigurationSpec> action) { | |
| 49 | deferred.whenResolved(registry -> registry.configureOutgoing(action)); |
|
56 | deferred.whenResolved(registry -> registry.configureOutgoing(action)); | |
| 50 |
|
57 | |||
| 51 | } |
|
58 | } | |
| 52 |
|
59 | |||
| 53 | @Override |
|
60 | @Override | |
| 54 | public void whenOutgoingSlot(Action<? super OutgoingArtifactSlotSpec> action) { |
|
61 | public void whenOutgoingSlot(Action<? super OutgoingArtifactSlotSpec> action) { | |
| 55 | deferred.whenResolved(registry -> registry.configureOutgoingSlot(action)); |
|
62 | deferred.whenResolved(registry -> registry.configureOutgoingSlot(action)); | |
| 56 | } |
|
63 | } | |
| 57 |
|
64 | |||
| 58 | }; |
|
65 | }; | |
| 59 |
|
66 | |||
| 60 | extensions.add(VariantArtifactsExtension.class, "variantArtifacts", variantArtifacts); |
|
67 | extensions.add(VariantArtifactsExtension.class, "variantArtifacts", variantArtifacts); | |
| 61 |
|
68 | |||
| 62 | } |
|
69 | } | |
| 63 |
|
70 | |||
| 64 | } |
|
71 | } | |
| @@ -1,22 +1,33 | |||||
| 1 | package org.implab.gradle.variants.artifacts; |
|
1 | package org.implab.gradle.variants.artifacts; | |
| 2 |
|
2 | |||
|
|
3 | import java.util.Optional; | |||
|
|
4 | ||||
| 3 | import org.eclipse.jdt.annotation.NonNullByDefault; |
|
5 | import org.eclipse.jdt.annotation.NonNullByDefault; | |
|
|
6 | import org.gradle.api.InvalidUserDataException; | |||
| 4 |
|
7 | |||
| 5 | /** |
|
8 | /** | |
| 6 | * Resolves stateful slot assemblies from cheap slot identities. |
|
9 | * Resolves stateful slot assemblies from cheap slot identities. | |
| 7 | * |
|
10 | * | |
| 8 | * <p>The returned assembly is a materialized build-model handle. It may expose lazy Gradle providers, but |
|
11 | * <p> | |
|
|
12 | * The returned assembly is a materialized build-model handle. It may expose | |||
|
|
13 | * lazy Gradle providers, but | |||
| 9 | * it is no longer an identity object suitable for replayable discovery. |
|
14 | * it is no longer an identity object suitable for replayable discovery. | |
| 10 | */ |
|
15 | */ | |
| 11 | @NonNullByDefault |
|
16 | @NonNullByDefault | |
| 12 | public interface ArtifactAssemblies { |
|
17 | public interface ArtifactAssemblies { | |
| 13 | /** |
|
18 | /** | |
| 14 | * Resolves the assembly for the given slot. |
|
19 | * Resolves the assembly for the given slot. | |
| 15 | * |
|
20 | * | |
| 16 | * <p>This call materializes the build-facing body of the slot from its identity. |
|
21 | * <p> | |
|
|
22 | * This call materializes the build-facing body of the slot from its identity. | |||
| 17 | * |
|
23 | * | |
| 18 | * @param slot slot identity inside a variant outgoing contract |
|
24 | * @param slot slot identity inside a variant outgoing contract | |
| 19 | * @return assembly handle for the slot |
|
25 | * @return assembly handle for the slot | |
| 20 | */ |
|
26 | */ | |
| 21 |
ArtifactAssembly re |
|
27 | default ArtifactAssembly require(ArtifactSlot slot) { | |
|
|
28 | return find(slot) | |||
|
|
29 | .orElseThrow(() -> new InvalidUserDataException("Artifact assembly '" + slot + "' isn't registered")); | |||
| 22 | } |
|
30 | } | |
|
|
31 | ||||
|
|
32 | Optional<ArtifactAssembly> find(ArtifactSlot slot); | |||
|
|
33 | } | |||
| @@ -1,32 +1,43 | |||||
| 1 | package org.implab.gradle.variants.artifacts; |
|
1 | package org.implab.gradle.variants.artifacts; | |
| 2 |
|
2 | |||
| 3 | import org.gradle.api.Task; |
|
3 | import org.gradle.api.Task; | |
|
|
4 | import org.gradle.api.file.FileCollection; | |||
| 4 | import org.gradle.api.file.FileSystemLocation; |
|
5 | import org.gradle.api.file.FileSystemLocation; | |
| 5 | import org.gradle.api.provider.Provider; |
|
6 | import org.gradle.api.provider.Provider; | |
| 6 | import org.gradle.api.tasks.TaskProvider; |
|
7 | import org.gradle.api.tasks.TaskProvider; | |
| 7 |
|
8 | |||
| 8 | /** |
|
9 | /** | |
| 9 | * Materialized body of an {@link ArtifactSlot}. |
|
10 | * Materialized body of an {@link ArtifactSlot}. | |
| 10 | * |
|
11 | * | |
| 11 | * <p>An assembly is a stateful build object obtained on demand from |
|
12 | * <p> | |
| 12 | * {@link ArtifactAssemblies#resolveSlot(ArtifactSlot)}. It describes how the slot artifact is produced and |
|
13 | * An assembly is a stateful build object obtained on demand from | |
|
|
14 | * {@link ArtifactAssemblies#require(ArtifactSlot)}. It describes how the | |||
|
|
15 | * slot artifact is produced and | |||
| 13 | * where that single published artifact will appear. |
|
16 | * where that single published artifact will appear. | |
| 14 | */ |
|
17 | */ | |
| 15 | public interface ArtifactAssembly { |
|
18 | public interface ArtifactAssembly { | |
| 16 |
|
19 | |||
| 17 | /** |
|
20 | /** | |
| 18 | * Returns the published artifact produced for the slot. |
|
21 | * Returns the published artifact produced for the slot. | |
| 19 | * |
|
22 | * | |
| 20 | * <p>A slot is expected to produce exactly one artifact represented by one file or one directory. |
|
23 | * <p> | |
|
|
24 | * A slot is expected to produce exactly one artifact represented by one file or | |||
|
|
25 | * one directory. | |||
| 21 | * |
|
26 | * | |
| 22 | * @return provider of the produced artifact location |
|
27 | * @return provider of the produced artifact location | |
| 23 | */ |
|
28 | */ | |
| 24 | Provider<? extends FileSystemLocation> getArtifact(); |
|
29 | Provider<? extends FileSystemLocation> getArtifact(); | |
| 25 |
|
30 | |||
| 26 | /** |
|
31 | /** | |
| 27 | * Returns the task that assembles the slot artifact. |
|
32 | * Returns the task that assembles the slot artifact. | |
| 28 | * |
|
33 | * | |
| 29 | * @return provider of the assembly task |
|
34 | * @return provider of the assembly task | |
| 30 | */ |
|
35 | */ | |
| 31 | TaskProvider<? extends Task> getAssemblyTask(); |
|
36 | TaskProvider<? extends Task> getAssemblyTask(); | |
|
|
37 | ||||
|
|
38 | /** | |||
|
|
39 | * File collection, contains {@link #getArtifact()} and build dependency on | |||
|
|
40 | * {@link #getAssemblyTask()}. This is a conventional property. | |||
|
|
41 | */ | |||
|
|
42 | FileCollection getFileCollection(); | |||
| 32 | } |
|
43 | } | |
| @@ -1,24 +1,17 | |||||
| 1 | package org.implab.gradle.variants.artifacts; |
|
1 | package org.implab.gradle.variants.artifacts; | |
| 2 |
|
2 | |||
| 3 | /** |
|
3 | /** | |
| 4 | * DSL model for selecting named outputs from a chosen source scope. |
|
4 | * DSL model for selecting named outputs from a chosen source scope. | |
| 5 | * |
|
5 | * | |
| 6 | * <p>The selected outputs are inputs to slot assembly. They do not create additional outgoing slots or |
|
6 | * <p>The selected outputs are inputs to slot assembly. They do not create additional outgoing slots or | |
| 7 | * affect slot identity. |
|
7 | * affect slot identity. | |
| 8 | */ |
|
8 | */ | |
| 9 | public interface OutputSelectionSpec { |
|
9 | public interface OutputSelectionSpec { | |
| 10 | /** |
|
10 | /** | |
| 11 | * Selects one named output. |
|
|||
| 12 | * |
|
|||
| 13 | * @param name output name |
|
|||
| 14 | */ |
|
|||
| 15 | void output(String name); |
|
|||
| 16 |
|
||||
| 17 | /** |
|
|||
| 18 | * Selects several named outputs. |
|
11 | * Selects several named outputs. | |
| 19 | * |
|
12 | * | |
| 20 | * @param name first output name |
|
13 | * @param name first output name | |
| 21 | * @param extra additional output names |
|
14 | * @param extra additional output names | |
| 22 | */ |
|
15 | */ | |
| 23 | void output(String name, String... extra); |
|
16 | void output(String name, String... extra); | |
| 24 | } |
|
17 | } | |
| @@ -1,34 +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.implab.gradle.variants.core.Variant; |
|
7 | import org.implab.gradle.variants.core.Variant; | |
| 7 | import org.implab.gradle.variants.core.VariantsView; |
|
8 | import org.implab.gradle.variants.core.VariantsView; | |
| 8 |
|
9 | |||
| 9 | /** |
|
10 | /** | |
| 10 | * Контекст работы с вариантами публикации, становится доступным после |
|
11 | * Контекст работы с вариантами публикации, становится доступным после | |
| 11 | * финализации модели вариантов. Фактически является живой моделью |
|
12 | * финализации модели вариантов. Фактически является живой моделью | |
| 12 | */ |
|
13 | */ | |
| 13 | public interface VariantArtifactsContext { |
|
14 | public interface VariantArtifactsContext { | |
| 14 |
|
15 | |||
| 15 | /** |
|
16 | /** | |
| 16 | * Зафиксированное представление о вариантах на основе которого адаптеры могут |
|
17 | * Зафиксированное представление о вариантах на основе которого адаптеры могут | |
| 17 | * конфигурировать артефакты и исходящие конфигурации |
|
18 | * конфигурировать артефакты и исходящие конфигурации | |
| 18 | */ |
|
19 | */ | |
| 19 | VariantsView getVariants(); |
|
20 | VariantsView getVariants(); | |
| 20 |
|
21 | |||
| 21 | ArtifactAssemblies getAssemblies(); |
|
22 | ArtifactAssemblies getAssemblies(); | |
| 22 |
|
23 | |||
| 23 | /** |
|
24 | /** | |
| 24 | * Replayable hook для всех объявленных конфигураций |
|
25 | * Replayable hook для всех объявленных конфигураций | |
| 25 | */ |
|
26 | */ | |
| 26 | void all(Action<? super OutgoingConfiguration> action); |
|
27 | void all(Action<? super OutgoingConfiguration> action); | |
| 27 |
|
28 | |||
| 28 |
Optional<OutgoingConfiguration> find |
|
29 | Optional<OutgoingConfiguration> findOutgoing(Variant variant); | |
| 29 |
|
30 | |||
| 30 |
OutgoingConfiguration require |
|
31 | default OutgoingConfiguration requireOutgoing(Variant variant) { | |
|
|
32 | return findOutgoing(variant) | |||
|
|
33 | .orElseThrow(() -> new InvalidUserDataException("Outgoing variant '" + variant + "' isn't registered")); | |||
|
|
34 | } | |||
| 31 |
|
35 | |||
| 32 | ArtifactAssemblyRules slotRules(ArtifactSlot slot); |
|
36 | ArtifactAssemblyRules slotRules(ArtifactSlot slot); | |
| 33 |
|
37 | |||
| 34 | } |
|
38 | } | |
| @@ -1,52 +1,82 | |||||
| 1 | package org.implab.gradle.variants.artifacts.internal; |
|
1 | package org.implab.gradle.variants.artifacts.internal; | |
| 2 |
|
2 | |||
|
|
3 | import java.util.HashSet; | |||
|
|
4 | import java.util.LinkedList; | |||
|
|
5 | import java.util.List; | |||
| 3 | import java.util.Set; |
|
6 | import java.util.Set; | |
|
|
7 | import java.util.function.Consumer; | |||
|
|
8 | import java.util.stream.Stream; | |||
| 4 |
|
9 | |||
| 5 | import org.gradle.api.Action; |
|
10 | import org.gradle.api.Action; | |
| 6 | import org.implab.gradle.variants.artifacts.ArtifactAssemblyRules; |
|
11 | import org.gradle.api.model.ObjectFactory; | |
|
|
12 | import org.implab.gradle.common.core.lang.Strings; | |||
| 7 | import org.implab.gradle.variants.artifacts.ArtifactAssemblySpec; |
|
13 | import org.implab.gradle.variants.artifacts.ArtifactAssemblySpec; | |
| 8 |
import org.implab.gradle.variants.core. |
|
14 | import org.implab.gradle.variants.core.Layer; | |
|
|
15 | import org.implab.gradle.variants.core.Role; | |||
| 9 | import org.implab.gradle.variants.artifacts.OutputSelectionSpec; |
|
16 | import org.implab.gradle.variants.artifacts.OutputSelectionSpec; | |
| 10 |
|
17 | |||
|
|
18 | /** | |||
|
|
19 | * Реализация DSL модели, строит набор {@link SlotContribution}. При построении набора | |||
|
|
20 | * правила и корректность не проверяются. По окончании использования клиент | |||
|
|
21 | * вызывает метод {@link #process(Consumer)} для обработки результатов. | |||
|
|
22 | * | |||
|
|
23 | */ | |||
| 11 | final class BoundArtifactAssemblySpec implements ArtifactAssemblySpec { |
|
24 | final class BoundArtifactAssemblySpec implements ArtifactAssemblySpec { | |
| 12 | private final VariantArtifactsRegistry registry; |
|
25 | private final List<SlotContribution> contributions = new LinkedList<>(); | |
| 13 |
private final |
|
26 | private final ObjectFactory objectFactory; | |
| 14 | private final ArtifactAssemblyRules rules; |
|
|||
| 15 |
|
27 | |||
| 16 | BoundArtifactAssemblySpec( |
|
28 | BoundArtifactAssemblySpec(ObjectFactory objectFactory) { | |
| 17 | VariantArtifactsRegistry registry, |
|
29 | this.objectFactory = objectFactory; | |
| 18 | Variant variant, |
|
|||
| 19 | ArtifactAssemblyRules rules) { |
|
|||
| 20 | this.registry = registry; |
|
|||
| 21 | this.variant = variant; |
|
|||
| 22 | this.rules = rules; |
|
|||
| 23 | } |
|
30 | } | |
| 24 |
|
31 | |||
| 25 | @Override |
|
32 | @Override | |
| 26 | public void from(Object artifact) { |
|
33 | public void from(Object artifact) { | |
| 27 |
|
|
34 | contributions.add(new DirectContribution(artifact)); | |
| 28 | } |
|
35 | } | |
| 29 |
|
36 | |||
| 30 | @Override |
|
37 | @Override | |
| 31 | public void fromVariant(Action<? super OutputSelectionSpec> action) { |
|
38 | public void fromVariant(Action<? super OutputSelectionSpec> action) { | |
| 32 |
|
|
39 | contributions.add(new VariantOutputsContribution(outputs(action))); | |
| 33 | } |
|
40 | } | |
| 34 |
|
41 | |||
| 35 | @Override |
|
42 | @Override | |
| 36 | public void fromRole(String roleName, Action<? super OutputSelectionSpec> action) { |
|
43 | public void fromRole(String roleName, Action<? super OutputSelectionSpec> action) { | |
| 37 | var role = registry.requireRole(variant, roleName); |
|
44 | ||
| 38 |
|
|
45 | contributions.add(new RoleOutputsContribution( | |
|
|
46 | objectFactory.named(Role.class, roleName), | |||
|
|
47 | outputs(action))); | |||
| 39 | } |
|
48 | } | |
| 40 |
|
49 | |||
| 41 | @Override |
|
50 | @Override | |
| 42 | public void fromLayer(String layerName, Action<? super OutputSelectionSpec> action) { |
|
51 | public void fromLayer(String layerName, Action<? super OutputSelectionSpec> action) { | |
| 43 | var layer = registry.requireLayer(variant, layerName); |
|
52 | contributions.add(new LayerOutputsContribution( | |
| 44 | rules.addLayerOutputs(layer, outputs(action)); |
|
53 | objectFactory.named(Layer.class, layerName), | |
|
|
54 | outputs(action))); | |||
|
|
55 | } | |||
|
|
56 | ||||
|
|
57 | void process(Consumer<? super SlotContribution> consumer) { | |||
|
|
58 | contributions.forEach(consumer); | |||
| 45 | } |
|
59 | } | |
| 46 |
|
60 | |||
| 47 | private static Set<String> outputs(Action<? super OutputSelectionSpec> action) { |
|
61 | private static Set<String> outputs(Action<? super OutputSelectionSpec> action) { | |
| 48 |
var spec = new |
|
62 | var spec = new OutputsSetSpec(); | |
| 49 | action.execute(spec); |
|
63 | action.execute(spec); | |
| 50 | return spec.outputs(); |
|
64 | return spec.outputs(); | |
| 51 | } |
|
65 | } | |
|
|
66 | ||||
|
|
67 | private static class OutputsSetSpec implements OutputSelectionSpec { | |||
|
|
68 | private final Set<String> outputs = new HashSet<>(); | |||
|
|
69 | ||||
|
|
70 | @Override | |||
|
|
71 | public void output(String name, String... extra) { | |||
|
|
72 | Stream.concat(Stream.of(name), Stream.of(extra)) | |||
|
|
73 | .map(Strings::requireNonBlank) | |||
|
|
74 | .forEach(outputs::add); | |||
| 52 | } |
|
75 | } | |
|
|
76 | ||||
|
|
77 | Set<String> outputs() { | |||
|
|
78 | return Set.copyOf(outputs); | |||
|
|
79 | } | |||
|
|
80 | ||||
|
|
81 | } | |||
|
|
82 | } | |||
| @@ -1,11 +1,17 | |||||
| 1 | package org.implab.gradle.variants.artifacts.internal; |
|
1 | package org.implab.gradle.variants.artifacts.internal; | |
| 2 |
|
2 | |||
|
|
3 | import java.util.function.Consumer; | |||
|
|
4 | ||||
| 3 | public interface SlotContributionVisitor { |
|
5 | public interface SlotContributionVisitor { | |
| 4 | void visit(DirectContribution contribution); |
|
6 | void visit(DirectContribution contribution); | |
| 5 |
|
7 | |||
| 6 | void visit(VariantOutputsContribution contribution); |
|
8 | void visit(VariantOutputsContribution contribution); | |
| 7 |
|
9 | |||
| 8 | void visit(RoleOutputsContribution contribution); |
|
10 | void visit(RoleOutputsContribution contribution); | |
| 9 |
|
11 | |||
| 10 | void visit(LayerOutputsContribution contribution); |
|
12 | void visit(LayerOutputsContribution contribution); | |
|
|
13 | ||||
|
|
14 | default Consumer<SlotContribution> consumer() { | |||
|
|
15 | return slot -> slot.accept(this); | |||
| 11 | } |
|
16 | } | |
|
|
17 | } | |||
| 1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
| 1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
| 1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
| 1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
| 1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
| 1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
| 1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
| 1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
| 1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now
