忘掉GOPATH,迎接Go modules,進入Go專案依賴庫版本管理新時代
Go SDK 1。13測試版已經發布了。從此版本開始,Go modules依賴庫版本管理特性將正式開始推薦使用。本文將解釋一些和Go modules相關的一些命令和概念。
Module(模組)定義為一些Go程式碼包的集合。通常體現為一個含有若干程式碼包的目錄。每個模組可以釋出一系列版本。版本號使用semver(語義化版本
https://
semver。org/lang/zh-CN/
)表示。一個模組可能依賴於其它若干模組;準確說來,是依賴於其它若干模組的各自的某個具體版本。每個模組可以在自己的根目錄下的
go。mod
檔案中指定其所依賴的各個模組的具體版本。
如果你所維護的某個模組尚未使用Go modules管理依賴,你可以開啟一個命令列終端,進入此模組根目錄,執行下面這條命令將此模組轉換為一個使用Go modules管理依賴的模組。
go mod init host。prefex/mypkg
其中,
host。prefex/mypkg
為其它包引入此模組中的包時的引入路徑的字首。常常地,
host。prefex
為
github。com
等原始碼託管網站;
mypkg
常為
user/project
這種形式。當然,你也可以將你自己的域名
my。website
用做引入路徑的字首(
host。prefex
)。但是這時如果不能從引入路徑
my。website/mypkg
中判斷出此程式碼包使用何種原始碼版本管理工具(比如git/hg/svn等),則
my。website
網站必須響應
https://my。website/mypkg?go-get=1
HTTPS請求(HTTP也可以但不推薦),並在在HTML的返回體中的
部分包含一個
標籤來指名具體到哪裡下載此模組。(本博將另開一篇文章詳解自定義域名引入路徑。)
當
go。mod
檔案已經創建出來之後,我們可以在此檔案中手動指定此模組所要依賴的其它模組和這些以來模組的版本號(版本號必須制定但可以使用偽版本號,比如
、 >=v1。5。6 、 latest 和分支名 master 等)。我們也可以執行 go build 和 go test 等命令來自動發現並且在 go。mod 檔案中加入依賴模組和它們的具體版本。手動指定的偽模組版本號將被 go build 等命令更改為確切的版本號。其中 latest 偽版本號將被解讀為最新正式釋出版本,正式釋出版本是標號為形如 vX。Y。Z 的語義化版本(semver,`X`/`Y`/`Z`均為整數數字)。 分支名偽版本號將被解讀為指定分支的最新提交。 而 將被解讀為 v1。12 系列版中最大的小於 v1。12。3 的版本。 當使用原始碼版本管理工具時,一個tag的名稱將被視為一個版本號。形如 v1。2。3-pre1 的預釋出版本不屬於正式版本。(關於模組的版本匹配規則,本博將另發一篇文章詳述。) go build 等命令將下載並快取尚未快取的依賴模組的版本程式碼。 在一個模組目錄下執行 go get a。b。c/x/y@v1。2。3 將在此模組的 go。mod 檔案中加入一個依賴。 預設情況下, go build 等命令將訪問sumdb(Checksum Database,預設值為 https:// sum。golang。org/ )驗證下載的各個直接或者間接依賴模組的雜湊值是否和sumdb中記錄的雜湊值相匹配。如果不匹配,很可能某些環節出了問題(比如下載的模組程式碼被人惡意更改了)。 一般說來, go。mod 檔案中只記錄當前模組的直接依賴。每個依賴體現為一條 require 或者 replace 指令。比如 module my。website/cmd/myprogram require github。com/boltdb/bolt v1。3。0 replace my。website/mypkg github。com/myname/myproject v1。0。0 其中的 replace 指令表示,當遇到引入路徑字首為 my。website/mypkg 的程式碼包時,真實的下載的程式碼包為處於路徑 github。com/myname/myproject 的v1。0。0版本的模組下的相應程式碼包。 如果你的一箇舊專案是使用其它流行第三方工具(比如deps和glide等)來管理包依賴的,則在此專案下執行 go mod init host。prefex/mypkg 命令將自動將此專案轉換為一個使用 go modules 管理依賴的專案。 如果你的一個新專案需要依賴於一個當前正使用其它流行第三方工具來管理包依賴的庫,則請到此庫的根目錄下執行以下 go mod init a。b/c 命令(引入路徑可任意),然後將生成的 go。mod 中的所有 require 指令複製到你的新專案下的 go。mod 檔案中。(至少對於目前的Go SDK 1。12是如此,以後的Go SDK版本可能會對此過程進行改進。) 一些其它的和modules相關的常用命令和命令選項: * go list -m all 列出所有的(包括直接的和間接的)將在go build中使用的各個模組和它們的具體版本號。 go list -u -m all 列出所有的(包括直接和間接)使用的各個模組目前可用的小更新或者補丁版本號。undefined go get -u or go get -u=patch 將目前所有的(直接和間接)依賴的模組的版本號更新到最新可用的小更新或者補丁版本號。 go mod tidy 從go。mod 中刪除目前已經不再使用的依賴模組,加入其它作業系統和架構所需的依賴。在以後的SDK版本中,此命令可能會在執行其它 go 命令時自動執行。 go mod vendor 將所有依賴放入當前模組下的vendor子目錄中。 go build -mod vendor 使用當前模組下的vendor子目錄中的依賴程式碼(而不是快取中依賴模組程式碼)來編譯構建。 更多關於Go語言的細節、技巧和常識,請訪問《Go語言101》專案或者《Go語言101》官網,或者關注本專欄公眾號(Go 101):