Restore the ability to generate several parameters with the same name

This commit fixes the handling of configuration parameters so that
nested groups can be reused when requested with the same parameter
name. However, single parameters are additive.

Closes gh-867
This commit is contained in:
Stephane Nicoll
2019-03-14 17:33:59 +01:00
parent 0805345e85
commit 0ecdf3097a
7 changed files with 103 additions and 67 deletions

View File

@@ -41,9 +41,9 @@ public class KotlinJpaMavenBuildCustomizer implements BuildCustomizer<MavenBuild
if (this.buildMetadataResolver.hasFacet(build, "jpa")) {
MavenPlugin kotlinNoArgPlugin = build.plugin("org.jetbrains.kotlin",
"kotlin-maven-noarg", "${kotlin.version}");
kotlinNoArgPlugin.configuration((configuration) -> configuration.parameter(
"compilerPlugins",
(compilerPlugins) -> compilerPlugins.parameter("plugin", "jpa")));
kotlinNoArgPlugin.configuration(
(configuration) -> configuration.configure("compilerPlugins",
(compilerPlugins) -> compilerPlugins.add("plugin", "jpa")));
}
}

View File

@@ -45,10 +45,10 @@ class KotlinMavenBuildCustomizer implements BuildCustomizer<MavenBuild> {
MavenPlugin kotlinMavenPlugin = build.plugin("org.jetbrains.kotlin",
"kotlin-maven-plugin");
kotlinMavenPlugin.configuration((configuration) -> {
configuration.parameter("args", (args) -> this.settings.getCompilerArgs()
.forEach((arg) -> args.parameter("arg", arg)));
configuration.parameter("compilerPlugins",
(compilerPlugins) -> compilerPlugins.parameter("plugin", "spring"));
configuration.configure("args", (args) -> this.settings.getCompilerArgs()
.forEach((arg) -> args.add("arg", arg)));
configuration.configure("compilerPlugins",
(compilerPlugins) -> compilerPlugins.add("plugin", "spring"));
});
kotlinMavenPlugin.dependency("org.jetbrains.kotlin", "kotlin-maven-allopen",
"${kotlin.version}");

View File

@@ -42,11 +42,11 @@ class KotlinMavenFullBuildCustomizer implements BuildCustomizer<MavenBuild> {
MavenPlugin kotlinMavenPlugin = build.plugin("org.jetbrains.kotlin",
"kotlin-maven-plugin", "${kotlin.version}");
kotlinMavenPlugin.configuration((configuration) -> {
configuration.parameter("args", (args) -> this.settings.getCompilerArgs()
.forEach((arg) -> args.parameter("arg", arg)));
configuration.parameter("compilerPlugins",
(compilerPlugins) -> compilerPlugins.parameter("plugin", "spring"));
configuration.parameter("jvmTarget", this.settings.getJvmTarget());
configuration.configure("args", (args) -> this.settings.getCompilerArgs()
.forEach((arg) -> args.add("arg", arg)));
configuration.configure("compilerPlugins",
(compilerPlugins) -> compilerPlugins.add("plugin", "spring"));
configuration.add("jvmTarget", this.settings.getJvmTarget());
});
kotlinMavenPlugin.execution("compile",
(compile) -> compile.phase("compile").goal("compile"));

View File

@@ -16,6 +16,9 @@
package io.spring.initializr.generator.spring.code.kotlin;
import java.util.Arrays;
import java.util.List;
import io.spring.initializr.generator.buildsystem.maven.MavenBuild;
import io.spring.initializr.generator.buildsystem.maven.MavenPlugin;
import io.spring.initializr.generator.buildsystem.maven.MavenPlugin.Configuration;
@@ -85,4 +88,33 @@ class KotlinMavenBuildCustomizerTests {
assertThat(allOpen.getVersion()).isEqualTo("${kotlin.version}");
}
@Test
void kotlinMavenPluginWithSeveralArgs() {
MavenBuild build = new MavenBuild();
new KotlinMavenBuildCustomizer(new TestKotlinProjectSettings()).customize(build);
Configuration configuration = build.getPlugins().get(0).getConfiguration();
Setting args = configuration.getSettings().get(0);
assertThat(args.getName()).isEqualTo("args");
assertThat(args.getValue()).asList().hasSize(2);
assertThat(args.getValue()).asList().element(0)
.hasFieldOrPropertyWithValue("name", "arg")
.hasFieldOrPropertyWithValue("value", "-Done=1");
assertThat(args.getValue()).asList().element(1)
.hasFieldOrPropertyWithValue("name", "arg")
.hasFieldOrPropertyWithValue("value", "-Dtwo=2");
}
private static class TestKotlinProjectSettings extends SimpleKotlinProjectSettings {
TestKotlinProjectSettings() {
super("1.3.20");
}
@Override
public List<String> getCompilerArgs() {
return Arrays.asList("-Done=1", "-Dtwo=2");
}
}
}

View File

@@ -146,35 +146,41 @@ public class MavenPlugin {
*/
public static class ConfigurationCustomization {
private final Map<String, Object> settings = new LinkedHashMap<>();
private final List<Setting> settings = new ArrayList<>();
/**
* Set the specified parameter with a single value.
* Add the specified parameter with a single value.
* @param name the name of the parameter
* @param value the single value of the parameter
* @return this for method chaining
*/
public ConfigurationCustomization parameter(String name, String value) {
this.settings.put(name, value);
public ConfigurationCustomization add(String name, String value) {
this.settings.add(new Setting(name, value));
return this;
}
/**
* Configure the parameter with the specified {@code name}.
* @param parameter the name of the parameter
* @param name the name of the parameter
* @param consumer a consumer to further configure the parameter
* @return this for method chaining
* @throws IllegalArgumentException if a parameter with the same name is
* registered with a single value
*/
public ConfigurationCustomization parameter(String parameter,
public ConfigurationCustomization configure(String name,
Consumer<ConfigurationCustomization> consumer) {
Object value = this.settings.computeIfAbsent(parameter,
(id) -> new ConfigurationCustomization());
Object value = this.settings.stream()
.filter((candidate) -> candidate.getName().equals(name)).findFirst()
.orElseGet(() -> {
Setting nestedSetting = new Setting(name,
new ConfigurationCustomization());
this.settings.add(nestedSetting);
return nestedSetting;
}).getValue();
if (!(value instanceof ConfigurationCustomization)) {
throw new IllegalArgumentException(String.format(
"Could not customize parameter '%s', a single value %s is already registered",
parameter, value));
name, value));
}
ConfigurationCustomization nestedConfiguration = (ConfigurationCustomization) value;
consumer.accept(nestedConfiguration);
@@ -182,16 +188,16 @@ public class MavenPlugin {
}
Configuration build() {
return new Configuration(this.settings.entrySet().stream()
.map((entry) -> resolve(entry.getKey(), entry.getValue()))
return new Configuration(this.settings.stream()
.map((entry) -> resolve(entry.getName(), entry.getValue()))
.collect(Collectors.toList()));
}
private Setting resolve(String key, Object value) {
if (value instanceof ConfigurationCustomization) {
List<Setting> values = ((ConfigurationCustomization) value).settings
.entrySet().stream()
.map((entry) -> resolve(entry.getKey(), entry.getValue()))
.stream()
.map((entry) -> resolve(entry.getName(), entry.getValue()))
.collect(Collectors.toList());
return new Setting(key, values);
}

View File

@@ -336,10 +336,9 @@ class MavenBuildWriterTests {
build.setArtifact("demo");
MavenPlugin kotlin = build.plugin("org.jetbrains.kotlin", "kotlin-maven-plugin");
kotlin.configuration((configuration) -> {
configuration.parameter("args",
(args) -> args.parameter("arg", "-Xjsr305=strict"));
configuration.parameter("compilerPlugins",
(compilerPlugins) -> compilerPlugins.parameter("plugin", "spring"));
configuration.configure("args", (args) -> args.add("arg", "-Xjsr305=strict"));
configuration.configure("compilerPlugins",
(compilerPlugins) -> compilerPlugins.add("plugin", "spring"));
});
generatePom(build, (pom) -> {
NodeAssert plugin = pom.nodeAtPath("/project/build/plugins/plugin");
@@ -364,8 +363,8 @@ class MavenBuildWriterTests {
execution.goal("process-asciidoc");
execution.phase("generateProject-resources");
execution.configuration((configuration) -> {
configuration.parameter("doctype", "book");
configuration.parameter("backend", "html");
configuration.add("doctype", "book");
configuration.add("backend", "html");
});
});
generatePom(build, (pom) -> {

View File

@@ -32,11 +32,11 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
class MavenPluginTests {
@Test
void configurationCanBeCustomized() {
void configurationParameterCanBeCustomized() {
MavenPlugin plugin = new MavenPlugin("com.example", "test-plugin");
plugin.configuration((customizer) -> customizer.parameter("enabled", "false")
.parameter("skip", "true"));
plugin.configuration((customizer) -> customizer.parameter("another", "test"));
plugin.configuration((configuration) -> configuration.add("enabled", "false")
.add("skip", "true"));
plugin.configuration((configuration) -> configuration.add("another", "test"));
assertThat(plugin.getConfiguration().getSettings().stream().map(Setting::getName))
.containsExactly("enabled", "skip", "another");
assertThat(
@@ -45,45 +45,44 @@ class MavenPluginTests {
}
@Test
void configurationCanBeOverridden() {
void configurationParameterCanBeAdded() {
MavenPlugin plugin = new MavenPlugin("com.example", "test-plugin");
plugin.configuration((customizer) -> customizer.parameter("enabled", "true"));
plugin.configuration((customizer) -> customizer.parameter("enabled", "false"));
plugin.configuration((configuration) -> configuration.add("enabled", "true"));
plugin.configuration((configuration) -> configuration.add("skip", "false"));
assertThat(plugin.getConfiguration().getSettings().stream().map(Setting::getName))
.containsExactly("enabled");
.containsExactly("enabled", "skip");
assertThat(
plugin.getConfiguration().getSettings().stream().map(Setting::getValue))
.containsExactly("false");
.containsExactly("true", "false");
}
@Test
@SuppressWarnings("unchecked")
void configurationWithNestedValuesCanBeCustomized() {
void configurationParameterWithNestedValuesCanBeCustomized() {
MavenPlugin plugin = new MavenPlugin("com.example", "test-plugin");
plugin.configuration((customizer) -> customizer.parameter("items",
(items) -> items.parameter("one", "true")));
plugin.configuration((customizer) -> customizer.parameter("items",
(items) -> items.parameter("two", "false")));
plugin.configuration((configuration) -> configuration.configure("items",
(items) -> items.add("item", "one")));
plugin.configuration((configuration) -> configuration.configure("items",
(items) -> items.add("item", "two")));
assertThat(plugin.getConfiguration().getSettings()).hasSize(1);
Setting setting = plugin.getConfiguration().getSettings().get(0);
assertThat(setting.getName()).isEqualTo("items");
assertThat(setting.getValue()).isInstanceOf(List.class);
List<Setting> values = (List<Setting>) setting.getValue();
assertThat(values.stream().map(Setting::getName)).containsExactly("one", "two");
assertThat(values.stream().map(Setting::getValue)).containsExactly("true",
"false");
assertThat(values.stream().map(Setting::getName)).containsExactly("item", "item");
assertThat(values.stream().map(Setting::getValue)).containsExactly("one", "two");
}
@Test
@SuppressWarnings("unchecked")
void configurationWithSeveralLevelOfNestedValuesCanBeCustomized() {
void configurationParameterWithSeveralLevelOfNestedValuesCanBeCustomized() {
MavenPlugin plugin = new MavenPlugin("com.example", "test-plugin");
plugin.configuration((customizer) -> customizer.parameter("items",
(items) -> items.parameter("subItems",
(subItems) -> subItems.parameter("one", "true"))));
plugin.configuration((customizer) -> customizer.parameter("items",
(items) -> items.parameter("subItems", (subItems) -> subItems
.parameter("one", "false").parameter("two", "true"))));
plugin.configuration((configuration) -> configuration.configure("items",
(items) -> items.configure("item",
(subItems) -> subItems.add("subItem", "one"))));
plugin.configuration((configuration) -> configuration.configure("items",
(items) -> items.configure("item", (subItems) -> subItems
.add("subItem", "two").add("subItem", "three"))));
assertThat(plugin.getConfiguration().getSettings()).hasSize(1);
Setting setting = plugin.getConfiguration().getSettings().get(0);
assertThat(setting.getName()).isEqualTo("items");
@@ -91,21 +90,22 @@ class MavenPluginTests {
List<Setting> items = (List<Setting>) setting.getValue();
assertThat(items).hasSize(1);
Setting item = items.get(0);
assertThat(item.getName()).isEqualTo("subItems");
assertThat(item.getName()).isEqualTo("item");
assertThat(item.getValue()).isInstanceOf(List.class);
List<Setting> subItems = (List<Setting>) item.getValue();
assertThat(subItems.stream().map(Setting::getName)).containsExactly("one", "two");
assertThat(subItems.stream().map(Setting::getValue)).containsExactly("false",
"true");
assertThat(subItems.stream().map(Setting::getName)).containsExactly("subItem",
"subItem", "subItem");
assertThat(subItems.stream().map(Setting::getValue)).containsExactly("one", "two",
"three");
}
@Test
void configurationCannotBeSwitchedToNestedValue() {
void configurationParameterWithSingleValueCannotBeSwitchedToNestedValue() {
MavenPlugin plugin = new MavenPlugin("com.example", "test-plugin");
plugin.configuration((customizer) -> customizer.parameter("test", "value"));
plugin.configuration((configuration) -> configuration.add("test", "value"));
assertThatIllegalArgumentException()
.isThrownBy(() -> plugin.configuration((customizer) -> customizer
.parameter("test", (test) -> test.parameter("one", "true"))))
.configure("test", (test) -> test.add("one", "true"))))
.withMessageContaining("test").withMessageContaining("value");
}
@@ -132,17 +132,16 @@ class MavenPluginTests {
@Test
void executionConfigurationCanBeOverridden() {
MavenPlugin plugin = new MavenPlugin("com.example", "test-plugin");
plugin.execution("test",
(test) -> test.configuration((testConfiguration) -> testConfiguration
.parameter("enabled", "true").parameter("another", "test")));
plugin.execution("test", (test) -> test.configuration(
(testConfiguration) -> testConfiguration.parameter("enabled", "false")));
(testConfiguration) -> testConfiguration.add("enabled", "true")));
plugin.execution("test", (test) -> test.configuration(
(testConfiguration) -> testConfiguration.add("another", "test")));
assertThat(plugin.getExecutions()).hasSize(1);
List<Setting> settings = plugin.getExecutions().get(0).getConfiguration()
.getSettings();
assertThat(settings.stream().map(Setting::getName)).containsExactly("enabled",
"another");
assertThat(settings.stream().map(Setting::getValue)).containsExactly("false",
assertThat(settings.stream().map(Setting::getValue)).containsExactly("true",
"test");
}