go mod更新指定的tag的包后,go vendor內(nèi)容未更新問題
背景
golang項目使用module進行依賴及版本管理,私有項目或二次開發(fā)的項目通過vendor進行管理。
在一次修改代碼,打完tag,修改項目go.mod中依賴私有倉庫的tag=v6.0.12后,使用 go mod tidy
更新依賴,go.sum中的對應倉庫的tag對應為v6.0.12;然后通過 go mod vendor
更新vendor下面的modules.txt及私有倉庫,發(fā)現(xiàn)modulest.txt中記錄的依賴倉庫的tag=v6.0.12已更新,但是倉庫的內(nèi)容卻不是最新的。
分析
- 可能本地mod有緩存
- 之前已經(jīng)存在該tag,被刪除后,新建了相同的tag,導致該tag的hash相同,命中緩存,進行
go mod tidy
后使用本地緩存中之前的tag的代碼,未進行更新。
解決
刪除本地配置的$GOPATH環(huán)境變量中pkg/mod及pkg/mod/cache/download路徑下對應的依賴倉庫及其tag版本,重新使用下面的命令更新。
$ go mod tidy go: downloading pkg.xx.com/service/lib/db/v6 v6.0.13 $ go mod vendor
如果通過上面清除緩存的方式,vendor依賴倉庫的內(nèi)容還沒有更新到最新的提交,可以在最新提交分支上重新創(chuàng)建一個新的tag,修改go.mod中依賴的tag為新創(chuàng)建的tag,再使用上面的 go mod tidy
和 go mod vendor
分別更新go mod和vendor依賴。
擴展
在go1.11之前的版本中,golang 主要依靠vendor和GOPATH來管理依賴庫,vendor相對主流,但現(xiàn)在官方更提倡go mod。
go get
go get之后下載文件的目錄位置:
1、GO111MODULE 如果為off,則在pkg目錄下;
2、GO111MODULE如果為on,則在src目錄下。
GOPATH
GOPATH模式下不方便使用同一個依賴包的多個版本。在GOMODULE模式下這個問題得到了很好的解決。
GOPATH模式下,依賴包存儲在 $GOPATH/src
,該目錄下只保存特定依賴包的一個版本。而在GOMODULE模式下,依賴包存儲在 $GOPATH/pkg/mod
,該目錄中可以存儲特定依賴包的多個版本。
需要注意的是$GOPATH/pkg/mod目錄下有個cache目錄,它用來存儲依賴包的緩存,簡單說,go命令每次下載新的依賴包都會在該cache目錄中保存一份。關(guān)于該目錄的工作機制我們留到GOPROXY章節(jié)時再詳細介紹。
接下來,我們使用開源項目github.com/google/uuid為例分別說明GOPATH模式和GOMODULE模式下特定依賴包存儲機制。在下面的操作中,我們會使用GO111MODULE環(huán)境變量控制具體的模式:
- export GO111MODULE=off切換到GOPATH模式
- export GO111MODULE=on切換到GOMODULE模式。
go module
自從go1.11版本后,golang引入go mod 機制來管理項目的依賴庫及其版本,其中 go.mod 簡要記錄了項目直接依賴庫的版本信息,
- go.sum詳細記錄了(項目直接或間接引用到的)各個依賴庫的版本及其對應hash。
- go mod用于解決之前沒有地方記錄依賴包具體版本的問題,方便依賴包的管理。
存放位置
一般第三方依賴庫(包括公司內(nèi)網(wǎng)gitlab上的依賴庫),其源碼都不被包含在項目內(nèi)部,而是在編譯的時候通過go連接公網(wǎng)或內(nèi)網(wǎng)下載到本地配置的環(huán)境變量$GOPATH中,然后編譯成對應的二進制文件,移植到各種系統(tǒng)中使用。
go module存儲下載的依賴包,具體位置在$GOPATH/pkg/mod。
GOPATH 在不同平臺上的安裝路徑不同,具體可以通過 go env
查看環(huán)境變量配置。
問題
有時候需在無公網(wǎng)、無內(nèi)網(wǎng)(無法連接內(nèi)網(wǎng)gitlab)的情況下編譯go項目,比如斷網(wǎng)的情況,那么需要如何做呢?
面對這種場景,可以通過 go get
或者 go mod vendor
將項目的依賴庫下載到項目內(nèi)部,作為項目的一部分來編譯。
除此之外,還有一些使用 go mod vendor
的場景或者優(yōu)勢:
- 雖然通常不會也不需要在無公網(wǎng)、無內(nèi)網(wǎng)環(huán)境實時編譯,因為go的可移植性很好,常以可執(zhí)行文件方式交付部署,但并不能排除此種可能。
- 防止依賴庫因為某種原因被刪除、移動,導致找不到依賴并編譯失敗。
- 對新手來說,下載一些墻外的依賴可能略有困難。
- 其他…總之,我們的目的是使用 go mod vendor,將項目的依賴庫下載到項目內(nèi)部,即項目中包含依賴庫源碼,依賴庫如同項目的一部分,也受到項目的版本管控(git、svn…)。
go vendor
通過 go mod tidy
下載并更新依賴倉庫的版本后,再執(zhí)行 go mod vendor
可以將下載的依賴包存放在vendor命令下并更新vendor/modules.txt文件,而vendor/modules.txt文件則自動記錄對應的依賴及其tag版本,不需要手動修改。
使用vendor的方式,相對于GOPATH或GOMODULE的方式,即使對應tag的依賴包被刪除或丟失,只要vendor目錄中存在就可以直接編譯使用。
# 在vendor目錄下創(chuàng)建依賴包副本 # 用vendor/modules.txt記錄依賴包及版本 go mod vendor # 指定構(gòu)建方式,Go 1.14之后,默認也是vendor模式構(gòu)建 go build -mod=vendor
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
golang控制結(jié)構(gòu)select機制及使用示例詳解
這篇文章主要介紹了golang控制結(jié)構(gòu)select機制及使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-10-10如何使用工具自動監(jiān)測SSL證書有效期并發(fā)送提醒郵件
本文介紹了如何開發(fā)一個工具,用于每日檢測SSL證書剩余有效天數(shù)并通過郵件發(fā)送提醒,工具基于命令行,通過SMTP協(xié)議發(fā)送郵件,需配置SMTP連接信息,本文還提供了配置文件樣例及代碼實現(xiàn),幫助用戶輕松部署和使用該工具2024-10-10win7下配置GO語言環(huán)境 + eclipse配置GO開發(fā)
這篇文章主要介紹了win7下配置GO語言環(huán)境 + eclipse配置GO開發(fā),需要的朋友可以參考下2014-10-10