赞
踩
版本号定义可以参考语义化版本 2.0.0,本文只考虑三位版本号,不考虑先行版本号和版本编译信息。具体如下:
版本格式:主版本号.次版本号.修订号,版本号递增规则如下:
采用 主版本号.次版本号.修订号的格式,且只能使用数字,不能以0开头。
正则表达式为:
^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$
对应java程序及单元测试:
private static final String PATTERN_STR = "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)$"; private static final Pattern VERSION_PATTERN = Pattern.compile(PATTERN_STR); /** * 是否是有效的版本号 * * @param input 字符串 * @return 是否是有效的版本号 */ public static boolean isValidVersion(String input) { if (input == null) { return false; } return VERSION_PATTERN.matcher(input).matches(); }
对应单元测试代码:
private static Stream<String> validVersionProvider() { return Stream.of( "0.0.4", "1.2.3", "10.20.30", "1.0.0", "2.0.0", "1.1.7", "99999999999999999999999.999999999999999999.99999999999999999" ); } private static Stream<String> invalidVersionProvider() { return Stream.of( "1", "1.2", "1.2.3-0123", "+invalid", "invalid", "alpha", "01.1.1", "1.01.1", "1.1.01", "1.2-SNAPSHOT", "1.2-RC-SNAPSHOT" ); } @ParameterizedTest(name = "#{index} - Run test with Version = {0}") @MethodSource("validVersionProvider") void test_version_regex_valid(String inputVersion) { assertTrue(VersionUtils.isValidVersion(inputVersion)); } @ParameterizedTest(name = "#{index} - Run test with Version = {0}") @MethodSource("invalidVersionProvider") void test_version_regex_invalid(String inputVersion) { assertFalse(VersionUtils.isValidVersion(inputVersion)); }
参考:https://semver.org/lang/zh-CN/#spec-item-11
版本的优先层级指的是不同版本在排序时如何比较。
判断优先层级时,必须(MUST)把版本依序拆分为主版本号、次版本号、修订号后进行比较。
由左到右依序比较每个标识符,第一个差异值用来决定优先层级:主版本号、次版本号及修订号以数值比较。
例如:1.0.0 < 2.0.0 < 2.1.0 < 2.1.1。
对应java代码及单元测试代码:
/** * 比较两个版本号大小 * version1比version2大返回1 * version1比version2小返回-1 * version1与version2相同返回0 * * @param version1 version1 * @param version2 version2 * @return 比较结果 */ public static int compare(String version1, String version2) { if (!isValidVersion(version1) || !isValidVersion(version2)) { throw new RuntimeException("invalid version."); } if (version1.equals(version2)) { return 0; } String[] version1Codes = version1.split("\\."); String[] version2Codes = version2.split("\\."); for (int i = 0; i < version1Codes.length; i++) { int code1 = Integer.parseInt(version1Codes[i]); int code2 = Integer.parseInt(version2Codes[i]); if (code1 > code2) { return 1; } else if (code1 < code2) { return -1; } } return 0; }
对应单元测试代码:
@Test @DisplayName("version compare return 1") public void test_version_compare_return_1() { String version1 = "1.1.1"; String version2 = "1.1.0"; Assertions.assertEquals(1, VersionUtils.compare(version1, version2)); version1 = "2.1.1"; version2 = "1.2.0"; Assertions.assertEquals(1, VersionUtils.compare(version1, version2)); version1 = "10.1.1"; version2 = "2.2.0"; Assertions.assertEquals(1, VersionUtils.compare(version1, version2)); } @Test @DisplayName("version compare return -1") public void test_version_compare_return__1() { String version1 = "1.1.1"; String version2 = "1.1.2"; Assertions.assertEquals(-1, VersionUtils.compare(version1, version2)); version1 = "2.1.1"; version2 = "2.2.0"; Assertions.assertEquals(-1, VersionUtils.compare(version1, version2)); version1 = "10.1.1"; version2 = "11.2.0"; Assertions.assertEquals(-1, VersionUtils.compare(version1, version2)); } @Test @DisplayName("version compare return 0") public void test_version_compare_return_0() { String version1 = "1.1.1"; String version2 = "1.1.1"; Assertions.assertEquals(0, VersionUtils.compare(version1, version2)); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。