diff --git a/.gitattributes b/.gitattributes index 9ae14fa217..7672033d63 100644 --- a/.gitattributes +++ b/.gitattributes @@ -51,3 +51,8 @@ cobigen/cobigen-textmerger/src/test/resources/TestBaseLineDelimiter.txt eol=lf cobigen/cobigen-textmerger/src/test/resources/PatchBaseLineDelimiter.txt eol=crlf cobigen/cobigen-textmerger/src/test/resources/MergeBaseLineDelimiter.txt eol=lf + +# handle line endings for test files differently +cobigen/cobigen-core-parent/cobigen-core-api/src/test/resources/testdata/unittest/SystemUtilTest/TestWindowsLineEndings.txt eol=crlf +cobigen/cobigen-core-parent/cobigen-core-api/src/test/resources/testdata/unittest/SystemUtilTest/TestLinuxLineEndings.txt eol=lf +cobigen/cobigen-core-parent/cobigen-core-api/src/test/resources/testdata/unittest/SystemUtilTest/TestOsxLineEndings.txt eol=cr diff --git a/cobigen/cobigen-core-parent/cobigen-core-api/pom.xml b/cobigen/cobigen-core-parent/cobigen-core-api/pom.xml index 68e31899eb..deed62f028 100644 --- a/cobigen/cobigen-core-parent/cobigen-core-api/pom.xml +++ b/cobigen/cobigen-core-parent/cobigen-core-api/pom.xml @@ -31,6 +31,13 @@ guava 17.0 + + + com.devonfw.cobigen + core-test + 7.0.0 + test + diff --git a/cobigen/cobigen-core-parent/cobigen-core-api/src/main/java/com/devonfw/cobigen/api/constants/ConfigurationConstants.java b/cobigen/cobigen-core-parent/cobigen-core-api/src/main/java/com/devonfw/cobigen/api/constants/ConfigurationConstants.java index 8badac4055..4facd2cc7d 100644 --- a/cobigen/cobigen-core-parent/cobigen-core-api/src/main/java/com/devonfw/cobigen/api/constants/ConfigurationConstants.java +++ b/cobigen/cobigen-core-parent/cobigen-core-api/src/main/java/com/devonfw/cobigen/api/constants/ConfigurationConstants.java @@ -24,7 +24,19 @@ public class ConfigurationConstants { /** Name of the templates folder */ public static final String TEMPLATES_FOLDER = "templates"; - + + /** Name of the extracted templates project */ + public static final String COBIGEN_TEMPLATES = "CobiGen_Templates"; + + /** Name of the environment variable pointing to cobigen configuration file */ + public static final String COBIGEN_CONFIG_DIR = "COBIGEN_CONFIG_DIR"; + + /** Name of cobigen configuration file */ + public static final String COBIGEN_CONFIG_FILE = ".cobigen"; + + /**Name of configuration key for location of templates. It could be Cobigen_Templates folder, an artifact or a maven dependency*/ + public static final String COBIGEN_CONFIG_TEMPLATES_LOCATION_KEY = "cobigen.templates.templates_location"; + /** Resource folder containing templates */ public static final String TEMPLATE_RESOURCE_FOLDER = "src/main/templates"; diff --git a/cobigen/cobigen-core-parent/cobigen-core-api/src/main/java/com/devonfw/cobigen/api/util/StringUtil.java b/cobigen/cobigen-core-parent/cobigen-core-api/src/main/java/com/devonfw/cobigen/api/util/StringUtil.java index 2e795308a4..74eae40f48 100644 --- a/cobigen/cobigen-core-parent/cobigen-core-api/src/main/java/com/devonfw/cobigen/api/util/StringUtil.java +++ b/cobigen/cobigen-core-parent/cobigen-core-api/src/main/java/com/devonfw/cobigen/api/util/StringUtil.java @@ -31,4 +31,21 @@ public static String uncapFirst(String in) { return in.substring(0, 1).toLowerCase() + in.substring(1, in.length()); } + /** + * Consolidates all line endings to the given one + * + * @param codeBlock + * which should be consolidate + * @param lineDelimiter + * the line delimiter of the file or null if none + * @return the consolidated code block + * @author mbrunnli (04.06.2013) + */ + public static String consolidateLineEndings(String codeBlock, String lineDelimiter) { + if (lineDelimiter != null) { + return codeBlock.replaceAll("\r\n|\r|\n", lineDelimiter); + } + return codeBlock; + } + } diff --git a/cobigen/cobigen-core-parent/cobigen-core-api/src/main/java/com/devonfw/cobigen/api/util/SystemUtil.java b/cobigen/cobigen-core-parent/cobigen-core-api/src/main/java/com/devonfw/cobigen/api/util/SystemUtil.java index 96b475f3e6..3a1c8932db 100644 --- a/cobigen/cobigen-core-parent/cobigen-core-api/src/main/java/com/devonfw/cobigen/api/util/SystemUtil.java +++ b/cobigen/cobigen-core-parent/cobigen-core-api/src/main/java/com/devonfw/cobigen/api/util/SystemUtil.java @@ -1,5 +1,11 @@ package com.devonfw.cobigen.api.util; +import java.io.BufferedInputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.file.Path; + /** * This util class provides system properties */ @@ -15,4 +21,63 @@ public class SystemUtil { */ public static final String LINE_SEPARATOR = java.lang.System.getProperty("line.separator"); + /** + * Determines the line delimiter + * + * @param path + * The path containing the input file + * @param targetCharset + * target char set of the file to be read and write + * @return The line delimiter corresponding to the input file + * @throws IOException + * If an exception occurs while processing the {@link BufferedInputStream} or the + * {@link InputStreamReader} + */ + public static String determineLineDelimiter(Path path, String targetCharset) throws IOException { + + try (FileInputStream stream = new FileInputStream(path.toString()); + BufferedInputStream bis = new BufferedInputStream(stream); + InputStreamReader reader = new InputStreamReader(bis, targetCharset)) { + + bis.mark(0); + try { + while (reader.ready()) { + int nextChar = reader.read(); + if (nextChar == '\r') { + nextChar = reader.read(); + if (nextChar == '\n') { + return "\r\n"; + } + return "\r"; + } else if (nextChar == '\n') { + return "\n"; + } + } + return null; + } finally { + emptyReader(reader); + bis.reset(); + } + + } catch (IOException e) { + throw new IOException("Could not read file:" + path.toString(), e); + } + + } + + /** + * Empties the {@link InputStreamReader} + * + * @param reader + * The {@link InputStreamReader} that is to be emptied + * @throws IOException + * If an exception occurs while processing the {@link InputStreamReader} + */ + private static void emptyReader(InputStreamReader reader) throws IOException { + while (reader.ready()) { + reader.read(); + } + + } + } diff --git a/cobigen/cobigen-core-parent/cobigen-core-api/src/test/java/com/devonfw/cobigen/api/StringUtilTest.java b/cobigen/cobigen-core-parent/cobigen-core-api/src/test/java/com/devonfw/cobigen/api/StringUtilTest.java new file mode 100644 index 0000000000..c806f7f3f0 --- /dev/null +++ b/cobigen/cobigen-core-parent/cobigen-core-api/src/test/java/com/devonfw/cobigen/api/StringUtilTest.java @@ -0,0 +1,36 @@ +package com.devonfw.cobigen.api; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; + +import com.devonfw.cobigen.api.util.StringUtil; + +/** + * + */ +public class StringUtilTest { + + /** Testdata root path */ + private static final String testdataRoot = "src/test/resources/testdata/unittest/StringUtilTest"; + + /** + * Tests whether consolidateLineEndings returns proper line endings for Windows, Linux and Osx + * @throws Exception + * test fails + */ + @Test + public void testConsolidateLineEndings() throws Exception { + String origin = "\n"; + String origin2 = "\r\n"; + String lineDelimiterWindows = "\r\n"; + String lineDelimiterLinux = "\n"; + String lineDelimiterOsx = "\r"; + String consolidatedWindows = StringUtil.consolidateLineEndings(origin, lineDelimiterWindows); + String consolidatedLinux = StringUtil.consolidateLineEndings(origin2, lineDelimiterLinux); + String consolidatedOsx = StringUtil.consolidateLineEndings(origin, lineDelimiterOsx); + assertThat(consolidatedWindows).isEqualTo(lineDelimiterWindows); + assertThat(consolidatedLinux).isEqualTo(lineDelimiterLinux); + assertThat(consolidatedOsx).isEqualTo(lineDelimiterOsx); + } +} diff --git a/cobigen/cobigen-core-parent/cobigen-core-api/src/test/java/com/devonfw/cobigen/api/SystemUtilTest.java b/cobigen/cobigen-core-parent/cobigen-core-api/src/test/java/com/devonfw/cobigen/api/SystemUtilTest.java new file mode 100644 index 0000000000..cd02163a68 --- /dev/null +++ b/cobigen/cobigen-core-parent/cobigen-core-api/src/test/java/com/devonfw/cobigen/api/SystemUtilTest.java @@ -0,0 +1,57 @@ +package com.devonfw.cobigen.api; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.junit.Test; + +import com.devonfw.cobigen.api.util.SystemUtil; + +/** Test suite for {@link SystemUtil}. */ +public class SystemUtilTest { + + /** Testdata root path */ + private static final String testdataRoot = "src/test/resources/testdata/unittest/SystemUtilTest"; + + /** + * Tests whether determineLineDelimiter returns Linux line endings + * @throws Exception + * test fails + */ + @Test + public void testDetermineLineDelimiterLinux() throws Exception { + Path path = Paths.get(testdataRoot, "TestLinuxLineEndings.txt"); + String targetCharset = "UTF-8"; + String lineEnding = SystemUtil.determineLineDelimiter(path, targetCharset); + assertThat(lineEnding).isEqualTo("\n"); + } + + /** + * Tests whether determineLineDelimiter returns Windows line endings + * @throws Exception + * test fails + */ + @Test + public void testDetermineLineDelimiterWindows() throws Exception { + Path path = Paths.get(testdataRoot, "TestWindowsLineEndings.txt"); + String targetCharset = "UTF-8"; + String lineEnding = SystemUtil.determineLineDelimiter(path, targetCharset); + assertThat(lineEnding).isEqualTo("\r\n"); + } + + /** + * Tests whether determineLineDelimiter returns Osx line endings + * @throws Exception + * test fails + */ + @Test + public void testDetermineLineDelimiterOsx() throws Exception { + Path path = Paths.get(testdataRoot, "TestOsxLineEndings.txt"); + String targetCharset = "UTF-8"; + String lineEnding = SystemUtil.determineLineDelimiter(path, targetCharset); + assertThat(lineEnding).isEqualTo("\r"); + } + +} diff --git a/cobigen/cobigen-core-parent/cobigen-core-api/src/test/resources/testdata/unittest/SystemUtilTest/TestLinuxLineEndings.txt b/cobigen/cobigen-core-parent/cobigen-core-api/src/test/resources/testdata/unittest/SystemUtilTest/TestLinuxLineEndings.txt new file mode 100644 index 0000000000..0a207c060e --- /dev/null +++ b/cobigen/cobigen-core-parent/cobigen-core-api/src/test/resources/testdata/unittest/SystemUtilTest/TestLinuxLineEndings.txt @@ -0,0 +1,2 @@ +a +b \ No newline at end of file diff --git a/cobigen/cobigen-core-parent/cobigen-core-api/src/test/resources/testdata/unittest/SystemUtilTest/TestOsxLineEndings.txt b/cobigen/cobigen-core-parent/cobigen-core-api/src/test/resources/testdata/unittest/SystemUtilTest/TestOsxLineEndings.txt new file mode 100644 index 0000000000..fcdf2130c8 --- /dev/null +++ b/cobigen/cobigen-core-parent/cobigen-core-api/src/test/resources/testdata/unittest/SystemUtilTest/TestOsxLineEndings.txt @@ -0,0 +1 @@ +e f \ No newline at end of file diff --git a/cobigen/cobigen-core-parent/cobigen-core-api/src/test/resources/testdata/unittest/SystemUtilTest/TestWindowsLineEndings.txt b/cobigen/cobigen-core-parent/cobigen-core-api/src/test/resources/testdata/unittest/SystemUtilTest/TestWindowsLineEndings.txt new file mode 100644 index 0000000000..7abb43b567 --- /dev/null +++ b/cobigen/cobigen-core-parent/cobigen-core-api/src/test/resources/testdata/unittest/SystemUtilTest/TestWindowsLineEndings.txt @@ -0,0 +1,2 @@ +c +d \ No newline at end of file diff --git a/cobigen/cobigen-core-parent/cobigen-core-systemtest/pom.xml b/cobigen/cobigen-core-parent/cobigen-core-systemtest/pom.xml index 15b705e0b4..28ade469c7 100644 --- a/cobigen/cobigen-core-parent/cobigen-core-systemtest/pom.xml +++ b/cobigen/cobigen-core-parent/cobigen-core-systemtest/pom.xml @@ -26,13 +26,13 @@ ${project.groupId} tempeng-freemarker - 7.0.0-SNAPSHOT + 7.0.0 test ${project.groupId} javaplugin - 7.0.0-SNAPSHOT + 7.0.0 test diff --git a/cobigen/cobigen-core-parent/cobigen-core/pom.xml b/cobigen/cobigen-core-parent/cobigen-core/pom.xml index 0fc1131283..16144ab6da 100644 --- a/cobigen/cobigen-core-parent/cobigen-core/pom.xml +++ b/cobigen/cobigen-core-parent/cobigen-core/pom.xml @@ -70,6 +70,14 @@ jackson-databind 2.10.0 + + + + com.github.stefanbirkner + system-lambda + 1.1.0 + test + diff --git a/cobigen/cobigen-core-parent/cobigen-core/src/main/java/com/devonfw/cobigen/impl/CobiGenFactory.java b/cobigen/cobigen-core-parent/cobigen-core/src/main/java/com/devonfw/cobigen/impl/CobiGenFactory.java index 2edfd36512..86c4b8cd4e 100644 --- a/cobigen/cobigen-core-parent/cobigen-core/src/main/java/com/devonfw/cobigen/impl/CobiGenFactory.java +++ b/cobigen/cobigen-core-parent/cobigen-core/src/main/java/com/devonfw/cobigen/impl/CobiGenFactory.java @@ -14,6 +14,7 @@ import com.devonfw.cobigen.impl.config.ContextConfiguration; import com.devonfw.cobigen.impl.extension.PluginRegistry; import com.devonfw.cobigen.impl.healthcheck.HealthCheckImpl; +import com.devonfw.cobigen.impl.util.ConfigurationUtil; import com.devonfw.cobigen.impl.util.FileSystemUtil; /** @@ -46,6 +47,24 @@ public static CobiGen create(URI configFileOrFolder) throws InvalidConfiguration return createBean; } + /** + * Creates a new {@link CobiGen} + * + * @return a new instance of {@link CobiGen} + * @throws IOException + * if the {@link URI} points to a file or folder, which could not be read. + * @throws InvalidConfigurationException + * if the context configuration could not be read properly. + */ + public static CobiGen create() throws InvalidConfigurationException, IOException { + URI configFileOrFolder = ConfigurationUtil.findTemplatesLocation(); + if (configFileOrFolder == null) { + throw new InvalidConfigurationException( + "No valid templates can be found. Please configure your cobigen configuration file properly or place the templates in cobigen home directory. Creating CobiGen instance aborted."); + } + return create(configFileOrFolder); + } + /** * Creates a new {@link HealthCheck}. * @return a new {@link HealthCheck} instance diff --git a/cobigen/cobigen-core-parent/cobigen-core/src/main/java/com/devonfw/cobigen/impl/util/ConfigurationUtil.java b/cobigen/cobigen-core-parent/cobigen-core/src/main/java/com/devonfw/cobigen/impl/util/ConfigurationUtil.java new file mode 100644 index 0000000000..1fe0afd453 --- /dev/null +++ b/cobigen/cobigen-core-parent/cobigen-core/src/main/java/com/devonfw/cobigen/impl/util/ConfigurationUtil.java @@ -0,0 +1,119 @@ +package com.devonfw.cobigen.impl.util; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Properties; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.devonfw.cobigen.api.constants.ConfigurationConstants; +import com.devonfw.cobigen.api.util.CobiGenPathUtil; + +/** + * Utilities related to the cobigen configurations including: + * + * 1. templates location + */ +public class ConfigurationUtil { + + private static final Logger LOG = LoggerFactory.getLogger(ConfigurationUtil.class); + + /** + * The method finds location of templates. It could be CobiGen_Templates folder or a template artifact + * @return template location uri if exist, otherwise null + */ + public static URI findTemplatesLocation() { + Path configFile = getConfigurationFile(); + if (configFile != null && Files.exists(configFile)) { + LOG.info("Configuration file is located at {}", configFile); + Properties props = readConfigrationFile(configFile); + String templatesLocation = props.getProperty(ConfigurationConstants.COBIGEN_CONFIG_TEMPLATES_LOCATION_KEY); + if (StringUtils.isNotEmpty(templatesLocation)) { + Path templatesPath = Paths.get(templatesLocation); + if (Files.exists(templatesPath)) { + return Paths.get(templatesLocation).toUri(); + } else { + LOG.info( + "Value of property {} in {} is invalid. Trying to look for templates in cobigen home directory {}", + ConfigurationConstants.COBIGEN_CONFIG_TEMPLATES_LOCATION_KEY, configFile, + CobiGenPathUtil.getCobiGenFolderPath()); + } + } else { + LOG.info("Property {} is not set in {}. Trying to look for templates in cobigen home directory {}", + ConfigurationConstants.COBIGEN_CONFIG_TEMPLATES_LOCATION_KEY, configFile, + CobiGenPathUtil.getCobiGenFolderPath()); + } + } else { + LOG.info("No configuration file is found. Trying to look for templates in cobigen home directory {}", + CobiGenPathUtil.getCobiGenFolderPath()); + } + return findTemplatesInCobigenHome(); + } + + /** + * Find the cobigen configuration file + * @return a path of cobigen configuration file if exist, otherwise null + */ + private static Path getConfigurationFile() { + String envValue = System.getenv(ConfigurationConstants.COBIGEN_CONFIG_DIR); + if (StringUtils.isNotEmpty(envValue)) { + return Paths.get(envValue).resolve(ConfigurationConstants.COBIGEN_CONFIG_FILE); + } else { + Path cobigenHome = CobiGenPathUtil.getCobiGenFolderPath(); + if (cobigenHome != null) { + return cobigenHome.resolve(ConfigurationConstants.COBIGEN_CONFIG_FILE); + } + } + return null; + } + + /** + * This is a helper method to read a given cobigen configuration file + * @param cobigenConfigFile: + * cobigen configuration file + * @return Properties containing configuration + */ + private static Properties readConfigrationFile(Path cobigenConfigFile) { + Properties props = new Properties(); + try (BufferedReader reader = Files.newBufferedReader(cobigenConfigFile, Charset.forName("UTF-8"))) { + props.load(reader); + } catch (IOException e) { + LOG.error("An error occured while reading the config file {}", cobigenConfigFile, e); + } + return props; + } + + /** + * This is a helper method to find templates in cobigen home + * @return templates location if found, otherwise null + */ + private static URI findTemplatesInCobigenHome() { + Path templatesPath = CobiGenPathUtil.getTemplatesFolderPath(); + if (templatesPath == null) { + return null; + } + Path templatesFolderPath = templatesPath.resolve(ConfigurationConstants.COBIGEN_TEMPLATES); + if (Files.exists(templatesFolderPath)) { + // use Cobigen_Templates folder + return templatesFolderPath.toUri(); + } else { + // use template jar + File templateJar = TemplatesJarUtil.getJarFile(false, templatesPath.toFile()); + if (templateJar != null && Files.exists(templatesPath)) { + return templateJar.toURI(); + } + } + LOG.info( + "Could not find any templates in cobigen home directory {}. Templates should be placed in the subdirectory /templates/CobiGen_Templates or /templates/.jar", + CobiGenPathUtil.getCobiGenFolderPath()); + return null; + } +} diff --git a/cobigen/cobigen-core-parent/cobigen-core/src/test/java/com/devonfw/cobigen/unittest/config/utils/ConfigurationUtilTest.java b/cobigen/cobigen-core-parent/cobigen-core/src/test/java/com/devonfw/cobigen/unittest/config/utils/ConfigurationUtilTest.java new file mode 100644 index 0000000000..cc5eb095bc --- /dev/null +++ b/cobigen/cobigen-core-parent/cobigen-core/src/test/java/com/devonfw/cobigen/unittest/config/utils/ConfigurationUtilTest.java @@ -0,0 +1,72 @@ +package com.devonfw.cobigen.unittest.config.utils; + +import static com.github.stefanbirkner.systemlambda.SystemLambda.restoreSystemProperties; +import static com.github.stefanbirkner.systemlambda.SystemLambda.withEnvironmentVariable; +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; + +import org.apache.commons.io.FileUtils; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import com.devonfw.cobigen.api.constants.ConfigurationConstants; +import com.devonfw.cobigen.impl.util.ConfigurationUtil; +import com.devonfw.cobigen.unittest.config.common.AbstractUnitTest; + +/** + * + */ +public class ConfigurationUtilTest extends AbstractUnitTest { + @Rule + public TemporaryFolder userhome = new TemporaryFolder(); + + @Test + public void testFindTemplatesLocation() throws Exception { + restoreSystemProperties(() -> { + System.setProperty("user.home", userhome.getRoot().getAbsolutePath()); + File cobigenHome = userhome.newFolder(ConfigurationConstants.COBIGEN_HOME_FOLDER); + File templatesFolder = + userhome.newFolder(ConfigurationConstants.COBIGEN_HOME_FOLDER, ConfigurationConstants.TEMPLATES_FOLDER); + String templatesArtifact = "templates-devon4j-1.0.jar"; + + // no configuration file exists + // no templates found + assertThat(ConfigurationUtil.findTemplatesLocation()).isNull(); + File templatesProject = new File(templatesFolder, ConfigurationConstants.COBIGEN_TEMPLATES); + File templatesJar = new File(templatesFolder, templatesArtifact); + templatesProject.createNewFile(); + templatesJar.createNewFile(); + // found CobiGen_Templates project + assertThat(ConfigurationUtil.findTemplatesLocation()).isEqualTo(templatesProject.toURI()); + templatesProject.delete(); + // found templates artifact + assertThat(ConfigurationUtil.findTemplatesLocation()).isEqualTo(templatesJar.toURI()); + + // configuration file exists + File randomDirectoryForConfigFile = userhome.newFolder(); + File randomDirectoryForTemplates = userhome.newFolder(); + File configFile = new File(randomDirectoryForConfigFile, ConfigurationConstants.COBIGEN_CONFIG_FILE); + File templates = new File(randomDirectoryForTemplates, templatesArtifact); + configFile.createNewFile(); + templates.createNewFile(); + + String templatesLocation = templates.getAbsolutePath().replace("\\", "\\\\"); + FileUtils.writeStringToFile(configFile, + ConfigurationConstants.COBIGEN_CONFIG_TEMPLATES_LOCATION_KEY + "=" + templatesLocation); + + withEnvironmentVariable(ConfigurationConstants.COBIGEN_CONFIG_DIR, + randomDirectoryForConfigFile.getAbsolutePath()).execute( + () -> { + // configuration file found from environment variable + assertThat(ConfigurationUtil.findTemplatesLocation()).isEqualTo(templates.toURI()); + }); + + File configFileInCobigenHome = new File(cobigenHome, ConfigurationConstants.COBIGEN_CONFIG_FILE); + FileUtils.copyFile(configFile, configFileInCobigenHome); + // configuration file found in cobigen home directory + assertThat(ConfigurationUtil.findTemplatesLocation()).isEqualTo(templates.toURI()); + }); + } +} diff --git a/cobigen/cobigen-core-parent/pom.xml b/cobigen/cobigen-core-parent/pom.xml index 3f74d065de..db8082a620 100644 --- a/cobigen/cobigen-core-parent/pom.xml +++ b/cobigen/cobigen-core-parent/pom.xml @@ -12,7 +12,7 @@ - 7.0.0 + 7.1.0 diff --git a/documentation/master-cobigen.asciidoc b/documentation/master-cobigen.asciidoc index d4ece545c1..03d36bf02f 100644 --- a/documentation/master-cobigen.asciidoc +++ b/documentation/master-cobigen.asciidoc @@ -17,7 +17,7 @@ DISCLAIMER: All Cobigen plugins are compatible with the latest release of Devonf --- -* CobiGen v7.0.0 +* CobiGen v7.1.0 * CobiGen - Java Plug-in v7.0.0 * CobiGen - XML Plug-in v7.0.0 * CobiGen - TypeScript Plug-in v7.1.0