maven 如何对版本号进行排序?



Maven似乎能够指示一系列版本,例如<version>[1.2.3,)</version>当所有开源软件包都没有一致的版本控制方案时,Maven如何确定什么是较新或较旧的版本。例如

  • 朱尼特4.10
  • SLF4J1.7.2
  • 休眠4.1.7.Final
  • 春季3.1.2.RELEASE

maven如何计算 maven 中软件包的旧版本与新版本是什么?如果软件包使用字母作为版本号,类似于 A、B、C 或 A2、A2、A4 ......等。

是否应该有一种标准的官方方式在 maven 中对包进行版本控制?像 spring 和 hibernate 这样的常见开源包是否忽略了这种版本控制约定?

从版本3.0 开始,Maven 使用一致的系统来比较各个版本和版本范围的版本号。一旦你了解了一些陷阱,这个系统现在就很有意义了。

现在所有的比较都是由ComparableVersion完成的,它说:

  • 混合"-"(破折号)和"."(点)分隔符,
  • 字符和数字之间的转换也构成分隔符:1.0alpha1=>[1, 0, alpha, 1]
  • 无限数量的版本组件,
  • 文本中的版本组件可以是数字或字符串,
  • 检查字符串是否存在已知的限定符,限定符排序用于版本排序。众所周知的限定符(不区分大小写)包括:
    • alphaa
    • betab
    • milestonem
    • rccr
    • snapshot
    • (空字符串)或gafinal
    • sp
  • 未知限定符在
  • 已知限定符之后考虑,具有词法顺序(始终不区分大小写),
  • 破折号通常位于限定符之前,并且总是不如前面带有点的内容重要。

这意味着版本按以下顺序出现,我认为这是非常有意义的,除了中间的 1.0-SNAPSHOT:

  • 1.0-beta1-SNAPSHOT
  • 1.0-beta1
  • 1.0-beta2-SNAPSHOT
  • 1.0-rc1-SNAPSHOT
  • 1.0-rc1
  • 1.0-SNAPSHOT
  • 1.0
  • 1.0-sp
  • 1.0-whatever
  • 1.0.1

我在这一切中发现的主要问题是snapshot是在betarc之后出现的,所以你不能拥有1.0-SNAPSHOT的开发版本,然后发布1.0-beta11.0-rc1,并让Maven了解这些是以后的。

另请注意,1.0-beta-11.0beta1完全相同,1.011.0.0完全相同。

版本范围现在也(几乎)按照您期望的方式工作。例如,[1.0-alpha-SNAPSHOT,1.0]会发现1.0-beta1-SNAPSHOT1.0-beta11.0-rc1-SNAPSHOT1.0-rc11.0-SNAPSHOT1.0,更喜欢后面的项目而不是早期的项目。这得到了mvn versions:resolve、M2Eclipse等的完全支持。

这是一个直接针对 Maven 的 ComparableVersion 类编写的测试。

package org.codehaus.mojo.buildhelper.versioning;
import org.apache.maven.artifact.versioning.ComparableVersion;
import org.junit.Assert;
import org.junit.Test;
public class TempTest {
@Test
public void testVersions() {
Assert.assertTrue(new ComparableVersion("1.0-beta1-SNAPSHOT").compareTo(
new ComparableVersion("1.0-beta1")) < 0);
Assert.assertTrue(new ComparableVersion("1.0-beta1").compareTo(
new ComparableVersion("1.0-beta2-SNAPSHOT")) < 0);
Assert.assertTrue(new ComparableVersion("1.0-beta2-SNAPSHOT").compareTo(
new ComparableVersion("1.0-rc1-SNAPSHOT")) < 0);
Assert.assertTrue(new ComparableVersion("1.0-rc1-SNAPSHOT").compareTo(
new ComparableVersion("1.0-rc1")) < 0);
Assert.assertTrue(new ComparableVersion("1.0-rc1").compareTo(
new ComparableVersion("1.0-SNAPSHOT")) < 0);
Assert.assertTrue(new ComparableVersion("1.0-SNAPSHOT").compareTo(
new ComparableVersion("1.0")) < 0);
Assert.assertTrue(new ComparableVersion("1.0").compareTo(
new ComparableVersion("1")) == 0);
Assert.assertTrue(new ComparableVersion("1.0").compareTo(
new ComparableVersion("1.0-sp")) < 0);
Assert.assertTrue(new ComparableVersion("1.0-sp").compareTo(
new ComparableVersion("1.0-whatever")) < 0);
Assert.assertTrue(new ComparableVersion("1.0-whatever").compareTo(
new ComparableVersion("1.0.1")) < 0);
}
}

此测试断言 Maven 认为以下版本从低到高:

  • 1.0-beta1-快照
  • 1.0-贝塔1
  • 1.0-β2-快照
  • 1.0-rc1-快照
  • 1.0-RC1
  • 1.0-快照
  • 1.0 和 1(相等)
  • 1.0-SP
  • 1.0-随便
  • 1.0.1

你关于使用主要/次要/渐进/等的假设是完全错误的。比较是在包含实现的 ComparableVersion 中完成的。ctor 将调用parseVersion(...),它使用ComparableVersion存储在DefaultArtifactVersion中作为实例,并在compareTo(..)期间使用

有像getMajor..这样的部分,但这些都无法正常工作。这就是将被标记为弃用的原因。

Stehpen Collony的信息适用于Maven 2,但不再适用于Maven 3。

最新更新