2012-10-22 80 views
13

Maven似乎有能力指出一系列版本,例如<version>[1.2.3,)</version>如果沒有所有開源軟件包遵循的一致版本方案,maven如何確定什麼是新版本或舊版本。例如maven如何排序版本號?

  • 的JUnit 4.10
  • SLF4J 1.7.2
  • 休眠4.1.7.Final
  • 3.1.2.RELEASE

如何行家圖什麼是舊與新的行家包的版本?如果軟件包使用字母作爲版本編號的東西沿線的A,B,C或A2,A2,A4等...

是否應該有一個標準的官方方式來在maven版本軟件包?常見的開源軟件包如spring和hibernate忽略了這個版本規範嗎?

+3

不要使用版本範圍。這是一個誘人的想法,事實證明這是一個糟糕的計劃。如果Maven允許直接列出範圍和指定版本,會更好。指定的版本將被解析,範圍將用於提供可以更新的範圍和/或範圍的範圍在運行時有效的提示。版本範圍混淆了構建時間問題和運行時問題,目前使用Maven的建議很簡單:*不要使用版本範圍* –

+0

@Stephen我同意我認爲Maven會將構建時間依賴與運行時兼容混淆,他們確實需要一個元素,它是框架作者列表,它們與之兼容的框架,但即使如此,仍然需要穩定的方式來對版本號進行排序。例如spring security 3.1.3聲明瞭對spring 3.0.7的依賴,因爲它可以與3.0.7和3.1.2一起使用,如果你使用強制插件來強制版本收斂,那麼你必須排除spring作爲spring安全的依賴。我不使用版本範圍,我使用執行插件強制收斂。 – ams

回答

13

this reference,Maven的要求的版本是這樣的形式:

<MajorVersion [> . <MinorVersion [> . <IncrementalVersion ] ] [> - <BuildNumber | Qualifier ]>

MajorVersionMinorVersionIncrementalVersionBuildNumber都是數字和預選賽是一個字符串。 如果您的版本號與此格式不匹配,則整個版本號將被視爲限定符

如果您使用的是不遵循此版本控制方案的工件,則可以解釋您可能「面臨問題」(特別是Maven版本範圍)。查看從文章鏈接的Maven source code是相當有幫助的。

在您給出的示例中,Hibernate和Spring構件在使用「.」而不是「-」來區分限定符時似乎有所偏差。

我的一些實驗顯示DefaultArtifactVersion將如上所述精確地解析版本號。也就是說,考慮到春節例子(3.1.2.RELEASE)將被解釋爲:

  • 專業:0
  • 輔修:0
  • 增量:0
  • 預選賽:3.1.2.RELEASE

更重要兩個版本號的比較(如果使用Maven 3.0或更高版本)是更靈活。版本號分爲項目列表(其中.-表示項目之間的邊界,請注意.的優先級高於-)。比較是通過將每個項目分期並進行自然順序比較來完成的。因此3.1.2.RELEASE將被視爲小於3.1.3.RELEASE。字符串也被比較,因此3.1.2.RELEASD將被視爲小於3.1.2.RELEASE。有跡象表明,有特殊等價一些特殊的字符串,例如3.1.3.a.1將整理一樣3.1.3.alpha.1

然而,雖然比較是Maven中的較新版本更加靈活。版本範圍邊界仍然使用Major:Minor:Incremental:Qualifier方案進行評估,因此如果您使用版本範圍,則靈活性不太有用。

+0

@StephenConnolly尼斯編輯,謝謝。當作者輸入:-) –

+0

這是一個非常有用的答案,尤其是提示比較的處理方式與上面提到的四組件解析方案不同。需要在C應用程序中比較Maven版本字符串,我寫了一個實用程序庫,其他人可能會覺得有用:https://github.com/flandr/c-maven-utils –

+0

maven是否指定只有0-9是「數字」 ?怎麼樣以36號碼編號的包裹? – Sparr

25

從版本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

主要疑難雜症我在這都發現是snapshotbetarc,所以你不能有1.0-SNAPSHOT開發版本,然後鬆開1.0-beta1或者1.0-rc1,並且Maven明白那些在後面。

還要注意的是1.0-beta-1是完全一樣1.0beta1,並1.0是完全一樣11.0.0

版本範圍現在也以您期望的方式工作(幾乎)。例如,[1.0-alpha-SNAPSHOT,1.0]將發現1.0-beta1-SNAPSHOT,1.0-beta1,1.0-rc1-SNAPSHOT,1.0-rc1,1.0-SNAPSHOT1.0,優選較後的項目而不是較早的項目。這完全由mvn versions:resolve,M2Eclipse等支持。

+1

對Maven版本3.2.0的給定引用是不正確的,因爲這已被Maven版本3.0更改請參見https://maven.apache.org/ref/3.0/maven-artifact/apidocs/org/apache/maven/artifact /versioning/ComparableVersion.html – khmarbaise

+0

你說得對。 Maven實際上使用DefaultArtifactVersion,它通過比較major/minor/incremental/qualifier來實現compareTo(),如果它無法理解版本,則會回退到限定符。我沒有花時間去計算DefaultArtifactVersion的實現更改的時間,以便compareTo()使用ComparableVersion,但它看起來像3.0版一樣,如下所示:http://grepcode.com/file/repo1 .maven.org/maven2/org.apache.maven/maven-artifact/3.0/org/apache/maven/artifact/versioning/DefaultArtifactVersion.java#DefaultArtifactVersion – Jelaby

+0

我編輯了匹配的答案。在你引用的Javadoc中,它表示SNAPSHOT來自'alpha'之前,但實現(在Grepcode上)表明情況並非如此,實際上是在RC之後,正如我在答案中所說的那樣。 – Jelaby

0

你對使用major/minor/incremtal /等的假設簡直是錯誤的。該比較在包含實現的ComparableVersion中完成。該構造函數將調用parseVersion(...)它採用ComparableVersion被存儲爲例如在DefaultArtifactVersion和它在compareTo(..)

使用有喜歡getMajor..等部分,但這些都無法正常工作。這就是爲什麼會be marked deprecated

由Stehpen Collony提供的信息對於Maven 2來說是正確的,但對於Maven 3來說不是這樣。

2

這是一個直接針對來自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-β1-SNAPSHOT
  • 1.0-β1
  • 1.0-β2-SNAPSHOT
  • 1.0-RC1-SNAPSHOT
  • 1.0- RC1
  • 1.0-SN APSHOT
  • 1。0和1(它們是相等的)
  • 1.0-SP
  • 1.0-任何
  • 1.0.1