diff --git a/multiapps-mta/pom.xml b/multiapps-mta/pom.xml index 387bb766..abe45d1c 100644 --- a/multiapps-mta/pom.xml +++ b/multiapps-mta/pom.xml @@ -21,7 +21,7 @@ commons-collections4 - org.semver4j + com.vdurmont semver4j diff --git a/multiapps-mta/src/main/java/module-info.java b/multiapps-mta/src/main/java/module-info.java index 44aec965..3ab88054 100644 --- a/multiapps-mta/src/main/java/module-info.java +++ b/multiapps-mta/src/main/java/module-info.java @@ -29,7 +29,7 @@ requires org.apache.commons.collections4; requires org.apache.commons.io; requires org.apache.commons.lang3; - requires org.semver4j; + requires semver4j; requires static java.compiler; requires static org.immutables.value; diff --git a/multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/model/Version.java b/multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/model/Version.java index 2b1aee7b..f8f2efc3 100644 --- a/multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/model/Version.java +++ b/multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/model/Version.java @@ -4,11 +4,16 @@ import org.cloudfoundry.multiapps.common.ParsingException; import org.cloudfoundry.multiapps.mta.Messages; -import org.semver4j.Semver; -import org.semver4j.SemverException; +import org.cloudfoundry.multiapps.mta.parsers.PartialVersionConverter; + +import com.vdurmont.semver4j.Semver; +import com.vdurmont.semver4j.Semver.SemverType; +import com.vdurmont.semver4j.SemverException; public class Version implements Comparable { + private static final PartialVersionConverter PARTIAL_VERSION_CONVERTER = new PartialVersionConverter(); + private final Semver version; private Version(Semver version) { @@ -27,12 +32,21 @@ public int getPatch() { return version.getPatch(); } + public String getBuild() { + return version.getBuild(); + } + + public String[] getSuffixTokens() { + return version.getSuffixTokens(); + } + public static Version parseVersion(String versionString) { - var version = Semver.coerce(versionString); //allows incomplete version strings like "3" or "3.0" - if (version == null) { - throw new ParsingException(Messages.UNABLE_TO_PARSE_VERSION, versionString); + try { + String fullVersionString = PARTIAL_VERSION_CONVERTER.convertToFullVersionString(versionString); + return new Version(new Semver(fullVersionString, SemverType.NPM)); + } catch (SemverException e) { + throw new ParsingException(e, Messages.UNABLE_TO_PARSE_VERSION, versionString); } - return new Version(version); } @Override @@ -42,7 +56,7 @@ public int hashCode() { @Override public String toString() { - return version.toString(); + return version.getValue(); } @Override diff --git a/multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/model/VersionRule.java b/multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/model/VersionRule.java index 649719e6..35c5208f 100644 --- a/multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/model/VersionRule.java +++ b/multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/model/VersionRule.java @@ -1,7 +1,5 @@ package org.cloudfoundry.multiapps.mta.model; -import java.util.function.Predicate; - public enum VersionRule { SAME_HIGHER(VersionRule::isNotDowngrade), @@ -10,14 +8,22 @@ public enum VersionRule { ALL(VersionRule::isAny); - private final Predicate versionRuleValidator; + private interface VersionRuleValidator { + boolean allows(DeploymentType deploymentType); + } + + private VersionRuleValidator versionRuleValidator; - VersionRule(Predicate versionRuleValidator) { + VersionRule(VersionRuleValidator versionRuleValidator) { this.versionRuleValidator = versionRuleValidator; } public boolean allows(DeploymentType deploymentType) { - return versionRuleValidator.test(deploymentType); + return versionRuleValidator.allows(deploymentType); + } + + public static VersionRule value(String caseInsensitiveValue) { + return VersionRule.valueOf(caseInsensitiveValue.toUpperCase()); } private static boolean isNotDowngrade(DeploymentType deploymentType) { diff --git a/multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/parsers/PartialVersionConverter.java b/multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/parsers/PartialVersionConverter.java new file mode 100644 index 00000000..22059356 --- /dev/null +++ b/multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/parsers/PartialVersionConverter.java @@ -0,0 +1,48 @@ +package org.cloudfoundry.multiapps.mta.parsers; + +import com.vdurmont.semver4j.Semver; +import com.vdurmont.semver4j.Semver.SemverType; + +public class PartialVersionConverter { + + private static final String VERSION_STRING_TEMPLATE = "%s.%s.%s%s%s"; + private static final String VERSION_SUFFIX_STRING_TEMPLATE = "-%s"; + private static final String VERSION_BUILD_STRING_TEMPLATE = "+%s"; + private static final String DEFAULT_VERSION_SUFFIX = ""; + + public String convertToFullVersionString(String partialVersionString) { + Semver partialVersion = new Semver(partialVersionString, SemverType.LOOSE); + Integer majorVersion = partialVersion.getMajor(); + Integer minorVersion = partialVersion.getMinor(); + Integer patchVersion = partialVersion.getPatch(); + + if (minorVersion == null) { + minorVersion = 0; + } + if (patchVersion == null) { + patchVersion = 0; + } + return buildVersionString(majorVersion, minorVersion, patchVersion, partialVersion.getSuffixTokens(), partialVersion.getBuild()); + } + + private String buildVersionString(int major, int minor, int patch, String[] suffixTokens, String buildVersion) { + String formattedSuffixTokens = formatSuffixTokens(suffixTokens); + String formattedBuildVersion = formatBuildVersion(buildVersion); + return String.format(VERSION_STRING_TEMPLATE, major, minor, patch, formattedSuffixTokens, formattedBuildVersion); + } + + private String formatSuffixTokens(String[] suffixTokens) { + if (suffixTokens.length == 0) { + return DEFAULT_VERSION_SUFFIX; + } + return String.format(VERSION_SUFFIX_STRING_TEMPLATE, String.join(".", suffixTokens)); + } + + private String formatBuildVersion(String buildVersion) { + if (buildVersion == null) { + return DEFAULT_VERSION_SUFFIX; + } + return String.format(VERSION_BUILD_STRING_TEMPLATE, buildVersion); + } + +} diff --git a/multiapps-mta/src/test/java/org/cloudfoundry/multiapps/mta/parsers/PartialVersionConverterTest.java b/multiapps-mta/src/test/java/org/cloudfoundry/multiapps/mta/parsers/PartialVersionConverterTest.java new file mode 100644 index 00000000..5a539d72 --- /dev/null +++ b/multiapps-mta/src/test/java/org/cloudfoundry/multiapps/mta/parsers/PartialVersionConverterTest.java @@ -0,0 +1,72 @@ +package org.cloudfoundry.multiapps.mta.parsers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.stream.Stream; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import com.vdurmont.semver4j.SemverException; + +class PartialVersionConverterTest { + + private final PartialVersionConverter partialVersionConverter = new PartialVersionConverter(); + + @ParameterizedTest + @MethodSource + void testConvertWithInvalidVersions(String versionString, String expectedExceptionMessage) { + SemverException exception = assertThrows(SemverException.class, + () -> partialVersionConverter.convertToFullVersionString(versionString)); + + assertEquals(expectedExceptionMessage, exception.getMessage()); + } + + static Stream testConvertWithInvalidVersions() { + return Stream.of( +// @formatter:off + Arguments.of("1.0.0-beta+", "The build cannot be empty."), + Arguments.of("3.a", "Invalid version (no minor version): 3.a"), + Arguments.of("a.b.c", "Invalid version (no major version): a.b.c"), + Arguments.of( "", "Invalid version (no major version): "), + Arguments.of("[ 2.0, 2.1 ]", "Invalid version (no major version): [ 2.0, 2.1 ]") +// @formatter:on + ); + } + + @ParameterizedTest + @MethodSource + void testConvertWithValidVersions(String versionString, String expectedResult) { + String fullVersionString = partialVersionConverter.convertToFullVersionString(versionString); + + assertEquals(expectedResult, fullVersionString); + } + + static Stream testConvertWithValidVersions() { + return Stream.of( +// @formatter:off + // Full version: + Arguments.of("1.0.0", "1.0.0"), + // Partial version with minor version: + Arguments.of("2.1", "2.1.0"), + // Partial version with patch version: + Arguments.of("2", "2.0.0"), + // Full version with suffix tokens: + Arguments.of("1.9.0-SHAPSHOT", "1.9.0-SHAPSHOT"), + // Partial version with suffix tokens: + Arguments.of("1.9-SHAPSHOT", "1.9.0-SHAPSHOT"), + // Partial version with suffix tokens: + Arguments.of("1-SHAPSHOT", "1.0.0-SHAPSHOT"), + // Full version with suffix tokens and build information: + Arguments.of("1.2.0-beta+exp.sha.5114f85", "1.2.0-beta+exp.sha.5114f85"), + // Partial version with suffix tokens and build information: + Arguments.of("1.2-beta+exp.sha.5114f85", "1.2.0-beta+exp.sha.5114f85"), + // Partial version with suffix tokens and build information: + Arguments.of("1-beta+exp.sha.5114f85", "1.0.0-beta+exp.sha.5114f85") +// @formatter:on + ); + } + +} diff --git a/pom.xml b/pom.xml index 5a48de3e..81f7df33 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,9 @@ 2.11.0 2.0.6 2.0 - 5.2.2 + + + 3.1.0 2.8.8 2.3.3 2.3.0.1 @@ -292,9 +294,9 @@ snakeyaml ${snakeyaml.version} - + - org.semver4j + com.vdurmont semver4j ${semver4j.version}