##// END OF EJS Templates
variants: move source set layout conventions out of model...
cin -
r59:780370baa54c default
parent child
Show More
@@ -0,0 +1,45
1 package org.implab.gradle.variants.sources.internal;
2
3 import org.gradle.api.Action;
4 import org.gradle.api.file.Directory;
5 import org.gradle.api.provider.Provider;
6 import org.implab.gradle.common.core.lang.FilePaths;
7 import org.implab.gradle.variants.sources.CompileUnitSourceSetSpec;
8
9 /**
10 * Applies the default layout policy for source sets materialized from variant
11 * compile units.
12 *
13 * <p>
14 * The convention keeps sources grouped by layer and outputs grouped by
15 * variant/layer. It only sets directory properties on the materialized source
16 * set; declaring source directories and named outputs remains the
17 * responsibility of adapters or user DSL.
18 * </p>
19 */
20 public class CompileUnitLayoutConvention implements Action<CompileUnitSourceSetSpec> {
21 private final Provider<Directory> sourcesBaseDir;
22 private final Provider<Directory> outputsBaseDir;
23
24 public CompileUnitLayoutConvention(
25 Provider<Directory> baseDirectory,
26 Provider<Directory> outputsBaseDir) {
27 this.sourcesBaseDir = baseDirectory;
28 this.outputsBaseDir = outputsBaseDir;
29 }
30
31 @Override
32 public void execute(CompileUnitSourceSetSpec spec) {
33 var sourceSet = spec.getSourceSet();
34 var unit = spec.getCompileUnit();
35 var layerName = unit.layer().getName();
36 var variantName = unit.variant().getName();
37
38 sourceSet.getSourceSetDir()
39 .convention(sourcesBaseDir.map(base -> base.dir(FilePaths.cat(layerName))));
40
41 sourceSet.getOutputsDir()
42 .convention(outputsBaseDir.map(base -> base.dir(FilePaths.cat(variantName, layerName))));
43 }
44
45 }
@@ -4,6 +4,7
4 "cSpell.words": [
4 "cSpell.words": [
5 "implab",
5 "implab",
6 "materializer",
6 "materializer",
7 "rawtypes"
7 "rawtypes",
8 "Replayable"
8 ]
9 ]
9 } No newline at end of file
10 }
@@ -6,6 +6,7 import org.gradle.api.Plugin;
6 import org.gradle.api.Project;
6 import org.gradle.api.Project;
7 import org.gradle.api.logging.Logger;
7 import org.gradle.api.logging.Logger;
8 import org.gradle.api.logging.Logging;
8 import org.gradle.api.logging.Logging;
9 import org.implab.gradle.common.core.lang.FilePaths;
9 import org.implab.gradle.variants.sources.GenericSourceSet;
10 import org.implab.gradle.variants.sources.GenericSourceSet;
10
11
11 /**
12 /**
@@ -16,12 +17,27 import org.implab.gradle.variants.source
16 public abstract class SourcesPlugin implements Plugin<Project> {
17 public abstract class SourcesPlugin implements Plugin<Project> {
17 private static final Logger logger = Logging.getLogger(SourcesPlugin.class);
18 private static final Logger logger = Logging.getLogger(SourcesPlugin.class);
18
19
19 private static final String SOURCES_EXTENSION_NAME = "sources";
20 public static final String SOURCES_EXTENSION_NAME = "sources";
21
22 private static final String SOURCES_DIRECTORY = "src";
23
24 private static final String OUTPUTS_DIRECTORY = "out";
20
25
21 @Override
26 @Override
22 public void apply(Project target) {
27 public void apply(Project target) {
23 logger.debug("Registering '{}' extension on project '{}'", SOURCES_EXTENSION_NAME, target.getPath());
28 logger.debug("Registering '{}' extension on project '{}'", SOURCES_EXTENSION_NAME, target.getPath());
29
30 var layout = target.getLayout();
31
24 var sources = target.getObjects().domainObjectContainer(GenericSourceSet.class);
32 var sources = target.getObjects().domainObjectContainer(GenericSourceSet.class);
33 sources.configureEach(sourceSet -> {
34 sourceSet.getSourceSetDir()
35 .convention(layout.getProjectDirectory()
36 .dir(FilePaths.cat(SOURCES_DIRECTORY, sourceSet.getName())));
37 sourceSet.getOutputsDir()
38 .convention(layout.getBuildDirectory()
39 .dir(FilePaths.cat(OUTPUTS_DIRECTORY, sourceSet.getName())));
40 });
25 target.getExtensions().add(SOURCES_EXTENSION_NAME, sources);
41 target.getExtensions().add(SOURCES_EXTENSION_NAME, sources);
26 }
42 }
27
43
@@ -32,7 +48,8 public abstract class SourcesPlugin impl
32 var extension = (NamedDomainObjectContainer<GenericSourceSet>) extensions.findByName(SOURCES_EXTENSION_NAME);
48 var extension = (NamedDomainObjectContainer<GenericSourceSet>) extensions.findByName(SOURCES_EXTENSION_NAME);
33
49
34 if (extension == null) {
50 if (extension == null) {
35 logger.error("Sources extension '{}' isn't found on project '{}'", SOURCES_EXTENSION_NAME, target.getPath());
51 logger.error("Sources extension '{}' isn't found on project '{}'", SOURCES_EXTENSION_NAME,
52 target.getPath());
36 throw new GradleException("Sources extension isn't found");
53 throw new GradleException("Sources extension isn't found");
37 }
54 }
38 logger.debug("Resolved '{}' extension on project '{}'", SOURCES_EXTENSION_NAME, target.getPath());
55 logger.debug("Resolved '{}' extension on project '{}'", SOURCES_EXTENSION_NAME, target.getPath());
@@ -21,6 +21,7 import org.implab.gradle.variants.source
21 import org.implab.gradle.variants.artifacts.OutgoingConfigurationSlotSpec;
21 import org.implab.gradle.variants.artifacts.OutgoingConfigurationSlotSpec;
22
22
23 public abstract class VariantArtifactsPlugin implements Plugin<Project> {
23 public abstract class VariantArtifactsPlugin implements Plugin<Project> {
24 public static final String VARIANT_ARTIFACTS_EXTENSION = "variantArtifacts";
24
25
25 @Override
26 @Override
26 public void apply(Project target) {
27 public void apply(Project target) {
@@ -105,7 +106,7 public abstract class VariantArtifactsPl
105
106
106 };
107 };
107
108
108 extensions.add(VariantArtifactsExtension.class, "variantArtifacts", variantArtifacts);
109 extensions.add(VariantArtifactsExtension.class, VARIANT_ARTIFACTS_EXTENSION, variantArtifacts);
109
110
110 }
111 }
111
112
@@ -1,12 +1,9
1 package org.implab.gradle.variants;
1 package org.implab.gradle.variants;
2
2
3 import java.util.Objects;
3 import java.util.Objects;
4 import java.util.function.Predicate;
5
4
6 import org.eclipse.jdt.annotation.NonNullByDefault;
5 import org.eclipse.jdt.annotation.NonNullByDefault;
7 import org.gradle.api.Action;
6 import org.gradle.api.Action;
8 import org.gradle.api.InvalidUserDataException;
9 import org.gradle.api.Named;
10 import org.gradle.api.Plugin;
7 import org.gradle.api.Plugin;
11 import org.gradle.api.Project;
8 import org.gradle.api.Project;
12 import org.implab.gradle.common.core.lang.Deferred;
9 import org.implab.gradle.common.core.lang.Deferred;
@@ -14,13 +11,13 import org.implab.gradle.common.core.lan
14 import org.implab.gradle.variants.core.Layer;
11 import org.implab.gradle.variants.core.Layer;
15 import org.implab.gradle.variants.core.Variant;
12 import org.implab.gradle.variants.core.Variant;
16 import org.implab.gradle.variants.core.VariantsExtension;
13 import org.implab.gradle.variants.core.VariantsExtension;
17 import org.implab.gradle.variants.core.VariantsView;
18 import org.implab.gradle.variants.sources.CompileUnit;
14 import org.implab.gradle.variants.sources.CompileUnit;
19 import org.implab.gradle.variants.sources.CompileUnitSourceSetSpec;
15 import org.implab.gradle.variants.sources.CompileUnitSourceSetSpec;
20 import org.implab.gradle.variants.sources.CompileUnitsView;
16 import org.implab.gradle.variants.sources.CompileUnitsView;
21 import org.implab.gradle.variants.sources.RoleProjectionsView;
17 import org.implab.gradle.variants.sources.RoleProjectionsView;
22 import org.implab.gradle.variants.sources.VariantSourcesContext;
18 import org.implab.gradle.variants.sources.VariantSourcesContext;
23 import org.implab.gradle.variants.sources.VariantSourcesExtension;
19 import org.implab.gradle.variants.sources.VariantSourcesExtension;
20 import org.implab.gradle.variants.sources.internal.CompileUnitLayoutConvention;
24 import org.implab.gradle.variants.sources.internal.CompileUnitNamer;
21 import org.implab.gradle.variants.sources.internal.CompileUnitNamer;
25 import org.implab.gradle.variants.sources.internal.DefaultCompileUnitNamingPolicy;
22 import org.implab.gradle.variants.sources.internal.DefaultCompileUnitNamingPolicy;
26 import org.implab.gradle.variants.sources.internal.DefaultLateConfigurationPolicySpec;
23 import org.implab.gradle.variants.sources.internal.DefaultLateConfigurationPolicySpec;
@@ -32,6 +29,10 import org.implab.gradle.variants.source
32 public abstract class VariantSourcesPlugin implements Plugin<Project> {
29 public abstract class VariantSourcesPlugin implements Plugin<Project> {
33 public static final String VARIANT_SOURCES_EXTENSION = "variantSources";
30 public static final String VARIANT_SOURCES_EXTENSION = "variantSources";
34
31
32 private static final String VARIANT_OUTPUTS_DIRECTORY = "variants";
33
34 private static final String VARIANT_SOURCES_DIRECTORY = "src";
35
35 @Override
36 @Override
36 public void apply(Project target) {
37 public void apply(Project target) {
37 var extensions = target.getExtensions();
38 var extensions = target.getExtensions();
@@ -40,7 +41,8 public abstract class VariantSourcesPlug
40 target.getPlugins().apply(VariantsPlugin.class);
41 target.getPlugins().apply(VariantsPlugin.class);
41 // Access the VariantsExtension to configure variant sources.
42 // Access the VariantsExtension to configure variant sources.
42 var variantsExtension = extensions.getByType(VariantsExtension.class);
43 var variantsExtension = extensions.getByType(VariantsExtension.class);
43 var objectFactory = target.getObjects();
44 var objects = target.getObjects();
45 var providers = target.getProviders();
44
46
45 var deferred = new Deferred<VariantSourcesContext>();
47 var deferred = new Deferred<VariantSourcesContext>();
46
48
@@ -53,7 +55,7 public abstract class VariantSourcesPlug
53 var roleProjections = RoleProjectionsView.of(variants);
55 var roleProjections = RoleProjectionsView.of(variants);
54
56
55 // create registries
57 // create registries
56 var sourceSetRegistry = new SourceSetRegistry(objectFactory);
58 var sourceSetRegistry = new SourceSetRegistry(objects);
57 lateConfigurationPolicy.finalizePolicy();
59 lateConfigurationPolicy.finalizePolicy();
58 var sourceSetConfiguration = new SourceSetConfigurationRegistry(lateConfigurationPolicy::mode);
60 var sourceSetConfiguration = new SourceSetConfigurationRegistry(lateConfigurationPolicy::mode);
59
61
@@ -63,6 +65,13 public abstract class VariantSourcesPlug
63 .nameCollisionPolicy(namingPolicy.policy())
65 .nameCollisionPolicy(namingPolicy.policy())
64 .build();
66 .build();
65
67
68 var compileUnitLayoutConvention = new CompileUnitLayoutConvention(
69 providers.provider(() -> target.getLayout().getProjectDirectory().dir(VARIANT_SOURCES_DIRECTORY)),
70 target.getLayout().getBuildDirectory().dir(VARIANT_OUTPUTS_DIRECTORY));
71
72 // apply layout convention to all compile unit source sets
73 sourceSetConfiguration.addAction(compileUnitLayoutConvention);
74
66 // create the context
75 // create the context
67 var context = new DefaultVariantSourcesContext(
76 var context = new DefaultVariantSourcesContext(
68 variants,
77 variants,
@@ -70,8 +79,7 public abstract class VariantSourcesPlug
70 roleProjections,
79 roleProjections,
71 compileUnitNamer,
80 compileUnitNamer,
72 sourceSetRegistry,
81 sourceSetRegistry,
73 sourceSetConfiguration
82 sourceSetConfiguration);
74 );
75 deferred.resolve(context);
83 deferred.resolve(context);
76 });
84 });
77
85
@@ -98,7 +106,9 public abstract class VariantSourcesPlug
98
106
99 lateConfigurationPolicy.finalizePolicy();
107 lateConfigurationPolicy.finalizePolicy();
100
108
101 whenAvailable(ctx -> ctx.configureVariant(resolveVariant(ctx.getVariants(), variantName), action));
109 var variant = objects.named(Variant.class, variantName);
110
111 whenAvailable(ctx -> ctx.configureVariant(variant, action));
102 }
112 }
103
113
104 @Override
114 @Override
@@ -109,7 +119,9 public abstract class VariantSourcesPlug
109
119
110 lateConfigurationPolicy.finalizePolicy();
120 lateConfigurationPolicy.finalizePolicy();
111
121
112 whenAvailable(ctx -> ctx.configureLayer(resolveLayer(ctx.getVariants(), layerName), action));
122 var layer = objects.named(Layer.class, layerName);
123
124 whenAvailable(ctx -> ctx.configureLayer(layer, action));
113 }
125 }
114
126
115 @Override
127 @Override
@@ -120,7 +132,11 public abstract class VariantSourcesPlug
120
132
121 lateConfigurationPolicy.finalizePolicy();
133 lateConfigurationPolicy.finalizePolicy();
122
134
123 whenAvailable(ctx -> ctx.configureUnit(resolveCompileUnit(ctx, variantName, layerName), action));
135 var variant = objects.named(Variant.class, variantName);
136 var layer = objects.named(Layer.class, layerName);
137 var unit = new CompileUnit(variant, layer);
138
139 whenAvailable(ctx -> ctx.configureUnit(unit, action));
124 }
140 }
125
141
126 @Override
142 @Override
@@ -136,31 +152,4 public abstract class VariantSourcesPlug
136 extensions.add(VariantSourcesExtension.class, VARIANT_SOURCES_EXTENSION, variantSourcesExtension);
152 extensions.add(VariantSourcesExtension.class, VARIANT_SOURCES_EXTENSION, variantSourcesExtension);
137
153
138 }
154 }
139
140 private static Layer resolveLayer(VariantsView variants, String name) {
141 return variants.getLayers().stream()
142 .filter(named(name))
143 .findAny()
144 .orElseThrow(() -> new InvalidUserDataException("Layer '" + name + "' isn't declared"));
145 }
155 }
146
147 private static Variant resolveVariant(VariantsView variants, String name) {
148 return variants.getVariants().stream()
149 .filter(named(name))
150 .findAny()
151 .orElseThrow(() -> new InvalidUserDataException("Variant '" + name + "' isn't declared"));
152 }
153
154 private static CompileUnit resolveCompileUnit(VariantSourcesContext ctx, String variantName, String layerName) {
155 return ctx.getCompileUnits().findUnit(
156 resolveVariant(ctx.getVariants(), variantName),
157 resolveLayer(ctx.getVariants(), layerName))
158 .orElseThrow(() -> new InvalidUserDataException(
159 "The CompileUnit isn't declared for variant '" + variantName + "', layer '" + layerName + "'"));
160 }
161
162 private static Predicate<Named> named(String name) {
163 return named -> named.getName().equals(name);
164 }
165
166 }
@@ -23,13 +23,15 import org.implab.gradle.variants.intern
23 *
23 *
24 */
24 */
25 public abstract class VariantsPlugin implements Plugin<Project> {
25 public abstract class VariantsPlugin implements Plugin<Project> {
26 public static final String VARIANTS_EXTENSION = "variants";
27
26 @Override
28 @Override
27 public void apply(Project target) {
29 public void apply(Project target) {
28
30
29 var objectFactory = target.getObjects();
31 var objectFactory = target.getObjects();
30
32
31 var variantsExtension = new DefaultVariantsExtension(objectFactory);
33 var variantsExtension = new DefaultVariantsExtension(objectFactory);
32 target.getExtensions().add(VariantsExtension.class, "variants", variantsExtension);
34 target.getExtensions().add(VariantsExtension.class, VARIANTS_EXTENSION, variantsExtension);
33 target.afterEvaluate(t -> variantsExtension.finalizeExtension());
35 target.afterEvaluate(t -> variantsExtension.finalizeExtension());
34
36
35 }
37 }
@@ -1,7 +1,6
1 package org.implab.gradle.variants.sources;
1 package org.implab.gradle.variants.sources;
2
2
3 import java.io.File;
3 import java.io.File;
4 import java.nio.file.Paths;
5 import java.util.HashSet;
4 import java.util.HashSet;
6 import java.util.LinkedHashMap;
5 import java.util.LinkedHashMap;
7 import java.util.List;
6 import java.util.List;
@@ -22,7 +21,6 import org.gradle.api.Task;
22 import org.gradle.api.file.ConfigurableFileCollection;
21 import org.gradle.api.file.ConfigurableFileCollection;
23 import org.gradle.api.file.DirectoryProperty;
22 import org.gradle.api.file.DirectoryProperty;
24 import org.gradle.api.file.FileCollection;
23 import org.gradle.api.file.FileCollection;
25 import org.gradle.api.file.ProjectLayout;
26 import org.gradle.api.file.SourceDirectorySet;
24 import org.gradle.api.file.SourceDirectorySet;
27 import org.gradle.api.model.ObjectFactory;
25 import org.gradle.api.model.ObjectFactory;
28 import org.gradle.api.tasks.TaskProvider;
26 import org.gradle.api.tasks.TaskProvider;
@@ -33,9 +31,10 import org.gradle.api.tasks.TaskProvider
33 * <p>
31 * <p>
34 * Each instance aggregates multiple {@link SourceDirectorySet source sets}
32 * Each instance aggregates multiple {@link SourceDirectorySet source sets}
35 * under a shared name and exposes typed outputs that must be declared up front.
33 * under a shared name and exposes typed outputs that must be declared up front.
36 * Default locations are {@code src/<name>} for sources and
34 * Source and output base directories are explicit model properties. They do
37 * {@code build/<name>} for outputs, both of which can be customized via the
35 * not define source directories or outputs by themselves; plugins and adapters
38 * exposed {@link DirectoryProperty} setters.
36 * may attach conventions or use them as layout hints for their own
37 * materialization rules.
39 * </p>
38 * </p>
40 *
39 *
41 * <p>
40 * <p>
@@ -62,7 +61,7 public abstract class GenericSourceSet i
62 private final Set<String> declaredOutputs = new HashSet<>();
61 private final Set<String> declaredOutputs = new HashSet<>();
63
62
64 @Inject
63 @Inject
65 public GenericSourceSet(String name, ObjectFactory objects, ProjectLayout layout) {
64 public GenericSourceSet(String name, ObjectFactory objects) {
66 this.name = name;
65 this.name = name;
67 this.objects = objects;
66 this.objects = objects;
68
67
@@ -75,14 +74,6 public abstract class GenericSourceSet i
75 allSourceDirectories = objects.fileCollection().from(sourceDirectoriesProvider());
74 allSourceDirectories = objects.fileCollection().from(sourceDirectoriesProvider());
76
75
77 allOutputs = objects.fileCollection().from(outputsProvider());
76 allOutputs = objects.fileCollection().from(outputsProvider());
78
79 getSourceSetDir().convention(layout
80 .getProjectDirectory()
81 .dir(Paths.get("src", name).toString()));
82
83 getOutputsDir().convention(layout
84 .getBuildDirectory()
85 .dir(name));
86 }
77 }
87
78
88 @Override
79 @Override
@@ -91,14 +82,24 public abstract class GenericSourceSet i
91 }
82 }
92
83
93 /**
84 /**
94 * Base directory for this source set. Defaults to {@code src/<name>} under
85 * Base directory associated with this source set.
95 * the project directory.
86 *
87 * <p>
88 * This property is intentionally convention-free in the base model. A
89 * plugin may attach a convention when it knows the surrounding layout
90 * policy, for example when materializing variant compile units.
91 * </p>
96 */
92 */
97 public abstract DirectoryProperty getSourceSetDir();
93 public abstract DirectoryProperty getSourceSetDir();
98
94
99 /**
95 /**
100 * Base directory for outputs of this source set. Defaults to
96 * Base directory associated with outputs of this source set.
101 * {@code build/<name>}.
97 *
98 * <p>
99 * This property is a layout hint. Actual named outputs are declared and
100 * populated through {@link #declareOutputs(String, String...)} and
101 * {@link #registerOutput(String, Object...)}.
102 * </p>
102 */
103 */
103 public abstract DirectoryProperty getOutputsDir();
104 public abstract DirectoryProperty getOutputsDir();
104
105
@@ -63,6 +63,8 class PluginMarkerFunctionalTest extends
63 doLast {
63 doLast {
64 def main = sources.named('main').get()
64 def main = sources.named('main').get()
65 println("sourceSet=" + main.name)
65 println("sourceSet=" + main.name)
66 println("sourceSetDir=" + project.relativePath(main.sourceSetDir.get().asFile))
67 println("outputsDir=" + project.relativePath(main.outputsDir.get().asFile))
66 println("jsFiles=" + main.output('js').files.collect { it.name }.sort().join(','))
68 println("jsFiles=" + main.output('js').files.collect { it.name }.sort().join(','))
67 }
69 }
68 }
70 }
@@ -71,6 +73,8 class PluginMarkerFunctionalTest extends
71 BuildResult result = runner("probe").build();
73 BuildResult result = runner("probe").build();
72
74
73 assertTrue(result.getOutput().contains("sourceSet=main"));
75 assertTrue(result.getOutput().contains("sourceSet=main"));
76 assertTrue(result.getOutput().contains("sourceSetDir=src/main"));
77 assertTrue(result.getOutput().contains("outputsDir=build/out/main"));
74 assertTrue(result.getOutput().contains("jsFiles=main.js"));
78 assertTrue(result.getOutput().contains("jsFiles=main.js"));
75 }
79 }
76
80
@@ -40,12 +40,15 class VariantSourcesPluginFunctionalTest
40
40
41 def left = ctx.sourceSets.getSourceSet(unit)
41 def left = ctx.sourceSets.getSourceSet(unit)
42 def right = ctx.sourceSets.getSourceSet(unit)
42 def right = ctx.sourceSets.getSourceSet(unit)
43 def sourceSet = left.get()
43
44
44 lines << "projectionUnits=" + ctx.roleProjections.getUnits(projection)
45 lines << "projectionUnits=" + ctx.roleProjections.getUnits(projection)
45 .collect { it.layer().name }
46 .collect { it.layer().name }
46 .sort()
47 .sort()
47 .join(',')
48 .join(',')
48 lines << "mainSourceSet=" + left.name
49 lines << "mainSourceSet=" + sourceSet.name
50 lines << "mainSourceSetDir=" + project.relativePath(sourceSet.sourceSetDir.get().asFile)
51 lines << "mainOutputsDir=" + project.relativePath(sourceSet.outputsDir.get().asFile)
49 lines << "sameProvider=" + left.is(right)
52 lines << "sameProvider=" + left.is(right)
50 }
53 }
51
54
@@ -67,6 +70,8 class VariantSourcesPluginFunctionalTest
67 assertTrue(result.getOutput().contains("units=browser:main,browser:test"));
70 assertTrue(result.getOutput().contains("units=browser:main,browser:test"));
68 assertTrue(result.getOutput().contains("projectionUnits=main"));
71 assertTrue(result.getOutput().contains("projectionUnits=main"));
69 assertTrue(result.getOutput().contains("mainSourceSet=browserMain"));
72 assertTrue(result.getOutput().contains("mainSourceSet=browserMain"));
73 assertTrue(result.getOutput().contains("mainSourceSetDir=src/main"));
74 assertTrue(result.getOutput().contains("mainOutputsDir=build/variants/browser/main"));
70 assertTrue(result.getOutput().contains("sameProvider=true"));
75 assertTrue(result.getOutput().contains("sameProvider=true"));
71 assertTrue(result.getOutput().contains("late:variants=browser"));
76 assertTrue(result.getOutput().contains("late:variants=browser"));
72 }
77 }
@@ -372,7 +377,7 class VariantSourcesPluginFunctionalTest
372 }
377 }
373 """);
378 """);
374
379
375 assertBuildFails("Variant 'missing' isn't declared", "help");
380 assertBuildFails("The specified variant 'missing' isn't declared", "help");
376 }
381 }
377
382
378 @Test
383 @Test
@@ -423,7 +428,7 class VariantSourcesPluginFunctionalTest
423 }
428 }
424 """);
429 """);
425
430
426 assertBuildFails("Layer 'missing' isn't declared", "help");
431 assertBuildFails("The specified layer 'missing' isn't declared", "help");
427 }
432 }
428
433
429 @Test
434 @Test
@@ -475,7 +480,7 class VariantSourcesPluginFunctionalTest
475 }
480 }
476 """);
481 """);
477
482
478 assertBuildFails("The CompileUnit isn't declared for variant 'browser', layer 'test'", "help");
483 assertBuildFails("Compile unit for variant 'browser' and layer 'test' not found", "help");
479 }
484 }
480
485
481 @Test
486 @Test
General Comments 0
You need to be logged in to leave comments. Login now