[Go]Golang 1.16 中 Modules的主要變化更新

本文轉載,目的方便查閱html

01介紹git

Golang 1.16 已經正式發佈了,其中 Modules 有一些變化:github

  • 默認開啓 Modules。
  • 不自動修改 go.mod 和 go.sum
  • 經過指定 @version 後綴安裝特定版本可執行文件。
  • 新增 retract 指令撤回 Module 版本。
  • 使用新增配置變量 GOVCS 指定特定模塊使用特定版本控制工具。

02默認開啓 Modulesgolang

golang 1.16 默認開啓 Modules,即便不存在 go.mod,Go 命令如今默認狀況下也會在 module-aware(模塊感知)模式下構建包。緩存

在 golang 1.16 中,經過設置關閉 GO111MODULE 環境變量,在 GOPATH 模式下構建包仍然是可能的。您還能夠將 GO111MODULE 設置爲 auto,以便在當前目錄或任何父目錄中存在 go.mod 文件時啓用 module-aware (模塊感知)模式。您還可使用 go env -w 永久設置 GO111MODULE 和其餘變量,:安全

 go env -w GO111MODULE=auto服務器

Go 官方計劃在 Go 1.17 中放棄對 GOPATH 模式的支持。換句話說,Go 1.17 將忽略 GO111MODULE。若是您的項目不在 module-aware (模塊感知)模式下構建,則如今是時候遷移至 module-aware (模塊感知)模式了。網絡

03不自動修改 go.mod 和 go.sum編輯器

在 golang 1.16 以前版本中,當 go 命令發現 go.mod 或 go.sum 存在問題時,如缺乏 require 指令或缺乏 sum,它將嘗試自動解決問題。Go 官方收到不少反饋,這種行爲是使人驚訝的,特別是對於 go 命令,如 go list,一般沒有反作用。自動修復並不老是可取的:若是任何所需模塊不提供導入的包,Go 命令將添加新的依賴項,可能觸發常見依賴項的升級。即便輸入路徑拼寫錯誤,也會致使(失敗的)網絡查找。ide

在 golang 1.16 中,module-aware (模塊感知)命令在 go.mod 或 go.sum 中發現問題後報告錯誤,而不是嘗試自動解決問題。在大多數狀況下,錯誤消息中列出建議命令來解決問題,例如:

$ go build
example.go:3:8: no required module provides package golang.org/x/net/html; to add it:
    go get golang.org/x/net/html
$ go get golang.org/x/net/html
$ go build

golang 1.16 與 Go 以前版本同樣,若是 vendor 目錄存在,Go 命令可能會使用 vendor 目錄。 go getgo mod tidy 命令仍然修改 go.mod  go.sum,由於他們的主要目的是管理依賴關係。

04經過指定 @version 後綴安裝特定版本可執行文件

go install 命令如今能夠經過指定 @version 後綴安裝特定版本的可執行文件,例如:

go install golang.org/x/tools/gopls@v0.6.5

若是使用 @version 後綴,go install 命令使用該確切 Module 版本,忽略當前目錄和父目錄中的任何 go.mod 文件中的 Module 版本。

若是沒有 @version 後綴,go install 繼續運行,由於它一直有,創建程序使用當前模塊的 go.mod 文件中 requirements 列表和 replacements 列表列出的版本。

爲了消除使用哪一個版本的模糊性,在使用此安裝語法 go install program@latest 時,Go 程序的 go.mod 文件中可能存在幾個限制的指令。特別是,至少目前不容許 replace 和 exclude 指令。從長遠來看,一旦新的 go install program@version 在大多數使用狀況下工做的很好的前提下,Go 官方計劃在將來某個版本中讓 go get 命令中止安裝二進制文件。

05新增 retract 指令撤回 Module 版本

您是否在模塊版本準備好以前意外地發佈了該版本?或者,您是否在發佈須要快速修復的版本後發現了問題?已發佈版本中的錯誤很難更正。爲了保持模塊生成的肯定性,版本發佈後沒法修改。即便您刪除或更改了版本標籤,proxy.golang.org 和其餘代理可能已經有原始緩存。

模塊做者如今可使用 go.mod 中的 retract 指令 retract 模塊版本。retract 的版本仍然存在,能夠下載(所以依賴於它的構建不會中斷),但 go 命令在解決 @latest 等版本時不會自動選擇它。go get 和 go list -m -u 會打印有關現有用途的警告。

例如,假設一個流行的庫的做者 example.com/lib 發佈 v1.0.5,而後發現一個新的安全問題。他們能夠添加指令到他們的 go.mod 文件,例如:

// Remote-triggered crash in package foo. See CVE-2021-01234.
retract v1.0.5

接下來,做者能夠 tag 和 push 版本 v1.0.6,新的最高版本。在此以後,已依賴 v1.0.5 的用戶在檢查更新或升級依賴包時將收到撤回通知。通知消息可能包括收回指令上方註釋的文本。例如:

$ go list -m -u all
example.com/lib v1.0.0 (retracted)
$ go get .
go: warning: example.com/lib@v1.0.5: retracted by module author:
    Remote-triggered crash in package foo. See CVE-2021-01234.
go: to switch to the latest unretracted version, run:
    go get example.com/lib@latest

06使用新增配置變量 GOVCS 指定特定模塊使用特定版本控制工具

go 命令能夠從鏡像 proxy.golang.org 或直接從版本控制存儲庫下載模塊源代碼,使用 git、hg、svn、bzr 或 fossil。直接版本控制訪問很重要,尤爲是對於代理上不可用的私有模塊,但它也多是一個安全問題:版本控制工具中的錯誤可能被惡意服務器利用來運行惡意代碼。

Go 1.16 引入了一個新的配置變量 GOVCS,它容許用戶指定哪些模塊容許使用特定的版本控制工具。GOVCS 接受一個逗號分隔的模式列表:vcslist 規則。

模式是一條 path.Match。匹配模式匹配模塊路徑的一個或多個主要元素。公共和私有的特殊模式匹配公共和私有模塊(私有定義爲與 GOPRIVATE 中的模式匹配的模塊;公共是其餘一切模塊)。vcslist 是容許版本控制命令或關鍵字 all 或 off 的管道分隔列表。例如:

GOVCS=github.com:git,evil.com:off,*:git|hg

使用此設置,可使用 git 下載帶有 github.com 路徑的模塊;沒法使用任何版本控制命令下載 evil.com上的路徑,使用 git 或 hg 下載全部其餘路徑(* 匹配全部內容)的模塊。

若是未設置環境變量 GOVCS,或者若是模塊與任何模式不匹配,Go 命令將使用 GOVCS 的默認值:容許 git 和 hg 用於公共模塊,而且容許全部工具用於私有模塊。

設置只容許使用 Git 和 Mercurial 的理由是,這兩個版本控制工具最關注做爲不受信任服務器的客戶端運行的問題。相比之下,Bazaar、Fossil 和 Subversion 主要用於受信任的、通過驗證的環境中,並且沒有像 attack surfaces 那樣受到很好的審查。即默認設置爲:

GOVCS=public:git|hg,private:all

07Module 將來發展

咱們但願您發現這些功能頗有用。咱們已經開始開發 Go 1.17 的模塊功能,特別是懶惰的模塊加載,這應該使模塊加載過程更快,更穩定。

08總結

本文主要介紹了 Golang 1.16 針對 Module 作的一些變化。經過 Go 官方的這些 Module 變化,切實解決了 Go 用戶在使用 Go 時的實際問題。Go 官方也表示會在 Golang 1.17 計劃完全去除 GOPATH 模式,因此,若是您的項目目前尚未遷移到 Module 模式,是時候開始遷移了。

相關文章
相關標籤/搜索