# HG changeset patch
# User cin
# Date 2026-04-20 19:19:11
# Node ID 3469331e3c4b01d904594191417d9559cc756808
# Parent 07d0d84bc0a28bcde22802e1e9a1a412012c4456
variants: enforce source configuration policies
diff --git a/variants/src/main/java/org/implab/gradle/variants/VariantSourcesPlugin.java b/variants/src/main/java/org/implab/gradle/variants/VariantSourcesPlugin.java
--- a/variants/src/main/java/org/implab/gradle/variants/VariantSourcesPlugin.java
+++ b/variants/src/main/java/org/implab/gradle/variants/VariantSourcesPlugin.java
@@ -54,6 +54,7 @@ public abstract class VariantSourcesPlug
// create registries
var sourceSetRegistry = new SourceSetRegistry(objectFactory);
+ lateConfigurationPolicy.finalizePolicy();
var sourceSetConfiguration = new SourceSetConfigurationRegistry(lateConfigurationPolicy::mode);
// build compile unit namer
@@ -131,14 +132,14 @@ public abstract class VariantSourcesPlug
return variants.getLayers().stream()
.filter(named(name))
.findAny()
- .orElseThrow(() -> new IllegalArgumentException("Layer '" + name + "' isn't declared"));
+ .orElseThrow(() -> new InvalidUserDataException("Layer '" + name + "' isn't declared"));
}
private static Variant resolveVariant(VariantsView variants, String name) {
return variants.getVariants().stream()
.filter(named(name))
.findAny()
- .orElseThrow(() -> new IllegalArgumentException("Variant '" + name + "' is't declared"));
+ .orElseThrow(() -> new InvalidUserDataException("Variant '" + name + "' isn't declared"));
}
private static CompileUnit resolveCompileUnit(VariantSourcesContext ctx, String variantName, String layerName) {
diff --git a/variants/src/main/java/org/implab/gradle/variants/sources/VariantSourcesExtension.java b/variants/src/main/java/org/implab/gradle/variants/sources/VariantSourcesExtension.java
--- a/variants/src/main/java/org/implab/gradle/variants/sources/VariantSourcesExtension.java
+++ b/variants/src/main/java/org/implab/gradle/variants/sources/VariantSourcesExtension.java
@@ -17,7 +17,10 @@ public interface VariantSourcesExtension
*
it must be selected before the first selector rule is registered via
* {@link #variant(String, Action)}, {@link #layer(String, Action)} or
* {@link #unit(String, String, Action)};
- * once selected, it cannot be changed later;
+ * it must be selected before the finalized context becomes observable via
+ * {@link #whenFinalized(Action)};
+ * once selected or once the finalized context is being created, it cannot
+ * be changed later;
* the policy controls both diagnostics and late-application semantics.
*
*
diff --git a/variants/src/main/java/org/implab/gradle/variants/sources/internal/DefaultLateConfigurationPolicySpec.java b/variants/src/main/java/org/implab/gradle/variants/sources/internal/DefaultLateConfigurationPolicySpec.java
--- a/variants/src/main/java/org/implab/gradle/variants/sources/internal/DefaultLateConfigurationPolicySpec.java
+++ b/variants/src/main/java/org/implab/gradle/variants/sources/internal/DefaultLateConfigurationPolicySpec.java
@@ -8,6 +8,7 @@ public class DefaultLateConfigurationPol
private boolean policyApplied = false;
public LateConfigurationMode mode() {
+ finalizePolicy();
return policyMode;
}
diff --git a/variants/src/test/java/org/implab/gradle/variants/VariantSourcesPluginFunctionalTest.java b/variants/src/test/java/org/implab/gradle/variants/VariantSourcesPluginFunctionalTest.java
--- a/variants/src/test/java/org/implab/gradle/variants/VariantSourcesPluginFunctionalTest.java
+++ b/variants/src/test/java/org/implab/gradle/variants/VariantSourcesPluginFunctionalTest.java
@@ -356,7 +356,7 @@ class VariantSourcesPluginFunctionalTest
}
""");
- assertBuildFails("Variant 'missing' is't declared", "help");
+ assertBuildFails("Variant 'missing' isn't declared", "help");
}
@Test
@@ -428,4 +428,27 @@ class VariantSourcesPluginFunctionalTest
assertBuildFails("Naming policy already applied", "help");
}
+
+ @Test
+ void rejectsChangingLateConfigurationPolicyAfterContextBecomesObservable() throws Exception {
+ writeSettings("variant-sources-late-policy-context-fixed");
+ writeBuildFile("""
+ apply plugin: org.implab.gradle.variants.VariantSourcesPlugin
+
+ def variantsExt = extensions.getByType(org.implab.gradle.variants.core.VariantsExtension)
+ variantsExt.layers.create('main')
+ variantsExt.roles.create('production')
+ variantsExt.variant('browser') {
+ role('production') { layers('main') }
+ }
+
+ variantSources.whenFinalized {
+ variantSources.lateConfigurationPolicy {
+ allowLateConfiguration()
+ }
+ }
+ """);
+
+ assertBuildFails("Lazy configuration policy already applied", "help");
+ }
}