[譯] 命名有意義的版本號2.0.0-rc1


原文鏈接:http://semver.org/

在軟件管理的世界里有一個可怕的地方叫“依賴地獄(dependency hell)”。你的系統越是成長壯大,你越是整合更多的軟件包到你自己的系統中,你越有可能在將來的某天發現自己已經掉進了這個絕望的深淵。

在一個有着眾多依賴的系統里,發布新版本可能很快成為一個惡夢。如果依賴定義得過於緊密,你就有可能進入版本鎖定(version lock)的狀態(版本鎖定是指一旦更新一個軟件包,就不得不更新其他所有依賴於它的包)。如果依賴定義得過於松散,你又難免會被版本穿插(version promiscuity)所傷(讓人以為會與多得不合理的未來版本兼容)。當你被版本鎖定或版本穿插所阻撓而不能容易地讓你的項目順利前進時,你就身處依賴地獄中了。

作為這個問題的解決方案之一,我提議用一組簡單的規則和要求來約束版本號的分配和增長規則。為了讓這套理論運作,你必須預先定義好自己的公共API。這可以通過文檔定義或代碼強制要求來實現。無論如何,這套API的清楚明了是十分重要的。一旦你定義了公共API,你就可以通過修改相應的版本號來通知大家你的修改。考慮使用這樣的版本號格式:X.Y.Z(主版本號,次版本號,補丁版本號)修復Bug但不影響API時增長補丁版本號;API保持向下兼容的增加/修改時增長次版本號;進行不向下兼容的修改時增長主版本號。

我把這套規則稱為“語義版本命名(Semantic Versioning)”。在這套工作模式下,版本號和它們的增長模式就會傳達從當前版本向下一個版本進行了怎樣的修改。

語義版本(SemVer)命名規范

在篇文章里出現的關鍵字“必須”,“必須不”,“要求”,“應該”,“不應該”,“一定要”,“一定不要”,“推薦”,“可以”和“可選”將在RFC2119中描述和解釋。(以下譯文中原樣使用這些關鍵字看上去會比較生硬,但為了清楚地傳達作者的意圖和保持RFC2119關鍵字的意義,仍然照這里的翻譯來使用——譯者注)

  1. 使用語義版本命名的軟件系統必須定義一套公共API。這套API可以是在代碼中申明或是用嚴格的文檔定義。不管怎樣做,它都應該清楚明了。
  2. 正常的版本號必須使用X.Y.Z的形式並且X/Y/Z是非負整數。X是主版本號,Y是次版本號,Z是補丁版本號。版本號每次必須只能增長1。例如:1.9.0->1.10.0->1.11.0。
  3. 當主版本號增長時,次版本號和補丁版本號必須清零。當次版本號增長時,補丁版本號必須清零。例如:1.1.9->2.0.0,2.1.7->2.2.0。
  4. 一旦發布了具有版本的包,那個版本的內容必須不能再更改。任何修改必須發布成一個新版本。
  5. 主版本號0 (0.y.z)是用來進行初始開發時使用的。任何東西都可能在任何時候改變。公共API此時應該被認為是經常變動的。
  6. 版本1.0.0開始定義公共API。這個版本及以后的版本號的增長方式將依賴於公共API以及它如何變化。
  7. 如果有任何向下兼容的bug修復發生,補丁版本號Z (x.y.Z | x > 0)必須增長1。“bug修復”被定義為內部進行的修復非正常行為的修復工作。
  8. 如果進行了新的並且向下兼容的公共API添加和修改,次版本號Y (x.Y.z | x > 0)必須增長1。如果任何公共API被標記為“過期”,次版本號必須增長1;如果有大量的新功能或改進在內部代碼中發生,次版本號可以增長1;這其中也可以包含補丁級別的修改。當次版本號增長時補丁版本號必須清零。
  9. 如果對公共API有任何向下不兼容的修改,主版本號X (X.y.z | X > 0)必須增長1。這其中也可以包含次版本和補丁版本級別的修改。當主版本號增長時次版本號和補丁版本號必須清零。
  10. 預覽版本(pre-release version)可以通過在補丁版本號后追加中橫線以及由點分隔開的一系列標識來表達。標識必須由ASCII字符和中橫線[0-9A-Za-z-]組成。預覽版本能滿足相關版本的要求,但優先級低於相關版本。例如:1.0.0-alpha,1.0.0-alpha.2,1.0.0-0.3.7,1.0.0-x.7.z.92。
  11. 構建版本(build version)可以通過在補丁版本號或預覽版本后追加一個加號和一系列由點分隔標識來表達。標識必須由ASCII字符和中橫線[0-9A-Za-z-]組成。構建版本能夠滿足相關版本的要求,並且優先於相關版本。例如:1.0.0+build.1,1.3.7+build.11.e0f985a。
  12. 將版本號分為主版本號、次版本號、補丁版本號,預覽版本,構建版本,必須按這樣的按順序分別逐級考慮來確定版本順序。主版本號、次版本號,補丁版本號總是通過數字大小來確定順序。預覽版本和構建版本的順序必須由比較由點分隔標識來確定,規則如下:如果標識只有數字,則由數字大小決定;如果標識包含字符和中橫線,則由比較字符的字典順序來確定。數字標識的順序永遠低於非數字標識。例如:1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0-rc.1+build.1 < 1.0.0 < 1.0.0+0.3.7 < 1.3.7+build < 1.3.7+build.2.b8f12d7 < 1.3.7+build.11.e0f985a。

為什么使用語義版本命名?

這並不是一個全新的革命性的想法。事實上,你可能已經做了和這差不多的事情了。問題是“差不多”還不夠好。如果不服從某種正式的規范,版本號對於版本依賴管理就失去了本質上的意義。通過給以上的想法一個清楚的定義和命名,與你的軟件用戶溝通你的意圖就變得容易了。一旦這些意圖明確表達出來,靈活(但不是過於靈活)的依賴定義就可以最終被制定出來。

一個簡單的例子可以演示語義版本命名如何讓版本地獄成為過去。考慮有一個庫叫做“救火車”。它需要一個語義版本命名的包“雲梯”。當救火車被制造的時候,雲梯的版本是3.1.0。因為救火車一開始使用了由雲梯3.1.0提供的某些功能,你可以安全地知道對雲梯的正確依賴是在3.1.0以后並且4.0.0之前。現在,當雲梯版本3.1.1和3.2.0發布時,你就可以把它們放到你的軟件包管理系統中並且知道它們會與依賴它的軟件兼容。

作為一個有責任的開發人員,你當然一定會想要確保所有軟件包更新都被廣而告之。現實世界是一個混亂的地方,除了提高警惕我們別無他法。你所能做的是讓語義版本命名為你提供一個健全的方式來發布版本更新軟件包,而不必更新所有的依賴軟件包,這將會節省你的時間,少為你添麻煩。

如果這些聽起來讓你滿意的話,你所需要對語義版本命名做的事情就是:申明你正在使用它並且按它的要求辦事。在你的README文檔中鏈接到這個網站,讓其他人知道這些規則並且從中受益。

FAQ

【內容太多,過兩天再補】

關於

語義版本命名規范由Tom Preston-Werner提出,他是Gravatars的創始人和GitHub的合作創始人。

如果你想留下一些反饋,請在GitHub提交一個新的問題

License

Creative Commons - CC BY 3.0 http://creativecommons.org/licenses/by/3.0/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM