| @@ -0,0 +1,29 | |||
|
|
1 | package org.implab.gradle.variants; | |
|
|
2 | ||
|
|
3 | import org.gradle.api.Plugin; | |
|
|
4 | import org.gradle.api.Project; | |
|
|
5 | import org.implab.gradle.common.core.lang.Deferred; | |
|
|
6 | import org.implab.gradle.variants.artifacts.VariantArtifactsContext; | |
|
|
7 | import org.implab.gradle.variants.core.VariantsExtension; | |
|
|
8 | ||
|
|
9 | public abstract class VariantArtifactsPlugin implements Plugin<Project> { | |
|
|
10 | ||
|
|
11 | @Override | |
|
|
12 | public void apply(Project target) { | |
|
|
13 | var extensions = target.getExtensions(); | |
|
|
14 | ||
|
|
15 | // Apply the main VariantsPlugin to ensure the core variant model is available. | |
|
|
16 | target.getPlugins().apply(VariantsPlugin.class); | |
|
|
17 | // Access the VariantsExtension to configure variant sources. | |
|
|
18 | var variantsExtension = extensions.getByType(VariantsExtension.class); | |
|
|
19 | ||
|
|
20 | var deferred = new Deferred<VariantArtifactsContext>(); | |
|
|
21 | ||
|
|
22 | variantsExtension.whenFinalized(variants -> { | |
|
|
23 | ||
|
|
24 | }); | |
|
|
25 | ||
|
|
26 | ||
|
|
27 | } | |
|
|
28 | ||
|
|
29 | } | |
| @@ -0,0 +1,22 | |||
|
|
1 | package org.implab.gradle.variants.artifacts; | |
|
|
2 | ||
|
|
3 | import org.eclipse.jdt.annotation.NonNullByDefault; | |
|
|
4 | ||
|
|
5 | /** | |
|
|
6 | * Resolves stateful slot assemblies from cheap slot identities. | |
|
|
7 | * | |
|
|
8 | * <p>The returned assembly is a materialized build-model handle. It may expose lazy Gradle providers, but | |
|
|
9 | * it is no longer an identity object suitable for replayable discovery. | |
|
|
10 | */ | |
|
|
11 | @NonNullByDefault | |
|
|
12 | public interface ArtifactAssemblies { | |
|
|
13 | /** | |
|
|
14 | * Resolves the assembly for the given slot. | |
|
|
15 | * | |
|
|
16 | * <p>This call materializes the build-facing body of the slot from its identity. | |
|
|
17 | * | |
|
|
18 | * @param slot slot identity inside a variant outgoing contract | |
|
|
19 | * @return assembly handle for the slot | |
|
|
20 | */ | |
|
|
21 | ArtifactAssembly resolveSlot(ArtifactSlot slot); | |
|
|
22 | } | |
| @@ -0,0 +1,32 | |||
|
|
1 | package org.implab.gradle.variants.artifacts; | |
|
|
2 | ||
|
|
3 | import org.gradle.api.Task; | |
|
|
4 | import org.gradle.api.file.FileSystemLocation; | |
|
|
5 | import org.gradle.api.provider.Provider; | |
|
|
6 | import org.gradle.api.tasks.TaskProvider; | |
|
|
7 | ||
|
|
8 | /** | |
|
|
9 | * Materialized body of an {@link ArtifactSlot}. | |
|
|
10 | * | |
|
|
11 | * <p>An assembly is a stateful build object obtained on demand from | |
|
|
12 | * {@link ArtifactAssemblies#resolveSlot(ArtifactSlot)}. It describes how the slot artifact is produced and | |
|
|
13 | * where that single published artifact will appear. | |
|
|
14 | */ | |
|
|
15 | public interface ArtifactAssembly { | |
|
|
16 | ||
|
|
17 | /** | |
|
|
18 | * Returns the published artifact produced for the slot. | |
|
|
19 | * | |
|
|
20 | * <p>A slot is expected to produce exactly one artifact represented by one file or one directory. | |
|
|
21 | * | |
|
|
22 | * @return provider of the produced artifact location | |
|
|
23 | */ | |
|
|
24 | Provider<? extends FileSystemLocation> getArtifact(); | |
|
|
25 | ||
|
|
26 | /** | |
|
|
27 | * Returns the task that assembles the slot artifact. | |
|
|
28 | * | |
|
|
29 | * @return provider of the assembly task | |
|
|
30 | */ | |
|
|
31 | TaskProvider<? extends Task> getAssemblyTask(); | |
|
|
32 | } | |
| @@ -0,0 +1,60 | |||
|
|
1 | package org.implab.gradle.variants.artifacts; | |
|
|
2 | ||
|
|
3 | import org.gradle.api.Action; | |
|
|
4 | import groovy.lang.Closure; | |
|
|
5 | import org.implab.gradle.common.core.lang.Closures; | |
|
|
6 | ||
|
|
7 | /** | |
|
|
8 | * DSL model describing how a slot artifact is assembled. | |
|
|
9 | * | |
|
|
10 | * <p>Selection rules declared here may refer to internal build topology such as roles, layers or units. | |
|
|
11 | * Those selectors influence slot assembly only and do not become part of published artifact identity. | |
|
|
12 | * | |
|
|
13 | * <p>Regardless of the number of declared inputs, a slot is expected to materialize to a single published | |
|
|
14 | * artifact. | |
|
|
15 | */ | |
|
|
16 | public interface ArtifactAssemblySpec { | |
|
|
17 | /** | |
|
|
18 | * Contributes direct input material to the slot assembly. | |
|
|
19 | * | |
|
|
20 | * <p>The resulting slot still represents one published artifact. | |
|
|
21 | * | |
|
|
22 | * @param artifact direct input notation understood by the implementation | |
|
|
23 | */ | |
|
|
24 | void from(Object artifact); | |
|
|
25 | ||
|
|
26 | /** | |
|
|
27 | * Selects outputs from the whole variant scope. | |
|
|
28 | * | |
|
|
29 | * @param action output selection rule | |
|
|
30 | */ | |
|
|
31 | void fromVariant(Action<? super OutputSelectionSpec> action); | |
|
|
32 | ||
|
|
33 | default void fromVariant(Closure<?> closure) { | |
|
|
34 | fromVariant(Closures.action(closure)); | |
|
|
35 | } | |
|
|
36 | ||
|
|
37 | /** | |
|
|
38 | * Selects outputs from a role inside the current variant. | |
|
|
39 | * | |
|
|
40 | * @param roleName role name used only for assembly-time selection | |
|
|
41 | * @param action output selection rule | |
|
|
42 | */ | |
|
|
43 | void fromRole(String roleName, Action<? super OutputSelectionSpec> action); | |
|
|
44 | ||
|
|
45 | default void fromRole(String roleName, Closure<?> closure) { | |
|
|
46 | fromRole(roleName, Closures.action(closure)); | |
|
|
47 | } | |
|
|
48 | ||
|
|
49 | /** | |
|
|
50 | * Selects outputs from a layer inside the current variant. | |
|
|
51 | * | |
|
|
52 | * @param layerName layer name used only for assembly-time selection | |
|
|
53 | * @param action output selection rule | |
|
|
54 | */ | |
|
|
55 | void fromLayer(String layerName, Action<? super OutputSelectionSpec> action); | |
|
|
56 | ||
|
|
57 | default void fromLayer(String layerName, Closure<?> closure) { | |
|
|
58 | fromLayer(layerName, Closures.action(closure)); | |
|
|
59 | } | |
|
|
60 | } | |
| @@ -0,0 +1,14 | |||
|
|
1 | package org.implab.gradle.variants.artifacts; | |
|
|
2 | ||
|
|
3 | import org.implab.gradle.variants.core.Variant; | |
|
|
4 | ||
|
|
5 | /** | |
|
|
6 | * Identity of a published artifact slot inside a variant outgoing contract. | |
|
|
7 | * | |
|
|
8 | * <p>This is a cheap immutable identity object suitable for discovery and selection. Heavy build state is | |
|
|
9 | * obtained separately through {@link ArtifactAssemblies}. | |
|
|
10 | * | |
|
|
11 | * @param variant variant owning the outgoing contract | |
|
|
12 | * @param slot slot identity inside the variant | |
|
|
13 | */ | |
|
|
14 | public record ArtifactSlot(Variant variant, Slot slot) {} | |
| @@ -0,0 +1,48 | |||
|
|
1 | package org.implab.gradle.variants.artifacts; | |
|
|
2 | ||
|
|
3 | import java.util.Optional; | |
|
|
4 | import java.util.Set; | |
|
|
5 | ||
|
|
6 | import org.implab.gradle.variants.core.Variant; | |
|
|
7 | ||
|
|
8 | /** | |
|
|
9 | * Finalized view of artifact slot identities. | |
|
|
10 | * | |
|
|
11 | * <p>This view exposes only cheap slot identities. Assemblies and publication state are resolved | |
|
|
12 | * separately. | |
|
|
13 | */ | |
|
|
14 | public interface ArtifactSlotsView { | |
|
|
15 | /** | |
|
|
16 | * Returns all declared slot identities. | |
|
|
17 | * | |
|
|
18 | * @return all slots known to the finalized model | |
|
|
19 | */ | |
|
|
20 | Set<ArtifactSlot> getSlots(); | |
|
|
21 | ||
|
|
22 | /** | |
|
|
23 | * Returns all slots declared for the given variant. | |
|
|
24 | * | |
|
|
25 | * @param variant variant identity | |
|
|
26 | * @return slots declared for the variant | |
|
|
27 | */ | |
|
|
28 | Set<ArtifactSlot> getSlotsForVariant(Variant variant); | |
|
|
29 | ||
|
|
30 | /** | |
|
|
31 | * Finds a slot by typed identities. | |
|
|
32 | * | |
|
|
33 | * @param variant variant identity | |
|
|
34 | * @param slot slot identity inside the variant | |
|
|
35 | * @return matching slot when present | |
|
|
36 | */ | |
|
|
37 | Optional<ArtifactSlot> findSlot(Variant variant, Slot slot); | |
|
|
38 | ||
|
|
39 | /** | |
|
|
40 | * Requires a slot by typed identities. | |
|
|
41 | * | |
|
|
42 | * @param variant variant identity | |
|
|
43 | * @param slot slot identity inside the variant | |
|
|
44 | * @return matching slot | |
|
|
45 | */ | |
|
|
46 | ArtifactSlot requireSlot(Variant variant, Slot slot); | |
|
|
47 | ||
|
|
48 | } | |
| @@ -0,0 +1,59 | |||
|
|
1 | package org.implab.gradle.variants.artifacts; | |
|
|
2 | ||
|
|
3 | import org.gradle.api.Action; | |
|
|
4 | import org.gradle.api.Task; | |
|
|
5 | import org.gradle.api.attributes.AttributeContainer; | |
|
|
6 | import groovy.lang.Closure; | |
|
|
7 | import org.implab.gradle.common.core.lang.Closures; | |
|
|
8 | ||
|
|
9 | /** | |
|
|
10 | * Materialized outgoing publication state of a single slot. | |
|
|
11 | * | |
|
|
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 OutgoingVariantSpec}, which | |
|
|
14 | * is limited to the root outgoing configuration of the variant. | |
|
|
15 | */ | |
|
|
16 | public interface OutgoingArtifactSlotSpec { | |
|
|
17 | /** | |
|
|
18 | * Returns the published slot identity. | |
|
|
19 | * | |
|
|
20 | * @return slot identity | |
|
|
21 | */ | |
|
|
22 | ArtifactSlot getArtifactSlot(); | |
|
|
23 | ||
|
|
24 | /** | |
|
|
25 | * Returns the assembly backing the published slot. | |
|
|
26 | * | |
|
|
27 | * @return slot assembly | |
|
|
28 | */ | |
|
|
29 | ArtifactAssembly getAssembly(); | |
|
|
30 | ||
|
|
31 | /** | |
|
|
32 | * Returns whether this slot is the primary outgoing artifact set of the variant. | |
|
|
33 | * | |
|
|
34 | * @return {@code true} for the primary slot | |
|
|
35 | */ | |
|
|
36 | boolean isPrimary(); | |
|
|
37 | ||
|
|
38 | /** | |
|
|
39 | * Configures the task producing the slot artifact. | |
|
|
40 | * | |
|
|
41 | * @param action task configuration action | |
|
|
42 | */ | |
|
|
43 | void assemblyTask(Action<? super Task> action); | |
|
|
44 | ||
|
|
45 | default void assemblyTask(Closure<?> closure) { | |
|
|
46 | assemblyTask(Closures.action(closure)); | |
|
|
47 | } | |
|
|
48 | ||
|
|
49 | /** | |
|
|
50 | * Configures attributes of this slot publication. | |
|
|
51 | * | |
|
|
52 | * @param action artifact attribute configuration action | |
|
|
53 | */ | |
|
|
54 | void artifactAttributes(Action<? super AttributeContainer> action); | |
|
|
55 | ||
|
|
56 | default void artifactAttributes(Closure<?> closure) { | |
|
|
57 | artifactAttributes(Closures.action(closure)); | |
|
|
58 | } | |
|
|
59 | } | |
| @@ -0,0 +1,43 | |||
|
|
1 | package org.implab.gradle.variants.artifacts; | |
|
|
2 | ||
|
|
3 | import org.gradle.api.Action; | |
|
|
4 | import org.gradle.api.artifacts.Configuration; | |
|
|
5 | import org.implab.gradle.common.core.lang.Closures; | |
|
|
6 | import org.implab.gradle.variants.core.Variant; | |
|
|
7 | ||
|
|
8 | import groovy.lang.Closure; | |
|
|
9 | ||
|
|
10 | /** | |
|
|
11 | * Materialized root outgoing configuration of a variant. | |
|
|
12 | * | |
|
|
13 | * <p>This is a variant-level publication hook. Slot-specific publication state is exposed separately via | |
|
|
14 | * {@link OutgoingArtifactSlotSpec}. | |
|
|
15 | */ | |
|
|
16 | public interface OutgoingVariantSpec { | |
|
|
17 | /** | |
|
|
18 | * Returns the variant whose outgoing configuration is represented here. | |
|
|
19 | * | |
|
|
20 | * @return variant identity | |
|
|
21 | */ | |
|
|
22 | Variant getVariant(); | |
|
|
23 | ||
|
|
24 | /** | |
|
|
25 | * Returns the root consumable outgoing configuration of the variant. | |
|
|
26 | * | |
|
|
27 | * @return outgoing configuration | |
|
|
28 | */ | |
|
|
29 | Configuration getConfiguration(); | |
|
|
30 | ||
|
|
31 | /** | |
|
|
32 | * Applies a configuration action to the root outgoing configuration. | |
|
|
33 | * | |
|
|
34 | * @param action configuration action | |
|
|
35 | */ | |
|
|
36 | default void configuration(Action<? super Configuration> action) { | |
|
|
37 | action.execute(getConfiguration()); | |
|
|
38 | } | |
|
|
39 | ||
|
|
40 | default void configuration(Closure<?> closure) { | |
|
|
41 | configuration(Closures.action(closure)); | |
|
|
42 | } | |
|
|
43 | } | |
| @@ -0,0 +1,24 | |||
|
|
1 | package org.implab.gradle.variants.artifacts; | |
|
|
2 | ||
|
|
3 | /** | |
|
|
4 | * DSL model for selecting named outputs from a chosen source scope. | |
|
|
5 | * | |
|
|
6 | * <p>The selected outputs are inputs to slot assembly. They do not create additional outgoing slots or | |
|
|
7 | * affect slot identity. | |
|
|
8 | */ | |
|
|
9 | public interface OutputSelectionSpec { | |
|
|
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. | |
|
|
19 | * | |
|
|
20 | * @param name first output name | |
|
|
21 | * @param extra additional output names | |
|
|
22 | */ | |
|
|
23 | void output(String name, String... extra); | |
|
|
24 | } | |
| @@ -0,0 +1,12 | |||
|
|
1 | package org.implab.gradle.variants.artifacts; | |
|
|
2 | ||
|
|
3 | import org.gradle.api.Named; | |
|
|
4 | ||
|
|
5 | /** | |
|
|
6 | * Named identity of a slot inside a variant outgoing contract. | |
|
|
7 | * | |
|
|
8 | * <p>A slot does not identify a published artifact on its own. Combine it with a variant to obtain an | |
|
|
9 | * {@link ArtifactSlot}. | |
|
|
10 | */ | |
|
|
11 | public interface Slot extends Named { | |
|
|
12 | } | |
| @@ -0,0 +1,28 | |||
|
|
1 | package org.implab.gradle.variants.artifacts; | |
|
|
2 | ||
|
|
3 | import org.gradle.api.NamedDomainObjectContainer; | |
|
|
4 | import org.gradle.api.NamedDomainObjectProvider; | |
|
|
5 | import org.gradle.api.artifacts.Configuration; | |
|
|
6 | import org.implab.gradle.variants.core.Variant; | |
|
|
7 | ||
|
|
8 | /** Описывает конфигурация варианта исходящей конфигурации */ | |
|
|
9 | public interface VariantArtifactsConfiguration { | |
|
|
10 | /** | |
|
|
11 | * Исходный вариант для которого строится Outgoing конфигурация | |
|
|
12 | */ | |
|
|
13 | Variant getVariant(); | |
|
|
14 | ||
|
|
15 | /** | |
|
|
16 | * Провайдер зарегистрированной конфигурации | |
|
|
17 | */ | |
|
|
18 | NamedDomainObjectProvider<Configuration> getOutgoingConfiguration(); | |
|
|
19 | ||
|
|
20 | /** | |
|
|
21 | * Слоты конфигурации, данная коллекция живая, используется для | |
|
|
22 | * получения информации об объявленных слотах, но эти слоты не | |
|
|
23 | * обязаны быть сконфигурированы, т.е. это только Identity. | |
|
|
24 | * | |
|
|
25 | * @see {@link ArtifactSlot} | |
|
|
26 | */ | |
|
|
27 | NamedDomainObjectContainer<Slot> getSlots(); | |
|
|
28 | } | |
| @@ -0,0 +1,27 | |||
|
|
1 | package org.implab.gradle.variants.artifacts; | |
|
|
2 | ||
|
|
3 | import java.util.Optional; | |
|
|
4 | ||
|
|
5 | import org.gradle.api.Action; | |
|
|
6 | import org.implab.gradle.variants.core.Variant; | |
|
|
7 | import org.implab.gradle.variants.core.VariantsView; | |
|
|
8 | ||
|
|
9 | /** | |
|
|
10 | * Контекст работы с вариантами публикации, становится доступным после | |
|
|
11 | * финализации модели вариантов. Фактически является живой моделью | |
|
|
12 | */ | |
|
|
13 | public interface VariantArtifactsContext { | |
|
|
14 | ||
|
|
15 | /** | |
|
|
16 | * Зафиксированное представление о вариантах на основе которого адаптеры могут | |
|
|
17 | * конфигурировать артефакты и исходящие конфигурации | |
|
|
18 | */ | |
|
|
19 | VariantsView getVariants(); | |
|
|
20 | ||
|
|
21 | void all(Action<? super VariantArtifactsConfiguration> action); | |
|
|
22 | ||
|
|
23 | Optional<VariantArtifactsConfiguration> findArtifacts(Variant variant); | |
|
|
24 | ||
|
|
25 | VariantArtifactsConfiguration requireArtifacts(Variant variant); | |
|
|
26 | ||
|
|
27 | } | |
| @@ -0,0 +1,59 | |||
|
|
1 | package org.implab.gradle.variants.artifacts; | |
|
|
2 | ||
|
|
3 | import org.gradle.api.Action; | |
|
|
4 | import org.implab.gradle.common.core.lang.Closures; | |
|
|
5 | ||
|
|
6 | import groovy.lang.Closure; | |
|
|
7 | ||
|
|
8 | /** | |
|
|
9 | * Project-level DSL entry point for declaring outgoing artifacts per variant. | |
|
|
10 | * | |
|
|
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. | |
|
|
13 | */ | |
|
|
14 | public interface VariantArtifactsExtension { | |
|
|
15 | /** | |
|
|
16 | * Configures artifact slots of the named variant. | |
|
|
17 | * | |
|
|
18 | * @param variantName variant name | |
|
|
19 | * @param action variant artifact declaration | |
|
|
20 | */ | |
|
|
21 | void variant(String variantName, Action<? super VariantArtifactsSpec> action); | |
|
|
22 | ||
|
|
23 | default void variant(String variantName, Closure<?> closure) { | |
|
|
24 | variant(variantName, Closures.action(closure)); | |
|
|
25 | } | |
|
|
26 | ||
|
|
27 | /** | |
|
|
28 | * Registers a callback invoked with the finalized artifact model. | |
|
|
29 | * | |
|
|
30 | * @param action finalized-model callback | |
|
|
31 | */ | |
|
|
32 | void whenFinalized(Action<? super VariantArtifactsContext> action); | |
|
|
33 | ||
|
|
34 | default void whenFinalized(Closure<?> closure) { | |
|
|
35 | whenFinalized(Closures.action(closure)); | |
|
|
36 | } | |
|
|
37 | ||
|
|
38 | /** | |
|
|
39 | * Registers a callback invoked for each materialized root outgoing configuration. | |
|
|
40 | * | |
|
|
41 | * @param action variant-level outgoing configuration callback | |
|
|
42 | */ | |
|
|
43 | void whenOutgoingVariant(Action<? super OutgoingVariantSpec> action); | |
|
|
44 | ||
|
|
45 | default void whenOutgoingVariant(Closure<?> closure) { | |
|
|
46 | whenOutgoingVariant(Closures.action(closure)); | |
|
|
47 | } | |
|
|
48 | ||
|
|
49 | /** | |
|
|
50 | * Registers a callback invoked for each materialized outgoing slot publication. | |
|
|
51 | * | |
|
|
52 | * @param action slot-level outgoing publication callback | |
|
|
53 | */ | |
|
|
54 | void whenOutgoingSlot(Action<? super OutgoingArtifactSlotSpec> action); | |
|
|
55 | ||
|
|
56 | default void whenOutgoingSlot(Closure<?> closure) { | |
|
|
57 | whenOutgoingSlot(Closures.action(closure)); | |
|
|
58 | } | |
|
|
59 | } | |
| @@ -0,0 +1,40 | |||
|
|
1 | package org.implab.gradle.variants.artifacts; | |
|
|
2 | ||
|
|
3 | import org.gradle.api.Action; | |
|
|
4 | import groovy.lang.Closure; | |
|
|
5 | import org.implab.gradle.common.core.lang.Closures; | |
|
|
6 | ||
|
|
7 | /** | |
|
|
8 | * DSL model for declaring slots of a single variant. | |
|
|
9 | * | |
|
|
10 | * <p>The surrounding variant defines the external outgoing contract. Slots declared here define artifact | |
|
|
11 | * sets within that contract. If a variant exposes more than one slot, one of them is expected to be the | |
|
|
12 | * primary slot. | |
|
|
13 | */ | |
|
|
14 | public interface VariantArtifactsSpec { | |
|
|
15 | /** | |
|
|
16 | * Declares a non-primary slot of the current variant. | |
|
|
17 | * | |
|
|
18 | * @param name slot name | |
|
|
19 | * @param action slot declaration | |
|
|
20 | * @return slot identity | |
|
|
21 | */ | |
|
|
22 | Slot slot(String name, Action<? super ArtifactAssemblySpec> action); | |
|
|
23 | ||
|
|
24 | default Slot slot(String name, Closure<?> closure) { | |
|
|
25 | return slot(name, Closures.action(closure)); | |
|
|
26 | } | |
|
|
27 | ||
|
|
28 | /** | |
|
|
29 | * Declares the primary slot of the current variant. | |
|
|
30 | * | |
|
|
31 | * @param name slot name | |
|
|
32 | * @param action slot declaration | |
|
|
33 | * @return slot identity | |
|
|
34 | */ | |
|
|
35 | Slot primarySlot(String name, Action<? super ArtifactAssemblySpec> action); | |
|
|
36 | ||
|
|
37 | default Slot primarySlot(String name, Closure<?> closure) { | |
|
|
38 | return primarySlot(name, Closures.action(closure)); | |
|
|
39 | } | |
|
|
40 | } | |
| @@ -0,0 +1,37 | |||
|
|
1 | package org.implab.gradle.variants.artifacts.internal; | |
|
|
2 | ||
|
|
3 | import java.util.Optional; | |
|
|
4 | ||
|
|
5 | import org.gradle.api.Action; | |
|
|
6 | import org.implab.gradle.variants.artifacts.VariantArtifactsConfiguration; | |
|
|
7 | import org.implab.gradle.variants.artifacts.VariantArtifactsContext; | |
|
|
8 | import org.implab.gradle.variants.core.Variant; | |
|
|
9 | import org.implab.gradle.variants.core.VariantsView; | |
|
|
10 | ||
|
|
11 | public class DefaultVariantArtifactsContext implements VariantArtifactsContext { | |
|
|
12 | ||
|
|
13 | @Override | |
|
|
14 | public VariantsView getVariants() { | |
|
|
15 | // TODO Auto-generated method stub | |
|
|
16 | throw new UnsupportedOperationException("Unimplemented method 'getVariants'"); | |
|
|
17 | } | |
|
|
18 | ||
|
|
19 | @Override | |
|
|
20 | public void all(Action<? super VariantArtifactsConfiguration> action) { | |
|
|
21 | // TODO Auto-generated method stub | |
|
|
22 | throw new UnsupportedOperationException("Unimplemented method 'all'"); | |
|
|
23 | } | |
|
|
24 | ||
|
|
25 | @Override | |
|
|
26 | public Optional<VariantArtifactsConfiguration> findArtifacts(Variant variant) { | |
|
|
27 | // TODO Auto-generated method stub | |
|
|
28 | throw new UnsupportedOperationException("Unimplemented method 'findArtifacts'"); | |
|
|
29 | } | |
|
|
30 | ||
|
|
31 | @Override | |
|
|
32 | public VariantArtifactsConfiguration requireArtifacts(Variant variant) { | |
|
|
33 | // TODO Auto-generated method stub | |
|
|
34 | throw new UnsupportedOperationException("Unimplemented method 'requireArtifacts'"); | |
|
|
35 | } | |
|
|
36 | ||
|
|
37 | } | |
| @@ -0,0 +1,11 | |||
|
|
1 | package org.implab.gradle.variants.artifacts.internal; | |
|
|
2 | ||
|
|
3 | import org.gradle.api.Action; | |
|
|
4 | import org.implab.gradle.variants.artifacts.VariantArtifactsSpec; | |
|
|
5 | import org.implab.gradle.variants.core.Variant; | |
|
|
6 | ||
|
|
7 | public class VariantArtifactsRegistry { | |
|
|
8 | public void configureVariant(Variant variant, Action<? super VariantArtifactsSpec> action) { | |
|
|
9 | ||
|
|
10 | } | |
|
|
11 | } | |
| @@ -0,0 +1,41 | |||
|
|
1 | /** | |
|
|
2 | * Variant-scoped outgoing artifacts. | |
|
|
3 | * | |
|
|
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 | |
|
|
6 | * contract. | |
|
|
7 | * | |
|
|
8 | * <p>The model intentionally separates cheap identity objects from stateful build objects: | |
|
|
9 | * | |
|
|
10 | * <ul> | |
|
|
11 | * <li>{@link org.implab.gradle.variants.artifacts.ArtifactSlot} identifies a published slot inside a | |
|
|
12 | * variant;</li> | |
|
|
13 | * <li>{@link org.implab.gradle.variants.artifacts.ArtifactAssembly} is the lazily materialized body of | |
|
|
14 | * that slot.</li> | |
|
|
15 | * </ul> | |
|
|
16 | * | |
|
|
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 | |
|
|
19 | * belong to external artifact identity. | |
|
|
20 | * | |
|
|
21 | * <p>Typical usage: | |
|
|
22 | * | |
|
|
23 | * <pre>{@code | |
|
|
24 | * variantArtifacts { | |
|
|
25 | * variant("browser") { | |
|
|
26 | * primarySlot("runtime") { | |
|
|
27 | * fromRole("main") { output("js") } | |
|
|
28 | * } | |
|
|
29 | * slot("sources") { | |
|
|
30 | * fromLayer("main") { output("sources") } | |
|
|
31 | * } | |
|
|
32 | * } | |
|
|
33 | * } | |
|
|
34 | * }</pre> | |
|
|
35 | * | |
|
|
36 | * <p>After finalization, slot identities can be observed through | |
|
|
37 | * {@link org.implab.gradle.variants.artifacts.VariantArtifactsContext#getSlots()}, while slot bodies are | |
|
|
38 | * obtained on demand through | |
|
|
39 | * {@link org.implab.gradle.variants.artifacts.VariantArtifactsContext#getAssemblies()}. | |
|
|
40 | */ | |
|
|
41 | package org.implab.gradle.variants.artifacts; | |
| @@ -10,6 +10,8 | |||
|
|
10 | 10 | - `find*` рассматривается как синоним legacy `get*` (поиск без `fail-fast`). |
|
|
11 | 11 | - `require*` это `find*` + `fail-fast` с понятной ошибкой в месте вызова. |
|
|
12 | 12 | - Для нового API предпочтительны формы `find/require`; новые `get*` по возможности не добавлять. |
|
|
13 | - Интерфейсы и классы, описывающие модели DSL должны иметь суффикс `Spec` у моделей описывающих уровень сервисов и состояние сценария сборки такого суффикса не должно быть. | |
|
|
14 | - Модель расширения на уровне проекта должна иметь суффикс `Extension`. | |
|
|
13 | 15 | |
|
|
14 | 16 | ### Документация |
|
|
15 | 17 | |
| @@ -64,7 +64,7 public final class CompileUnitsView { | |||
|
|
64 | 64 | .collect(Collectors.toUnmodifiableSet()); |
|
|
65 | 65 | } |
|
|
66 | 66 | |
|
|
67 |
public CompileUnit |
|
|
|
67 | public CompileUnit requireUnit(Variant variant, Layer layer) { | |
|
|
68 | 68 | return findUnit(variant, layer) |
|
|
69 | 69 | .orElseThrow(() -> new IllegalArgumentException( |
|
|
70 | 70 | "Compile unit for variant '" + variant.getName() |
| @@ -36,7 +36,7 class VariantSourcesPluginFunctionalTest | |||
|
|
36 | 36 | def production = ctx.variants.roles.find { it.name == 'production' } |
|
|
37 | 37 | def mainLayer = ctx.variants.layers.find { it.name == 'main' } |
|
|
38 | 38 | def projection = ctx.roleProjections.getProjection(browser, production) |
|
|
39 |
def unit = ctx.compileUnits. |
|
|
|
39 | def unit = ctx.compileUnits.requireUnit(browser, mainLayer) | |
|
|
40 | 40 | |
|
|
41 | 41 | def left = ctx.sourceSets.getSourceSet(unit) |
|
|
42 | 42 | def right = ctx.sourceSets.getSourceSet(unit) |
| @@ -113,9 +113,9 class VariantSourcesPluginFunctionalTest | |||
|
|
113 | 113 | def mainLayer = ctx.variants.layers.find { it.name == 'main' } |
|
|
114 | 114 | def testLayer = ctx.variants.layers.find { it.name == 'test' } |
|
|
115 | 115 | |
|
|
116 |
def browserMain = ctx.sourceSets.getSourceSet(ctx.compileUnits. |
|
|
|
117 |
def browserTest = ctx.sourceSets.getSourceSet(ctx.compileUnits. |
|
|
|
118 |
def nodeMain = ctx.sourceSets.getSourceSet(ctx.compileUnits. |
|
|
|
116 | def browserMain = ctx.sourceSets.getSourceSet(ctx.compileUnits.requireUnit(browser, mainLayer)).get() | |
|
|
117 | def browserTest = ctx.sourceSets.getSourceSet(ctx.compileUnits.requireUnit(browser, testLayer)).get() | |
|
|
118 | def nodeMain = ctx.sourceSets.getSourceSet(ctx.compileUnits.requireUnit(node, mainLayer)).get() | |
|
|
119 | 119 | def bySourceSet = events.groupBy { it.split(':', 2)[1] } |
|
|
120 | 120 | |
|
|
121 | 121 | println("browserMain=" + bySourceSet[browserMain.name].collect { it.split(':', 2)[0] }.join(',')) |
| @@ -149,7 +149,7 class VariantSourcesPluginFunctionalTest | |||
|
|
149 | 149 | variantSources.whenFinalized { ctx -> |
|
|
150 | 150 | def browser = ctx.variants.variants.find { it.name == 'browser' } |
|
|
151 | 151 | def mainLayer = ctx.variants.layers.find { it.name == 'main' } |
|
|
152 |
def unit = ctx.compileUnits. |
|
|
|
152 | def unit = ctx.compileUnits.requireUnit(browser, mainLayer) | |
|
|
153 | 153 | |
|
|
154 | 154 | ctx.sourceSets.getSourceSet(unit).get() |
|
|
155 | 155 | variantSources.layer('main') { |
| @@ -185,7 +185,7 class VariantSourcesPluginFunctionalTest | |||
|
|
185 | 185 | variantSources.whenFinalized { ctx -> |
|
|
186 | 186 | def browser = ctx.variants.variants.find { it.name == 'browser' } |
|
|
187 | 187 | def mainLayer = ctx.variants.layers.find { it.name == 'main' } |
|
|
188 |
def unit = ctx.compileUnits. |
|
|
|
188 | def unit = ctx.compileUnits.requireUnit(browser, mainLayer) | |
|
|
189 | 189 | |
|
|
190 | 190 | def sourceSet = ctx.sourceSets.getSourceSet(unit).get() |
|
|
191 | 191 | variantSources.layer('main') { |
| @@ -224,7 +224,7 class VariantSourcesPluginFunctionalTest | |||
|
|
224 | 224 | variantSources.whenFinalized { ctx -> |
|
|
225 | 225 | def browser = ctx.variants.variants.find { it.name == 'browser' } |
|
|
226 | 226 | def mainLayer = ctx.variants.layers.find { it.name == 'main' } |
|
|
227 |
def unit = ctx.compileUnits. |
|
|
|
227 | def unit = ctx.compileUnits.requireUnit(browser, mainLayer) | |
|
|
228 | 228 | |
|
|
229 | 229 | def sourceSet = ctx.sourceSets.getSourceSet(unit).get() |
|
|
230 | 230 | variantSources.layer('main') { |
| @@ -321,8 +321,8 class VariantSourcesPluginFunctionalTest | |||
|
|
321 | 321 | def variantBar = ctx.variants.layers.find { it.name == 'variantBar' } |
|
|
322 | 322 | def bar = ctx.variants.layers.find { it.name == 'bar' } |
|
|
323 | 323 | |
|
|
324 |
def later = ctx.compileUnits. |
|
|
|
325 |
def earlier = ctx.compileUnits. |
|
|
|
324 | def later = ctx.compileUnits.requireUnit(fooVariant, bar) | |
|
|
325 | def earlier = ctx.compileUnits.requireUnit(foo, variantBar) | |
|
|
326 | 326 | |
|
|
327 | 327 | println("map1=" + later.variant().name + ":" + later.layer().name + "->" + ctx.sourceSets.getSourceSet(later).name) |
|
|
328 | 328 | println("map2=" + earlier.variant().name + ":" + earlier.layer().name + "->" + ctx.sourceSets.getSourceSet(earlier).name) |
| @@ -33,8 +33,8 class CompileUnitsViewTest { | |||
|
|
33 | 33 | new VariantRoleLayer(browser, qa, test))); |
|
|
34 | 34 | |
|
|
35 | 35 | var units = CompileUnitsView.of(view); |
|
|
36 |
var browserMain = units. |
|
|
|
37 |
var browserTest = units. |
|
|
|
36 | var browserMain = units.requireUnit(browser, main); | |
|
|
37 | var browserTest = units.requireUnit(browser, test); | |
|
|
38 | 38 | |
|
|
39 | 39 | assertEquals(2, units.getUnits().size()); |
|
|
40 | 40 | assertEquals(Set.of(browserMain, browserTest), units.getUnitsForVariant(browser)); |
| @@ -59,7 +59,7 class CompileUnitsViewTest { | |||
|
|
59 | 59 | |
|
|
60 | 60 | var units = CompileUnitsView.of(view); |
|
|
61 | 61 | |
|
|
62 |
var ex = assertThrows(IllegalArgumentException.class, () -> units. |
|
|
|
62 | var ex = assertThrows(IllegalArgumentException.class, () -> units.requireUnit(browser, missing)); | |
|
|
63 | 63 | assertTrue(ex.getMessage().contains("Compile unit for variant 'browser' and layer 'missing' not found")); |
|
|
64 | 64 | } |
|
|
65 | 65 | |
General Comments 0
You need to be logged in to leave comments.
Login now
