diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/util/semver/SemVersionInternal.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/util/semver/SemVersionInternal.kt index f71be72f6..d57c226e9 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/util/semver/SemVersionInternal.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/internal/util/semver/SemVersionInternal.kt @@ -21,7 +21,7 @@ internal object SemVersionInternal { private val versionSelect = """^[0-9]+(\.[0-9]+)*\.x$""".toRegex() private val versionMathRange = """([\[\(])([0-9]+(\.[0-9]+)+(|[\-+].+))\s*\,\s*([0-9]+(\.[0-9]+)+(|[\-+].+))([\]\)])""".toRegex() - private val versionRule = """^((\>\=)|(\<\=)|(\=)|(\>)|(\<))\s*([0-9]+(\.[0-9]+)+(|[\-+].+))$""".toRegex() + private val versionRule = """^((\>\=)|(\<\=)|(\=)|(\!\=)|(\>)|(\<))\s*([0-9]+(\.[0-9]+)+(|[\-+].+))$""".toRegex() private val SEM_VERSION_REGEX = """^(0|[1-9]\d*)\.(0|[1-9]\d*)(?:\.(0|[1-9]\d*))?(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$""".toRegex() @@ -127,7 +127,7 @@ internal object SemVersionInternal { } versionRule.matchEntire(trimmed)?.let { result -> val operator = result.groupValues[1] - val version1 = SemVersion.invoke(result.groupValues[7]) + val version1 = SemVersion.invoke(result.groupValues[8]) return when (operator) { ">=" -> { object : SemVersion.Requirement { @@ -154,6 +154,11 @@ internal object SemVersionInternal { override fun test(version: SemVersion): Boolean = version.compareTo(version1) == 0 } } + "!=" -> { + object : SemVersion.Requirement { + override fun test(version: SemVersion): Boolean = version.compareTo(version1) != 0 + } + } else -> error("operator=$operator, version=$version1") } } diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/SemVersion.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/SemVersion.kt index de1d647f8..a80c467a2 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/SemVersion.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/SemVersion.kt @@ -113,21 +113,28 @@ internal constructor( * * - `1.0.0-M4` 要求 1.0.0-M4 版本, 且只能是 1.0.0-M4 版本 * - `1.x` 要求 1.x 版本 - * - `1.0.0 - 1.2.0` 要求 1.0.0 到 1.2.0 的任意版本, 注意 `-` 两边必须要有空格 - * - `[1.0.0, 1.2.0]` 与 `1.0.0 - 1.2.0` 一致 * - `> 1.0.0-RC` 要求 1.0.0-RC 之后的版本, 不能是 1.0.0-RC * - `>= 1.0.0-RC` 要求 1.0.0-RC 或之后的版本, 可以是 1.0.0-RC * - `< 1.0.0-RC` 要求 1.0.0-RC 之前的版本, 不能是 1.0.0-RC * - `<= 1.0.0-RC` 要求 1.0.0-RC 或之前的版本, 可以是 1.0.0-RC + * - `!= 1.0.0-RC` 要求 除了1.0.0-RC 的任何版本 + * - `[1.0.0, 1.2.0]` + * - `(1.0.0, 1.2.0]` + * - `[1.0.0, 1.2.0)` + * - `(1.0.0, 1.2.0)` [数学区间](https://baike.baidu.com/item/%E5%8C%BA%E9%97%B4/1273117) * - * 对于多个规则, 也允许使用 `||` 拼接. + * 对于多个规则, 允许使用逻辑符号 `{}`, `||`, `&&` * 例如: * - `1.x || 2.x || 3.0.0` * - `<= 0.5.3 || >= 1.0.0` + * - `{> 1.0 && < 1.5} || {> 1.8}` + * - `{> 1.0 && < 1.5} || {> 1.8}` + * - `> 1.0.0 && != 1.2.0` * * 特别注意: * - 依赖规则版本号不需要携带版本号元数据, 元数据不参与依赖需求的检查 * - 如果目标版本号携带有先行版本号, 请不要忘记先行版本号 + * - 因为 `()` 已经用于数学区间, 使用 `{}` 替代 `()` */ @Throws(IllegalArgumentException::class) @JvmStatic diff --git a/backend/mirai-console/src/test/kotlin/net/mamoe/mirai/console/util/TestSemVersion.kt b/backend/mirai-console/src/test/kotlin/net/mamoe/mirai/console/util/TestSemVersion.kt index e7de240c9..3f74dd191 100644 --- a/backend/mirai-console/src/test/kotlin/net/mamoe/mirai/console/util/TestSemVersion.kt +++ b/backend/mirai-console/src/test/kotlin/net/mamoe/mirai/console/util/TestSemVersion.kt @@ -90,6 +90,11 @@ internal class TestSemVersion { .assertFalse("0.98774587") SemVersion.parseRangeRequirement("> 1.0.0") .assertFalse("1.0.0") + SemVersion.parseRangeRequirement("!= 1.0.0 && != 2.0.0") + .assert("1.2.3").assert("2.1.1") + .assertFalse("1.0").assertFalse("1.0.0") + .assertFalse("2.0").assertFalse("2.0.0") + .assert("2.0.1").assert("1.0.1") SemVersion.parseRangeRequirement("> 1.0.0 || < 0.9.0") .assertFalse("1.0.0")