本文轉載,目的方便查閱html
01介紹git
Golang 1.16 已經正式發佈了,其中 Modules 有一些變化:github
go.mod
和 go.sum
。@version
後綴安裝特定版本可執行文件。retract
指令撤回 Module 版本。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 get
和go 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 模式,是時候開始遷移了。