This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository nuiton-config. See https://gitlab.nuiton.org/nuiton/nuiton-config.git commit 3f2cbe67e6a76b58a4f7716da722b2fe160dec0f Author: Tony CHEMIT <chemit@codelutin.com> Date: Wed Oct 5 18:58:20 2016 +0200 Introduce a third format (ini) this will be the new default format. (Fixes #4057) --- nuiton-config-example/pom.xml | 1 + .../src/main/config/NuitonConfigExample.ini | 36 ++++ nuiton-config-example/src/site/apt/index.apt.vm | 4 +- nuiton-config-maven-plugin/pom.xml | 5 + .../nuiton/config/plugin/ConfigMojoSupport.java | 6 +- .../config/plugin/io/ConfigModelIOIniImpl.java | 186 +++++++++++++++++++++ .../config/plugin/io/ConfigModelIOIniImplTest.java | 78 +++++++++ .../src/test/resources/NuitonConfigExample.ini | 29 ++++ pom.xml | 6 + src/site/apt/usage.apt.vm | 51 +++++- 10 files changed, 388 insertions(+), 14 deletions(-) diff --git a/nuiton-config-example/pom.xml b/nuiton-config-example/pom.xml index 0bfc857..155ac18 100644 --- a/nuiton-config-example/pom.xml +++ b/nuiton-config-example/pom.xml @@ -114,6 +114,7 @@ <target> <copy todir="${project.reporting.outputDirectory}/model" failonerror="true" overwrite="true"> <fileset dir="src/main/config"> + <include name="*.ini" /> <include name="*.toml" /> <include name="*.yaml" /> </fileset> diff --git a/nuiton-config-example/src/main/config/NuitonConfigExample.ini b/nuiton-config-example/src/main/config/NuitonConfigExample.ini new file mode 100644 index 0000000..d927e5f --- /dev/null +++ b/nuiton-config-example/src/main/config/NuitonConfigExample.ini @@ -0,0 +1,36 @@ +description = Exemple de configuration + +[option firstName] +description = Prénom de l'utilisateur +key = identity.firstName +type = string +defaultValue = Joshua + +[option lastName] +description = Nom de l'utilisateur +key = identity.lastName +type = string +defaultValue = Bloch + +[option email] +description = Courriel de l'utilisateur +key = identity.email +type = string + +[option twitter] +description = Compte Twitter de l'utilisateur +key = identity.twitter +type = string +defaultValue = jbloch + +[option age] +description = age de l'utilisateur +key = identity.age +type = int +defaultValue = 56 + +[action help] +description = Pour afficher l'aide +action = "org.nuiton.config.example.NuitonConfigExample#help" +aliases = -h,--help + diff --git a/nuiton-config-example/src/site/apt/index.apt.vm b/nuiton-config-example/src/site/apt/index.apt.vm index b0c16d2..3a80b66 100644 --- a/nuiton-config-example/src/site/apt/index.apt.vm +++ b/nuiton-config-example/src/site/apt/index.apt.vm @@ -78,8 +78,8 @@ Utilisation [] - Voir le fichier de configuration au format {{{./model/NuitonConfigExample.toml}Toml}} ou - {{{./model/NuitonConfigExample.yaml}Yaml}}. + Voir le fichier de configuration au format {{{./model/NuitonConfigExample.ini}Ini}}, + {{{./model/NuitonConfigExample.toml}Toml}} ou {{{./model/NuitonConfigExample.yaml}Yaml}}. * Générer les classes de configuration diff --git a/nuiton-config-maven-plugin/pom.xml b/nuiton-config-maven-plugin/pom.xml index bb7c422..955bd82 100644 --- a/nuiton-config-maven-plugin/pom.xml +++ b/nuiton-config-maven-plugin/pom.xml @@ -83,6 +83,11 @@ </dependency> <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-configuration2</artifactId> + </dependency> + + <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </dependency> diff --git a/nuiton-config-maven-plugin/src/main/java/org/nuiton/config/plugin/ConfigMojoSupport.java b/nuiton-config-maven-plugin/src/main/java/org/nuiton/config/plugin/ConfigMojoSupport.java index 433f776..df0a24f 100644 --- a/nuiton-config-maven-plugin/src/main/java/org/nuiton/config/plugin/ConfigMojoSupport.java +++ b/nuiton-config-maven-plugin/src/main/java/org/nuiton/config/plugin/ConfigMojoSupport.java @@ -42,11 +42,11 @@ import java.util.Map; abstract class ConfigMojoSupport extends AbstractPlugin { /** - * Configuration description format {@code toml} or {@code yaml}. + * Configuration description format {@code ini}, {@code toml} or {@code yaml}. * - * Default value is {@code toml}. + * Default value is {@code ini}. */ - @Parameter(property = "config.format", defaultValue = "toml") + @Parameter(property = "config.format", defaultValue = "ini") private String format; /** diff --git a/nuiton-config-maven-plugin/src/main/java/org/nuiton/config/plugin/io/ConfigModelIOIniImpl.java b/nuiton-config-maven-plugin/src/main/java/org/nuiton/config/plugin/io/ConfigModelIOIniImpl.java new file mode 100644 index 0000000..b362b0d --- /dev/null +++ b/nuiton-config-maven-plugin/src/main/java/org/nuiton/config/plugin/io/ConfigModelIOIniImpl.java @@ -0,0 +1,186 @@ +package org.nuiton.config.plugin.io; + +/*- + * #%L + * Nuiton Config :: Maven plugin + * %% + * Copyright (C) 2016 Code Lutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import com.google.common.base.Joiner; +import com.google.common.io.Files; +import org.apache.commons.configuration2.INIConfiguration; +import org.apache.commons.configuration2.SubnodeConfiguration; +import org.apache.commons.lang3.StringUtils; +import org.nuiton.config.plugin.model.ActionModel; +import org.nuiton.config.plugin.model.ConfigModel; +import org.nuiton.config.plugin.model.OptionModel; + +import java.io.Reader; +import java.io.Writer; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.LinkedList; + +/** + * Implementation using {@code ini} format. + * + * Created on 02/10/16. + * + * @author Tony Chemit - chemit@codelutin.com + * @plexus.component role="org.nuiton.config.plugin.io.ConfigModelIO" role-hint="ini" + * @since 3.0 + */ +public class ConfigModelIOIniImpl implements ConfigModelIO { + + private static final String DESCRIPTION = "description"; + private static final String KEY = "key"; + private static final String TYPE = "type"; + private static final String DEFAULT_VALUE = "defaultValue"; + private static final String TRANSIENT = "transient"; + private static final String FINAL = "final"; + private static final String ACTION = "action"; + private static final String ALIASES = "aliases"; + + @Override + public ConfigModel read(Path path) throws ReadConfigModelException { + + try (Reader reader = Files.newReader(path.toFile(), StandardCharsets.UTF_8)) { + + INIConfiguration iniConfiguration = new INIConfiguration(); + iniConfiguration.read(reader); + + ConfigModel configModel = new ConfigModel(); + configModel.setDescription(iniConfiguration.getString(DESCRIPTION)); + + LinkedList<OptionModel> options = new LinkedList<>(); + LinkedList<ActionModel> actions = new LinkedList<>(); + configModel.setOptions(options); + configModel.setActions(actions); + + for (String section : iniConfiguration.getSections()) { + + if (section == null) { + continue; + } + + if (section.startsWith("option ")) { + SubnodeConfiguration optionSection = iniConfiguration.getSection(section); + + OptionModel optionModel = new OptionModel(); + + String optionName = StringUtils.removeStart(section, "option "); + optionModel.setName(optionName); + + String description = optionSection.getString(DESCRIPTION, ""); + optionModel.setDescription(description); + + String key = optionSection.getString(KEY); + optionModel.setKey(key); + + String type = optionSection.getString(TYPE); + optionModel.setType(type); + + String defaultValue = optionSection.getString(DEFAULT_VALUE); + optionModel.setDefaultValue(defaultValue); + + String _transient = optionSection.getString(TRANSIENT); + if (StringUtils.isNotEmpty(_transient)) { + optionModel.setTransient(Boolean.valueOf(_transient)); + } + String _final = optionSection.getString(FINAL); + if (StringUtils.isNotEmpty(_final)) { + optionModel.setTransient(Boolean.valueOf(_final)); + } + options.add(optionModel); + } else if (section.startsWith("action ")) { + SubnodeConfiguration actionSection = iniConfiguration.getSection(section); + + ActionModel actionModel = new ActionModel(); + + String actionName = StringUtils.removeStart(section, "action "); + actionModel.setName(actionName); + String description = actionSection.getString(DESCRIPTION, ""); + actionModel.setDescription(description); + + String action = actionSection.getString(ACTION); + actionModel.setAction(action); + + String aliases = actionSection.getString(ALIASES); + if (StringUtils.isNotEmpty(aliases)) { + actionModel.setAliases(aliases.split("\\s*,\\s*")); + } + actions.add(actionModel); + } + } + + return configModel; + } catch (Exception e) { + throw new ReadConfigModelException("Can't real ini config model from file: " + path, e); + } + + } + + @Override + public void write(ConfigModel configModel, Path path) throws WriteConfigModelException { + + try (Writer writer = Files.newWriter(path.toFile(), StandardCharsets.UTF_8)) { + + INIConfiguration iniConfiguration = new INIConfiguration(); + + iniConfiguration.addProperty(DESCRIPTION, configModel.getDescription()); + + for (OptionModel optionModel : configModel.getOptions()) { + + SubnodeConfiguration section = iniConfiguration.getSection("option " + optionModel.getName()); + + section.addProperty(DESCRIPTION, optionModel.getDescription()); + section.addProperty(KEY, optionModel.getKey()); + section.addProperty(TYPE, optionModel.getType()); + if (optionModel.getDefaultValue() != null) { + section.addProperty(DEFAULT_VALUE, optionModel.getDefaultValue()); + } + if (optionModel.isTransient()) { + section.addProperty(TRANSIENT, "true"); + } + if (optionModel.isFinal()) { + section.addProperty(FINAL, "true"); + } + } + + for (ActionModel actionModel : configModel.getActions()) { + + SubnodeConfiguration section = iniConfiguration.getSection("action " + actionModel.getName()); + + section.addProperty(DESCRIPTION, actionModel.getDescription()); + section.addProperty(ACTION, actionModel.getAction()); + if (actionModel.getAliases().length > 0) { + section.addProperty(ALIASES, Joiner.on(",").join(Arrays.asList(actionModel.getAliases()))); + } + + } + iniConfiguration.write(writer); + + } catch (Exception e) { + throw new WriteConfigModelException("Can't write ini config model from file: " + path, e); + } + + } + +} diff --git a/nuiton-config-maven-plugin/src/test/java/org/nuiton/config/plugin/io/ConfigModelIOIniImplTest.java b/nuiton-config-maven-plugin/src/test/java/org/nuiton/config/plugin/io/ConfigModelIOIniImplTest.java new file mode 100644 index 0000000..ac0934b --- /dev/null +++ b/nuiton-config-maven-plugin/src/test/java/org/nuiton/config/plugin/io/ConfigModelIOIniImplTest.java @@ -0,0 +1,78 @@ +package org.nuiton.config.plugin.io; + +/*- + * #%L + * Nuiton Config :: Maven plugin + * %% + * Copyright (C) 2016 Code Lutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.nuiton.config.plugin.model.ConfigModel; + +import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; + +/** + * Created on 01/10/16. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 3.0 + */ +public class ConfigModelIOIniImplTest { + + private ConfigModelIO io; + private ConfigMoldeIOFixtures ioFixtures; + + @Before + public void setUp() throws Exception { + io = new ConfigModelIOIniImpl(); + ioFixtures = new ConfigMoldeIOFixtures(); + } + + @Test + public void read() throws Exception { + + Path path = Paths.get(new File("").getAbsolutePath(), "src", "test", "resources", "NuitonConfigExample.ini"); + + ConfigModel configModel = io.read(path); + + ioFixtures.assertConfigModel(configModel); + + } + + @Test + public void write() throws Exception { + + Path path = Paths.get(new File("").getAbsolutePath(), "src", "test", "resources", "NuitonConfigExample.ini"); + + ConfigModel configModel = io.read(path); + Assert.assertNotNull(configModel); + + Path path2 = Paths.get(new File("").getAbsolutePath(), "target", "surefire-workdir", "NuitonConfigExample2.ini"); + io.write(configModel, path2); + + ConfigModel configModel2 = io.read(path); + ioFixtures.assertConfigModel(configModel2); + + } + +} diff --git a/nuiton-config-maven-plugin/src/test/resources/NuitonConfigExample.ini b/nuiton-config-maven-plugin/src/test/resources/NuitonConfigExample.ini new file mode 100644 index 0000000..72064c8 --- /dev/null +++ b/nuiton-config-maven-plugin/src/test/resources/NuitonConfigExample.ini @@ -0,0 +1,29 @@ +description = Exemple de configuration +[option firstName] +key = identity.firstName +description = Prénom de l'utilisateur +type = string +defaultValue = Joshua +[option lastName] +key = identity.lastName +description = Nom de l'utilisateur +type = string +defaultValue = Bloch +[option email] +key = identity.email +description = Courriel de l'utilisateur +type = string +[option twitter] +key = identity.twitter +description = Compte Twitter de l'utilisateur +type = string +defaultValue = jbloch +[option age] +key = identity.age +description = age de l'utilisateur +type = int +defaultValue = 56 +[action help] +description = Pour afficher l'aide +action = org.nuiton.config.example.NuitonConfigExample#help +aliases = -h,--help \ No newline at end of file diff --git a/pom.xml b/pom.xml index a073af4..a8e3e7e 100644 --- a/pom.xml +++ b/pom.xml @@ -152,6 +152,12 @@ </dependency> <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-configuration2</artifactId> + <version>2.1</version> + </dependency> + + <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> diff --git a/src/site/apt/usage.apt.vm b/src/site/apt/usage.apt.vm index 97915fb..baeae89 100644 --- a/src/site/apt/usage.apt.vm +++ b/src/site/apt/usage.apt.vm @@ -30,14 +30,27 @@ Première étape : décrire sa configuration La première chose à faire est de décrire sa configuration (options, actions, description, ...). - Il existe deux formats ({{{https://github.com/toml-lang/toml}Toml}}) ou ({{{http://yaml.org/}Yaml}}) pour décrire la configuration. + Il existe trois formats {{{https://en.wikipedia.org/wiki/INI_file}Ini}}, ({{{https://github.com/toml-lang/toml}Toml}}) + ou ({{{http://yaml.org/}Yaml}}) pour décrire la configuration. - Le format par défaut est le <<Toml>>. + Le format par défaut est le <<Ini>> car il est le plus concis. * Comment décrire une configuration ? Une configuration est composée d'une description, d'options et d'actions (optionnelles) +** Format Ini + ++------------------------------------------------ +description = Exemple de configuration +[option 1] +[option 2] +... +[action 1] +[action 2] +... ++------------------------------------------------ + ** Format Toml +------------------------------------------------ @@ -110,6 +123,17 @@ actions: Pour pouvez aussi mettre n'importe quelle classe java qui dispose d'une constructeur publique via son nom qualifié. +** Exemple d'une option au format Ini + ++------------------------------------------------ +[options age] +name = age +key = identity.age +description = age de l'utilisateur +type = int +defaultValue = 56 ++------------------------------------------------ + ** Exemple d'une option au format Toml +------------------------------------------------ @@ -149,6 +173,15 @@ defaultValue = "56" ** Exemple d'une action au format Toml +------------------------------------------------ +[action help] +description = Pour afficher l'aide +action = org.nuiton.config.example.NuitonConfigExample#help +aliases = -h, --help ++------------------------------------------------ + +** Exemple d'une action au format Toml + ++------------------------------------------------ [[actions]] name = "help" description = "Pour afficher l'aide" @@ -190,8 +223,8 @@ aliases = ["-h", "--help"] [] - Voir le fichier de configuration au format {{{./nuiton-config-example/model/NuitonConfigExample.toml}Toml}} ou - {{{./nuiton-config-example/model/NuitonConfigExample.yaml}Yaml}}. + Voir le fichier de configuration au format {{{./nuiton-config-example/model/NuitonConfigExample.ini}Ini}}, + {{{./nuiton-config-example/model/NuitonConfigExample.toml}Toml}} ou {{{./nuiton-config-example/model/NuitonConfigExample.yaml}Yaml}}. Deuxième étape : Générer la configuration @@ -213,7 +246,7 @@ Deuxième étape : Générer la configuration </plugin> +------------------------------------------------ - Le format par défaut utilisé est le <<Toml>>, vous pouvez aussi utiliser le format <<yaml>>. + Le format par défaut utilisé est <<ini>>, vous pouvez aussi utiliser le format <<toml>> ou <<yaml>>. Par défaut, on place le fichier de description dans le répertoire <<src/main/config>>. @@ -317,16 +350,16 @@ Décrire une configuration à partir des classes java (migration) Lancer ensuite en ligne de commande +------------------------------------------------ -mvn nuiton-config:describe -Dconfig.providerName=NuitonConfigExample +mvn nuiton-config:describe [ -Dconfig.providerName=NuitonConfigExample ] +------------------------------------------------ - Cela va générer le fichier (toml) à l'emplacement suivant : + Cela va générer le fichier (ini) à l'emplacement suivant : +------------------------------------------------ src └── main └── config - └── NuitonConfigExample.toml + └── NuitonConfigExample.ini +------------------------------------------------ - Vous pouvez aussi choisir le format <Yaml> en passant l'option <<-Dconfig.format=yaml>>. + Vous pouvez aussi choisir le format <toml> ou <yaml> en passant l'option <<-Dconfig.format=ini|toml|yaml>>. -- To stop receiving notification emails like this one, please contact nuiton.org SCM administrator <admin+scm@nuiton.org>.