Go Modules與GOPROXY 配置

golangd 配置go mod 在博文底部

摘抄自https://studygolang.com/articles/24544 go語言中文網 在原基礎博客整理增加知識點 讓你徹底名錶go mod
隨着Go 1.13發佈,GOPROXY默認值proxy.golang.org在中國大陸不能被訪問。

七牛雲順勢推出goproxy.cn,以利於中國開發者更好使用Go Modules,它是非盈利性的項目,首先感謝七牛雲。

Windows下使用教程:

(1)升級到Go1.13

(2)運行<go env -w GO111MODULE=on> //開啓mod

(3)運行<go env -w GOPROXY=https://goproxy.cn,direct> //設置七牛雲goproxy代理

可以通過運行go env查看(2)、(3)步驟是否設置成功

在這裏插入圖片描述
(4)在項目跟目錄下執行go mod init <OPTIONAL_MODULE_PATH>

執行成功後生成go.mod文件

其他指令

go get -u //更新現有的依賴
go mod tidy //整理模塊(拉取缺少的模塊,移除不用的模塊)
go mod download//下載依賴包
go mod graph //打印現有依賴結構
go mod vendor //將依賴複製到vendor下
go mod verify //校驗依賴
go.mod文件解析
module:模塊名稱,使用指令go mod init <OPTIONAL_MODULE_PATH>可設置
require:依賴包列表以及版本
exclude:禁用依賴包列表
replace:替換依賴包列表
go:go版本號

goland編輯器中配置go mod

在goland的setting裏設置啓用Go Modules
goland Preference->Go->Go Modules(vgo) -> Enable Go Modules(vgo)intergration

在這裏插入圖片描述

勾選 Enable Go Modules(vgo)intergration 之後 ,

proxy配置(參考上圖)
https://goproxy.cn
點擊apply (應用)ok 即可。

______________________________________________________________
______________________________________________________________


gomod 的相關知識 摘抄自go 夜讀 (author:盛傲飛)
在這裏插入圖片描述
go.mod

module sss

go 1.13

require (
	github.com/astaxie/beego v1.12.0
	github.com/go-sql-driver/mysql v1.4.1
	github.com/julienschmidt/httprouter v1.3.0
	github.com/micro/examples v0.2.0
	github.com/micro/go-micro v1.18.0
)

go.mod 是啓用了 Go moduels 的項目所必須的最重要的文件,它描述了當前項目(也就是當前模塊)的元信息,每一行都以一個動詞開頭,目前有以下 5 個動詞:

  • module:用於定義當前項目的模塊路徑。
  • go:用於設置預期的 Go 版本。
  • require:用於設置一個特定的模塊版本。
  • exclude:用於從使用中排除一個特定的模塊版本。
  • replace:用於將一個模塊版本替換爲另外一個模塊版本。

這裏的填寫格式基本爲包引用路徑+版本號,另外比較特殊的是 go $version,目前從 Go1.13 的代碼裏來看,還只是個標識作用,暫時未知未來是否有更大的作用。
go.sum
go.sum 是類似於比如 dep 的 Gopkg.lock 的一類文件,它詳細羅列了當前項目直接或間接依賴的所有模塊版本,並寫明瞭那些模塊版本的 SHA-256 哈希值以備 Go 在今後的操作中保證項目所依賴的那些模塊版本不會被篡改。

example.com/apple v0.1.2 h1:WX...
example.com/apple v0.1.2/go.mod h1:xHW...
example.com/banana v1.2.3/go.mod h1:HS... 
...
example.com/apple v0.1.2 h1:WXk...
example.com/apple v0.1.2/go.mod h1:xH...

前者爲 Go modules 打包整個模塊包文件 zip 後再進行 hash 值,而後者爲針對 go.mod 的 hash 值。他們兩者,要不就是同時存在,要不就是隻存在 go.mod hash。

那什麼情況下會不存在 zip hash 呢,就是當 Go 認爲肯定用不到某個模塊版本的時候就會省略它的 zip hash,就會出現不存在 zip hash,只存在 go.mod hash 的情況。

GO111MODULE
這個環境變量主要是 Go modules 的開關,主要有以下參數:

  • auto:只在項目包含了 go.mod 文件時啓用 Go modules,在 Go 1.13 中仍然是默認值,詳見 :golang.org/issue/31857。
  • on:無腦啓用 Go modules,推薦設置,未來版本中的默認值,讓 GOPATH 從此成爲歷史。
  • off:禁用 Go modules。

GOPROXY
這個環境變量主要是用於設置 Go 模塊代理,主要如下:

  • 它的值是一個以英文逗號 “,” 分割的 Go module proxy 列表(稍後講解)
  • 作用:用於使 Go 在後續拉取模塊版本時能夠脫離傳統的 VCS 方式從鏡像站點快速拉取。它擁有一個默認值,但很可惜 proxy.golang.org 在中國無法訪問,故而建議使用 goproxy.cn 作爲替代。
  • 設置爲 “off” :禁止 Go 在後續操作中使用任 何 Go module proxy。

剛剛在上面,我們可以發現值列表中有 “direct” ,它又有什麼作用呢?
其實值列表中的 “direct” 爲特殊指示符,用於指示 Go 回源到模塊版本的源地址去抓取 (比如 GitHub 等),當值列表中上一個 Go module proxy 返回 404 或 410 錯誤時,Go 自動嘗試列表中的下一個,遇見 “direct” 時回源,遇見 EOF 時終止並拋出類似 “invalid version: unknown revision…” 的錯誤。

GOSUMDB
它的值是一個 Go checksum database,用於使 Go 在拉取模塊版本時(無論是從源站拉取還是通過 Go module proxy 拉取)保證拉取到的模塊版本數據未經篡改,也可以是“off”即禁止 Go 在後續操作中校驗模塊版本

  • 格式: SUMDB_NAME+PUBLIC_KEY或SUMDB_NAME+PUBLIC_KEY SUMDB_URL。
  • 擁有默認值: sum.golang.org (之所以沒有按照上面的格式是因爲 Go 對默認值做了特殊處理)。
  • 可被 Go module proxy 代理 (詳見:Proxying a Checksum Database)。
  • GOSUMDB 的默認值在中國無法訪問,故而更加建議將 GOPROXY 設置爲 goproxy.cn,因爲 goproxy.cn 支持代理 sum.golang.org。

Go Checksum Database
Go checksum database 主要用於保護 Go 不會從任何源頭拉到被篡改過的非法 Go 模塊版本,其作用(左)和工作機制(右)如下圖:
在這裏插入圖片描述
如果有興趣的小夥伴可以看看 Proposal: Secure the Public Go Module Ecosystem,有詳細介紹其算法機制,如果想簡單一點,查看 go helpmodule-auth 也是一個不錯的選擇。

GONOPROXY/GONOSUMDB/GOPRIVATE
這三個環境變量都是用在當前項目依賴了私有模塊,也就是依賴了由 GOPROXY 指定的 Go module proxy 或由 GOSUMDB 指定 Go checksum database 無法訪問到的模塊時的場景,他們具有如下特性:

  • 它們三個的值都是一個以英文逗號 “,” 分割的模塊路徑前綴,匹配規則同 path.Match。

  • 其中 GOPRIVATE 較爲特殊,它的值將作爲 GONOPROXY 和 GONOSUMDB 的默認值,所以建議的最佳姿勢是隻是用 GOPRIVATE。

在使用上來講,比如 GOPRIVATE=*.corp.example.com 表示所有模塊路徑以 corp.example.com 的下一級域名 (如 team1.corp.example.com) 爲前綴的模塊版本都將不經過 Go module proxy 和 Go checksum database,需要注意的是不包括 corp.example.com 本身。
Global Caching
這個主要是針對 Go modules 的全局緩存數據說明,如下:

  • 同一個模塊版本的數據只緩存一份,所有其他模塊共享使用。
  • 目前所有模塊版本數據均緩存在 $GOPATH/pkg/mod和 $GOPATH/pkg/sum 下,未來或將移至 $GOCACHE/mod和 $GOCACHE/sum 下( 可能會在當 $GOPATH 被淘汰後)。
  • 可以使用 go clean-modcache 清理所有已緩存的模塊版本數據。

另外在 Go1.11 之後 GOCACHE 已經不允許設置爲 off 了,我想着這也是爲了模塊數據緩存移動位置做準備,因此大家應該儘快做好適配。

++++++++++++++++++++++++=+++++++++++++++++=++++++++++++++++++++++++=+++++++++++++++++=++++++++++++++++++++++++=+++++++++++++++++=++++++++++++++++++++++++=+++++++++++++++++=++++++++++++++++++++++++=+++++++++++++++++=++++++++++++++++++++++++=+++++++++++++++++=++++++++++++++++++++++++=+++++++++++++++++=++++++++++++++++++++++++=+++++++++++++++++=++++++++++++++++++++++++=+++++++++++++++++=++++++++++++++++++++++++=+++++++++++++++++=

快速遷移項目至 Go Modules

在這裏插入圖片描述

  • 升級到 Go 1.13。

  • 讓 GOPATH 從你的腦海中完全消失,早一步踏入未來。

    • 修改 GOBIN 路徑(可選)。
    • 打開 Go modules 的開關。
    • 設置 GOPROXY。
  • 按照你喜歡的目錄結構重新組織你的所有項目。

  • 在你項目的根目錄下執行 go mod init<OPTIONAL_MODULE_PATH> 以生成 go.mod 文件。

  • 想辦法說服你身邊所有的人都去走一下前四步。

遷移後 go get 行爲的改變

這裏我們注意到有兩點比較特別,分別是:
在這裏插入圖片描述

  • 第一點:爲什麼 “拉取 hash 爲 342b231 的 commit,最終會被轉換爲 v0.3.2” 呢。這是因爲雖然我們設置了拉取 @342b2e commit,但是因爲 Go modules 會與 tag 進行對比,若發現對應的 commit 與 tag 有關聯,則進行轉換。
  • 第二點:爲什麼不建議使用 go mod vendor,因爲 Go modules 正在淡化 Vendor 的概念,很有可能 Go2 就去掉了。

使用 Go Modules 時常遇見的坑

坑 1: 判斷項目是否啓用了 Go Modules

在這裏插入圖片描述

坑 2: 管理 Go 的環境變量

在這裏插入圖片描述
這裏主要是提到 Go1.13 新增了 go env-w 用於寫入環境變量,而寫入的地方是 os.UserConfigDir 所返回的路徑,需要注意的是 go env-w 不會覆寫。

坑 3: 從 dep、glide 等遷移至 Go Modules

在這裏插入圖片描述
這裏主要是指從舊有的依賴包管理工具(dep/glide 等)進行遷移時,因爲 BUG 的原因會導致不經過 GOPROXY 的代理,解決方法有如下兩個:

  • 手動創建一個 go.mod 文件,再執行 go mod tidy 進行補充。
  • 上代理,相當於不使用 GOPROXY 了。

坑 4:拉取私有模塊

在這裏插入圖片描述
這裏主要想涉及兩塊知識點,如下:

  • GOPROXY 是無權訪問到任何人的私有模塊的,所以你放心,安全性沒問題。
  • GOPROXY 除了設置模塊代理的地址以外,還需要增加 “direct” 特殊標識才可以成功拉取私有庫。

坑 5:更新現有的模塊

在這裏插入圖片描述

坑 6:主版本號

在這裏插入圖片描述

Q:使用 Go modules 時可以同時依賴同一個模塊的不同的兩個或者多個小版本(修訂版本號不同)嗎?

A:不可以的,Go modules 只可以同時依賴一個模塊的不同的兩個或者多個大版本(主版本號不同)。比如可以同時依賴 example.com/[email protected] 和 example.com/foobar/[email protected],因爲他們的模塊路徑(module path)不同,Go modules 規定主版本號不是 v0 或者 v1 時,那麼主版本號必須顯式地出現在模塊路徑的尾部。但是,同時依賴兩個或者多個小版本是不支持的。比如如果模塊 A 同時直接依賴了模塊 B 和模塊 C,且模塊 A 直接依賴的是模塊 C 的 v1.0.0 版本,然後模塊 B 直接依賴的是模塊 C 的 v1.0.1 版本,那麼最終 Go modules 會爲模塊 A 選用模塊 C 的 v1.0.1 版本而不是模塊 A 的 go.mod 文件中指明的 v1.0.0 版本。

這是因爲 Go modules 認爲只要主版本號不變,那麼剩下的都可以直接升級採用最新的。但是如果採用了最新的結果導致項目 Break 掉了,那麼 Go modules 就會 Fallback 到上一個老的版本,比如在前面的例子中就會 Fallback 到 v1.0.0 版本。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章