Golang之go module開發系列二--使用偽版本和GoCenter

JFrog傑蛙科技發表於2020-04-24


Go模組已經為Go開發帶來了秩序,但也存在一些潛在的混亂。管理模組尤其是偽版本可能很困難,尤其是在要進行一些最新更改的情況下。

JFrog GoCenter是一個免費的版本話棋模組倉庫,現在它包含了一些重要的更新,可以幫助你堅持這個最佳實踐。首先讓我們看看偽版本是如何工作的,以及您可以期望從這些更改中得到什麼。我們還提供了一些指導,讓您在升級到1.13或更高版本時保持Go的構建工作。



Go 的模組版本化

對Go模組進行版本化是一個關鍵特性,它為開發人員提供了一種方法來確保他們的應用程式使用他們想要的依賴項。在對模組進行版本控制時,應用程式可以指定依賴的模組版本,因為我們知道模組版本與其他元件執行時相容問題。


Go模組版本是透過在底層源儲存庫中標記其修訂來分配的。go命令使用標準形式vX.Y.Z的語義版本控制,以此來描述模組的版本。版本號根據API的變化而變化,如下圖:

Golang之go module開發系列二--使用偽版本和GoCenter



從這個標準格式中,可以比較模組版本,以確定哪個應該被認為是最當前的,哪個應該被認為是最不當前的。



使用Pseudo-Versions(偽版本)

版本化的Go模組是已經發布的,供一般使用的模組,應該是大多數開發人員的首選。但是,在某些情況下,您不能釋出模組的最新版本。

例如,一個團隊可能需要在開發期間共享一個臨時版本。特別是當一個依賴的專案還沒有釋出版本時,所以它還沒有被標記上版本。類似地,您可能需要針對尚未標記(打tag)的提交進行開發。

要使用未標記版本的模組作為依賴項,必須透過其偽版本識別符號引用它。偽版本的格式如下:

Golang之go module開發系列二--使用偽版本和GoCenter


偽版本有三種可接受的形式:

· Vx.0.0-yyyymmddhhmms-abcdefxyz,當在目標提交之前沒有使用適當的主版本進行早期版本提交時

· vX.Y.Z-pre.0.yyyymmddhhmms -abcdefxyz。當目標提交之前的最新版本提交是vX.Y.Z-pre時,

· vX.Y.(Z + 1) 0.yyyymmddhhmms -abcdefxyz。當目標提交之前的最新版本提交是vX.Y.Z時,

作為一種最佳實踐,偽版本字串不應該是手工輸入的。go命令將接受普通的提交雜湊並自動將其轉換為偽版本。此方法有助於根據生成的時間戳比較修訂。

例如,一個go get命令可能只使用模組查詢的提交雜湊(githash):

Golang之go module開發系列二--使用偽版本和GoCenter


同時,這裡存在無法讓go命令自動生成偽版本存在問題:

·偽版本參與最小版本選擇。如果它的版本字首不準確,那麼偽版本的優先順序可能比隨後的版本更高,從而有效地將模組固定到提交

·偽版本中的提交日期提供了偽版本之間的總順序,因此如果它被編輯,就會打亂順序

儘管有這樣的建議,但有時我們會手工修改的go模組中可能存在一個偽版本。在其他情況下,完整的偽版本字串可能由第三方工具生成。


更嚴格的規則Go 1.13

GO的發行版1.12,Go對偽版本引用進行了修改。大多數涉及偽版本的操作都接受版本字串和日期的任意組合,並且只要該修訂存在,就會解析為基礎修訂(通常是Git提交雜湊,git hash)。

然而Go 1.13的釋出帶來了更嚴格的規則,以解決上面提到的問題。Go 1.13對“Go”命令接受的偽版本進行了限制,使一些以前接受但不規範的版本無效。

現在,go客戶端將針對版本控制後設資料對偽版本的不同元素執行一些驗證:

· 版本字首的格式必須為vX.0.0,或者從命名修訂版本的祖先上的標籤派生,或者從包含命名修訂版本本身上的構建後設資料的標籤派生。

· 日期字串必須與修訂版的UTC時間戳匹配。

· 修訂的簡稱必須使用與go命令生成的字元相同的字元數。(對於git使用的SHA-1雜湊,為12位數字的字首。)

· 僅當對應的主要版本需要偽版本,並且僅當基礎模組沒有go.mod檔案時,偽版本才包含“ +不相容”( ‘+incompatible’)字尾

· 即使從代理解析了模組之後,go客戶端也會嘗試從校驗和伺服器獲取校驗和內容,該伺服器(Go sumdb)將執行相同的偽版本驗證規則,並拒絕提供校驗和內容,防止代理進行偽裝


1.13之前的Go版本不執行有關偽版本元件的這些規則。這意味著,即使使用者不應該手動生成偽版本,也可以在多個偽版本中使用相同的提交雜湊,而不會出現任何問題。


如何修復不正確的偽版本

為了遷移到1.13,開發人員必須糾正所有不符合上述要求的偽版本引用。否則go客戶端會標記一個異常:

go get  golang.org/x/sys@v0.0.0-20190726090000-fde4db37ae7a: invalid

pseudo-version: does not match version-control timestamp (2019-08-13T06:44:41Z)

幸運的是,透過建立偽版本引用的go.mod檔案很容易做到這一點。

如果go.mod檔案require指令的偽版本不正確,可以透過以下方法更正此錯誤:

1. 用提交雜湊字串替換完整的偽版本引用4

Golang之go module開發系列二--使用偽版本和GoCenter

執行go mod tidy以使go客戶端執行正確的替換。

[if !supportLists]2.      [endif]如果其中一個傳遞依賴項引用了無效的偽版本,則可以replace在go.mod檔案中使用指令來強制更正:

Golang之go module開發系列二--使用偽版本和GoCenter

GoCenter 如何應對上述變化

GoCenter的目標是與Go版本無關(即使在1.13之前,我們也支援所有Go模組版本)。JFrog的社群工程團隊已經對GoCenter進行了重要的更新,以支援Go 1.13的所有版本,我們正在進行進一步的更新,以滿足Go 1.14的要求。

GoCenter現在透過重定向到正確的偽版本來幫助您遵從偽版本驗證。當請求模組下載錯誤的偽版本時,GoCenter將使用正確的版本修改.info中的後設資料。

Golang之go module開發系列二--使用偽版本和GoCenter


要使用GoCenter,請設定GOPROXY 

Golang之go module開發系列二--使用偽版本和GoCenter


針對Go 1.12

對於Go 1.12使用者,GoCenter將更新Go。用正確的偽版本儲存在其儲存庫中的go.mod檔案。GoCenter仍將提供在此更改之前在GoCenter中處理的不正確的偽版本。

Golang之go module開發系列二--使用偽版本和GoCenter

針對Go 1.13

Go 1.13使用者將收到一條錯誤訊息,指出正確的偽版本。

Golang之go module開發系列二--使用偽版本和GoCenter

以便在go.mod檔案中更新正確的偽版本,Go 1.13使用者只需要改變Go get包含偽版本中的提交雜湊(git hash)部分。

Golang之go module開發系列二--使用偽版本和GoCenter

如果希望覆蓋此行為並讓GoCenter提供前面處理的錯誤偽版本,則可以設定GOSUMDB= off。


Go 1.14對於Go Module的變更

正如我們所注意到的,JFrog正在修改GoCenter以支援Go 1.14。以下是該版本中可能會影響模組操作的一些更改,您可能希望瞭解這些更改:

1. Go命令標誌

· go get命令不再接受-mod標誌

· 如果沒有頂級供應商目錄並且go.mod檔案是隻讀的,則預設設定-mod = readonly

· 引入了-modfile = file新標記,該標記指示go命令讀取/寫入備用go.mod檔案,還將使用備用go.sum檔案。儘管仍必須存在名為go.mod的檔案才能確定模組的根目錄


2.go.mod檔案更改

· 除非明確要求或已經要求,go get不會升級到+不相容的主要版本

· go命令(go mod tidy除外)不會刪除require指令,該指令指定主模組的其他依賴項已經隱含的間接依賴項的版本

· 設定-mod = readonly標誌時,go命令不會因缺少go指令或任何錯誤而失敗

3. 模組下載

· go命令現在在模組模式下支援Subversion儲存庫

· Go命令現在包括來自模組代理和其他HTTP伺服器的純文字錯誤訊息的摘要。僅當錯誤訊息是有效的UTF-8且由壟斷圖形字元和空格組成時,才會顯示錯誤訊息。


和GoCenter一起前進

隨著Go模組獲得更大的接受度,標準肯定會改變。您可以依靠JFrog GoCenter來跟上這些變化,並在需求發展時幫助您克服障礙。

如果你還沒有探索GoCenter的免費Go模組庫,我們邀請你去探索!它有一個豐富的UI,可以幫助您檢查所有600,000多個Go模組的資料,可以幫助您獲得對所使用的GoLang依賴項的強大支援。


學習更多技術知識可以關注我們的線上課堂

關注微信公眾號:JFrog傑蛙DevOs, 獲取課程通知


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69954434/viewspace-2688233/,如需轉載,請註明出處,否則將追究法律責任。

相關文章