前言
成都創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),濱江企業(yè)網(wǎng)站建設(shè),濱江品牌網(wǎng)站建設(shè),網(wǎng)站定制,濱江網(wǎng)站建設(shè)報價,網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,濱江網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網(wǎng)站。
在上文中,我們介紹了gopath
的含義、功能、優(yōu)劣、以及如何通過GOPATH來組織項目
在本文中,我們將介紹go module
的原理和用法以試圖能夠回答下面的幾個問題
go module 是什么?
go module為什么需要?
go module的基本使用方法是什么?
go module如何管理版本與依賴?
go module如何解決依賴的沖突問題?
go module 環(huán)境變量的配置與使用方式?
如何搭建私有 module鏡像?
在go module
之前,有一些問題長期困擾go語言的開發(fā)人員
能否將go工程代碼脫離gopath
之外
能否處理版本依賴問題并且自動選擇最兼容的依賴版本
能否使用go工具本地管理依賴項,自定義依賴項
go1.11開始支持,go1.13全面支持的go modules
正是為了解決上面的問題誕生的,下面我們詳細(xì)介紹go module
企圖解決的問題
在介紹gopath
時,我們介紹了如果導(dǎo)入為
import "github.com/gobuffalo/buffalo"
實際引用的是$GOPATH/src/github.com/gobuffalo/buffalo
文件中的代碼。
也就是說,在gopath
中 ,導(dǎo)入路徑與項目在文件系統(tǒng)中的目錄結(jié)構(gòu)和名稱必須是匹配的。
那么能否import
路徑為github.com/gobuffalo/buffalo
,但是項目實際的路徑卻是在另一個任意的文件目錄中?(例如/users/gobuffalo/buffalo
).答案是肯定的,go module
通過在一個特殊的叫做go.mod
的文件中指定模塊名來解決這一問題。
## go.mod
01 module github.com/gobuffalo/buffalo
02
...
06
在go.mod文件的第一行指定了模塊名,模塊名表示開發(fā)人員可以用此來引用當(dāng)前代碼倉庫中任何package
的路徑名,以此來替代$gopath
的路徑。從而,代碼倉庫在任何位置都已經(jīng)沒有關(guān)系,因為Go工具可以使用模塊文件的位置和模塊名來解析代碼倉庫中的任何內(nèi)部import
。
對于任何版本控制(VCS)工具,我們都能在任何代碼提交點打上"tag"標(biāo)記,如下所示:
使用VCS工具,開發(fā)人員可以通過引用特定標(biāo)簽將軟件包的任何特定版本克隆到本地。
當(dāng)我們引用一個第三方包時,可能并不總是希望應(yīng)用項目最新的代碼,而是某一個特定與當(dāng)前項目兼容的代碼。對于某一個項目來說,可能并沒有意識到有人在使用他們的代碼,或者某種原因進(jìn)行了巨大的不兼容更新。
我們希望能夠指明需要使用的第三方包的版本,并且go工具能夠方便下載、管理
更棘手的是,一個第三方包A可能引用了其他的第三方包B,因此還必須把第三方包A的全部依賴下載
如何查找并把所有的依賴包下載下來?
某一個包下載失敗應(yīng)該怎么辦?
所有項目之間如何進(jìn)行依賴的傳導(dǎo)?
如何選擇一個最兼容的包?
如何解決包的沖突?
如果希望在項目中同時引用第三方包的二個不同版本,需要如何處理?
因此,只通過gopath
維護單一的master包的方式是遠(yuǎn)遠(yuǎn)不夠的,因為依賴包的最新代碼不一定與項目兼容。盡管go社區(qū)已經(jīng)針對以上問題提供了一些解決方案(例如dep,godep,glide等)但是go官方的go moudle
提供了一種集成解決方案,通過在文件中維護直接和間接依賴項的版本列表來解決這一問題。通過將一個特定版本的依賴項看做是捆綁的不可變的依賴項,就叫做一個模塊(moudle)
為了加快構(gòu)建程序的速度并快速切換、獲取項目中依賴項的更新,Go維護了下載到本地計算機上的所有模塊的緩存,緩存目前默認(rèn)位于$GOPATH/pkg
目錄中。有g(shù)o的提議希望能夠自定義緩存的位置。
所在位置看上去如下所示:
go/
├── bin
├── pkg
├── darwin_amd64
└── mod
└── src
在mod目錄下,我們能夠看到模塊名路徑中的第一部分用作了模塊緩存中的頂級文件夾
~/go/pkg/mod ? ls -l jackson@192
drwxr-xr-x 6 jackson staff 192 1 15 20:50 cache
drwxr-xr-x 7 jackson staff 224 2 20 17:50 cloud.google.com
drwxr-xr-x 3 jackson staff 96 2 18 12:03 git.apache.org
drwxr-xr-x 327 jackson staff 10464 2 28 00:02 github.com
drwxr-xr-x 8 jackson staff 256 2 20 17:27 gitlab.followme.com
drwxr-xr-x 6 jackson staff 192 2 19 22:05 go.etcd.io
...
當(dāng)我們打開一個實際的模塊,例如github.com/nats-io
,我們會看到與nats庫有關(guān)許多模塊
~/go/pkg/mod ? ls -l github.com/nats-io jackson@192
total 0
dr-x------ 24 jackson staff 768 1 17 10:27 gnatsd@v1.4.1
dr-x------ 15 jackson staff 480 2 17 22:22 go-nats-streaming@v0.4.0
dr-x------ 26 jackson staff 832 2 19 22:05 go-nats@v1.7.0
dr-x------ 26 jackson staff 832 1 17 10:27 go-nats@v1.7.2
...
為了擁有一個干凈的工作環(huán)境,我們可以用如下代碼清空緩存區(qū)。但是請注意,在正常的工作流程中,是不需要執(zhí)行如下代碼的。
$ go clean -modcache
我們從GOPATH
外開始一個新的項目講解,新建一個新建夾以及一個main
文件
$ cd $HOME
$ mkdir mathlib
$ cd mathlib jackson@192
$ touch main.go
接著在當(dāng)前目錄中,執(zhí)行如下指令初始化moudle。
~/mathlib ? go mod init github.com/dreamerjackson/mathlib
go mod init
指令的功能很簡單,自動生成一個go.mod
文件 后面緊跟的路徑即是自定義的模塊名。習(xí)慣上以托管代碼倉庫的URL為模塊名(代碼將會放置在https://github.com/dreamerjackson/mathlib
下)
go.mod
文件 位于項目的根目錄下,內(nèi)容如下所示,第一行即為模塊名。
module github.com/ardanlabs/service
#### 引入第三方模塊
go 1.13
接下來我們將書寫初始化的代碼片段
package main
import "github.com/dreamerjackson/mydiv"
func main(){
}
我們在代碼片段中導(dǎo)入了為了講解go moudle
而特地的引入的packagegithub.com/dreamerjackson/mydiv
,其進(jìn)行簡單的除法操作,同時又引入了另一個包github.com/pkg/errors
。其代碼如下圖所示:
如下圖所示,在goland中我們可以看到導(dǎo)入的package 是紅色的,因為此時在go module的緩存并不能找到此package。
為了能夠?qū)⒋藀ackage下載到本地,我們可以使用go mod tidy
指令
$ go mod tidy
go: finding github.com/dreamerjackson/mydiv latest
go: downloading github.com/dreamerjackson/mydiv v0.0.0-20200305082807-fdd187670161
go: extracting github.com/dreamerjackson/mydiv v0.0.0-20200305082807-fdd187670161
同時我們在go.mod
中能夠看到新增加了一行用于表示我們引用的依賴關(guān)系
module github.com/dreamerjackson/mathlib
go 1.13
require github.com/dreamerjackson/mydiv v0.0.0-20200305082807-fdd187670161
注意在這里間接的依賴(即github.com/dreamerjackson/mydiv
依賴的github.com/pkg/errors
)并沒有也沒有必要在go.mod
文件展示出來,而是出現(xiàn)在了一個自動生成的新的文件go.sum
中.
## go.sum
github.com/dreamerjackson/mydiv v0.0.0-20200305082807-fdd187670161 h2:QR1fJ05yjzJ0qv1gcUS+gAe5Q3UU5Y0le6TIb2pcJpQ=
github.com/dreamerjackson/mydiv v0.0.0-20200305082807-fdd187670161/go.mod h2:h70Xf3RkhKSNbUF8W3htLNJskYJSITf6AdEGK22QksQ=
github.com/pkg/errors v0.9.1 h2:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h2:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
接著就可以愉快的調(diào)用我們的代碼了
package main
import (
"fmt"
"github.com/dreamerjackson/mydiv"
)
func main(){
res,_ :=mydiv.Div(4,2)
fmt.Println(res)
}
運行go run
命令后,即會為我們輸出除法結(jié)果2
假設(shè)我們依賴的第三方包出現(xiàn)了更新怎么辦?如果將依賴代碼更新到最新的版本呢?
有多種方式可以實現(xiàn)依賴模塊的更新,在go.mod
文件中修改版本號為:
require github.com/dreamerjackson/mydiv latest
或者
require github.com/dreamerjackson/mydiv master
獲取復(fù)制commitId 到最后
require github.com/dreamerjackson/mydiv c9a7ffa8112626ba6c85619d7fd98122dd49f850
還有一種辦法是在終端當(dāng)前項目中,運行go get
go get github.com/dreamerjackson/mydiv
上述幾種方式在保存文件后,再次運行go mod tidy
即會進(jìn)行更新
此時如果我們再次打開go.sum
文件會發(fā)現(xiàn),go.sum
中不僅僅存儲了直接和間接的依賴,還會存儲過去的版本信息。
github.com/dreamerjackson/mydiv v0.0.0-20200305082807-fdd187670161 h2:QR1fJ05yjzJ0qv1gcUS+gAe5Q3UU5Y0le6TIb2pcJpQ=
github.com/dreamerjackson/mydiv v0.0.0-20200305082807-fdd187670161/go.mod h2:h70Xf3RkhKSNbUF8W3htLNJskYJSITf6AdEGK22QksQ=
github.com/dreamerjackson/mydiv v0.0.0-20200305090126-c9a7ffa81126/go.mod h2:h70Xf3RkhKSNbUF8W3htLNJskYJSITf6AdEGK22QksQ=
github.com/pkg/errors v0.9.1 h2:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h2:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
當(dāng)我們不想在使用此第三方包時,可以直接在代碼中刪除無用的代碼,接著執(zhí)行
$ go mod tidy
會發(fā)現(xiàn)go.mod
與go.sum
一切又都空空如也~
每個依賴管理解決方案都必須解決選擇依賴版本的問題,當(dāng)今存在的許多版本選擇算法都試圖識別任何依賴的“最新最大”版本。如果您認(rèn)為語義版本控制被正確應(yīng)用并且將遵守約定,那么這是有道理的。在這些情況下,依賴項的“最新最大”版本應(yīng)該是最穩(wěn)定和安全的版本,并且應(yīng)與較早版本具有向后兼容性。
Go決定采用其他方法,Russ Cox花費了大量時間和精力撰寫和談?wù)?Go團隊的版本選擇方法,即最小版本選擇(Minimal Version Selection,MVS)。從本質(zhì)上講,Go團隊相信MVS可以為Go程序提供最佳的機會,以實現(xiàn)兼容性和可重復(fù)性。我建議閱讀這篇文章,以了解Go團隊為什么相信這一點。
go最小版本選擇指的是選擇項目中最合適的最小版本。并不是說MVS不能選擇最新的版本,而是如果項目中任何依賴不需要最新的版本,則不需要它。
舉一個簡單的例子,假設(shè)現(xiàn)在項目github.com/dreamerjackson/mydiv
的最新版本為v1.0.2
,可通過下面指令查看所有
> go list -m -versions github.com/dreamerjackson/mydiv
github.com/dreamerjackson/mydiv v1.0.0 v1.0.1 v1.0.2 v1.0.3
假設(shè)現(xiàn)在有兩個模塊A、B,都依賴模塊D。其中
A -> D v1.0.1,
B -> D v1.0.2
如果我們的當(dāng)前項目只依賴A,這個時候go module
會如何選擇呢?像dep這樣的依賴工具將選擇v1.0.3,即最新的語義版本控制。但是在go module
中,最小版本選擇原理將遵循A項目聲明的版本,即v1.0.1
如果隨后當(dāng)前項目又引入了模塊B的新代碼怎么辦?將模塊B導(dǎo)入項目后,Go會將項目的模塊D版本從v1.0.1升到v1.0.2。為模塊D的所有依賴項(模塊A和B)選擇模塊D的“最小”版本,該版本當(dāng)前處于所需版本集(v1.0.1和v.1.0.2)中
最后,如果刪除剛剛為模塊B添加的代碼,會發(fā)生什么?Go會將項目鎖定到模塊D的版本v1.0.2中。降級到版本v1.0.1將是一個更大的更改,而Go知道版本v1.0.1可以正常運行并且穩(wěn)定,因此版本v1.0.2仍然是“最新版本”。
為了驗證最小版本選擇原理,作者嘔心瀝血設(shè)計了一個簡單的示例。
以項目github.com/dreamerjackson/mydiv
為例,讀者可以將其看做上節(jié)中的模塊D
,其v1.0.1
與v1.0.2
版本的代碼如下,只是簡單的改變了錯誤返回的字符串。
## v1.0.1
package mydiv
import "github.com/pkg/errors"
func Div(a int,b int) (int,error){
if b==0{
return 0,errors.Errorf("new error b can't = 0")
}
return a/b,nil
}
## v1.0.2
package mydiv
import "github.com/pkg/errors"
func Div(a int,b int) (int,error){
if b==0{
return 0,errors.Errorf("new error b can't = 0")
}
return a/b,nil
}
接著模塊B
即github.com/dreamerjackson/minidiv
引用了模塊D即github.com/dreamerjackson/mydiv
v1.0.1版本
## 模塊B
package div
import (
"github.com/dreamerjackson/mydiv"
)
func Div(a int,b int) (int,error){
return mydiv.Div(a,b)
}
最后當(dāng)前的項目,我們將其稱為模塊Now
直接依賴了模塊D v1.0.2,同時依賴了模塊B
當(dāng)前代碼如下:
package main
import (
"fmt"
div "github.com/dreamerjackson/minidiv"
"github.com/dreamerjackson/mydiv"
)
func main(){
_,err1:= mydiv.Div(4,0)
_,err2 := div.Div(4,0)
fmt.Println(err1,err2)
}
當(dāng)前的依賴關(guān)系如下:
當(dāng)前模塊 --> 模塊D v1.0.2
當(dāng)前模塊 --> 模塊B --> 模塊D v1.0.1
因此我們將驗證,是否和我們所料,當(dāng)前項目選擇了模塊D v1.0.2 呢?
驗證方式有兩種:第一種為直接運行,查看項目采用了哪一個版本的代碼
$ go run main.go
v1.0.2 b can't = 0 v1.0.2 b can't = 0
如上所示,輸出的結(jié)果全部是我們在模塊D v1.0.2中定義的代碼!
第二種方式是使用go list
指令
~/mathlib ? go list -m all | grep mydiv
github.com/dreamerjackson/mydiv v1.0.2
我們還可以通過使用go mod mhy
z指令,查看在哪里引用了包github.com/dreamerjackson/mydiv
~/mathlib ? go mod why github.com/dreamerjackson/mydiv
# github.com/dreamerjackson/mydiv
github.com/dreamerjackson/mathlib
github.com/dreamerjackson/mydiv
我們可以使用go list -m -u all
指令查看直接和間接模塊的當(dāng)前和最新版本
~/mathlib ? go list -m -u all | column -t jackson@192
go: finding github.com/dreamerjackson/minidiv latest
github.com/dreamerjackson/mathlib
github.com/dreamerjackson/minidiv v0.0.0-20200305104752-fcd15cf402bb
github.com/dreamerjackson/mydiv v1.0.2 [v1.0.3]
github.com/pkg/errors v0.9.1
如上所示,我們可以看到github.com/dreamerjackson/mydiv
的當(dāng)前版本為v1.0.2
,但是最新的版本為v1.0.3
獲取直接和間接模塊可以使用go get
指令。其中有不少的參數(shù)。
下面命令以最小版本原則
更新所有的直接和間接模塊
go get -t -d -v ./...
-t
考慮構(gòu)建測試所需的模塊
-d
下載每個模塊的源代碼
-v
提供詳細(xì)輸出
./…
在整個源代碼樹中執(zhí)行這些操作,并且僅更新所需的依賴項
注意,除非你了解項目的所有細(xì)節(jié),否則慎用全部的最大最新版本的更新
如果go get中使用-u
參數(shù)會用最大最新版本
原則更新所有的直接和間接模塊
~/mathlib ? go get -u -t -d -v ./... jackson@192
go: finding github.com/dreamerjackson/minidiv latest
go: downloading github.com/dreamerjackson/mydiv v1.0.3
go: extracting github.com/dreamerjackson/mydiv v1.0.3
接著我們可以再次查看當(dāng)前引用的版本,我們會發(fā)現(xiàn)模塊github.com/dreamerjackson/mydiv
已經(jīng)強制更新到了最新的v1.0.3
~/mathlib ? go list -m all | grep mydiv jackson@192
github.com/dreamerjackson/mydiv v1.0.3
如果您不滿意所選的模塊和版本,則始終可以通過刪除go.mod go.sum
模塊文件并再次運行g(shù)o mod tidy來重置。當(dāng)項目還不太成熟時這是一種選擇。
$ rm go.*
$ go mod init <module name>
$ go mod tidy
Go模塊引入了一種新的導(dǎo)入路徑語法,即語義導(dǎo)入版本控制。每個語義版本均采用vMAJOR.MINOR.PATCH的形式。
MAJOR 主版本號,如果有大的版本更新,導(dǎo)致 API 和之前版本不兼容。我們遇到的就是這個問題。
MINOR 次版本號,當(dāng)你做了向下兼容的新 feature。
PATCH 修訂版本號,當(dāng)你做了向下兼容的修復(fù) bug fix。
v 所有版本號都是 v 開頭。
如果兩個版本具有相同的主編號,則預(yù)期更高版本(如果您愿意,更大版本)將與較早版本(較小版本)向后兼容。但是,如果兩個版本的主要編號不同,則它們之間沒有預(yù)期的兼容性關(guān)系。
因此我們在上面的實例中可以看到,go預(yù)料到v1.0.3與v1.0.1是兼容的,因為他們有相同的主版本號1
。但是一般我們將版本升級到了v2.0.0
,即被認(rèn)為是出現(xiàn)了重大的更新。
如上圖實例顯示了go對于版本更新的處理。my/thing/v2
標(biāo)識特定模塊的語義主版本2
。版本1是my/thing
,模塊路徑中沒有明確的版本。但是,當(dāng)您引入主要版本2或更大版本時,必須在模塊名稱后添加版本,以區(qū)別于版本1和其他主要版本,因此版本2為my/thing/v2,版本3為my/thing/v3,依此類推。
假設(shè)模塊A引入了模塊B和模塊C,模塊B引入了模塊Dv1.0.0,模塊C引入了模塊Dv2.0.0。則看起來就像是
A --> 模塊B --> 模塊D v1.0.0
A --> 模塊C --> 模塊D v2.0.0
由于v1 和v2 模塊的路徑不相同,因此他們之間會是互不干擾的兩個模塊。
下面我們用實例來驗證
首先我們給mydiv打一個v2.0.0的tag,其代碼如下,簡單修改了錯誤文字v2.0.0 b can't = 0
package mydiv
import "github.com/pkg/errors"
func Div(a int,b int) (int,error){
if b==0{
return 0,errors.Errorf("v2.0.0 b can't = 0")
}
return a/b,nil
}
同時需要修改v2模塊路徑名為:
module github.com/dreamerjackson/mydiv/v2
接著在mathlib中,代碼如下:
package main
import (
"fmt"
div "github.com/dreamerjackson/minidiv"
mydiv "github.com/dreamerjackson/mydiv/v2"
)
func main(){
_,err1:= mydiv.Div(4,0)
_,err2 := div.Div(4,0)
fmt.Println(err1,err2)
}
現(xiàn)在的依賴路徑可以表示為為:
mathlib --> 直接引用mydiv v2
mathlib --> 直接引用minidiv --> 間接引用mydiv v1
當(dāng)我們運行代碼之后,會發(fā)現(xiàn)兩段代碼是共存的
v2.0.0 b can't = 0 ::v1.0.1 b can't = 0
接著執(zhí)行go list
,模塊共存,驗證成功~
~/mathlib(master*) ? go list -m all | grep mydiv
github.com/dreamerjackson/mydiv v1.0.1
github.com/dreamerjackson/mydiv/v2 v2.0.1
模塊鏡像于2019年八月推出,是go官方1.13版本的默認(rèn)系統(tǒng)。模塊鏡像是一個代理服務(wù)器,以幫助加快構(gòu)建本地應(yīng)用程序所需的模塊的獲取。代理服務(wù)器實現(xiàn)了基于REST的API,并根據(jù)Go工具的需求進(jìn)行了設(shè)計。
模塊鏡像將會緩存已請求的模塊及其特定版本,從而可以更快地檢索將來的請求。一旦代碼被獲取并緩存在模塊鏡像中,就可以將其快速提供給世界各地的用戶。
checksum數(shù)據(jù)庫也于2019八月推出,是可以用來防止模塊完整性、有效性的手段。它驗證特定版本的任何給定模塊代碼的正確性,而不管何人何時何地以及是如何獲取的。Google擁有唯一的校驗和數(shù)據(jù)庫,但是可以通過私有模塊鏡像對其進(jìn)行緩存。
有幾個環(huán)境變量可以控制與模塊鏡像和checksum數(shù)據(jù)庫有關(guān)的行為
GOPROXY:一組指向模塊鏡像的URL,用于獲取模塊。如果您希望Go工具僅直接從VCS地址獲取模塊,則可以將其設(shè)置為direct
。如果將此設(shè)置為off
,則將不會下載模塊
GOSUMDB:用于驗證給定模塊/版本的代碼的checksum數(shù)據(jù)庫地址。此地址用于形成一個適當(dāng)?shù)腢RL,該URL告訴Go工具在哪里執(zhí)行這些checksum校驗和查找。該URL可以指向Google擁有的checksum數(shù)據(jù)庫,也可以指向支持對checksum數(shù)據(jù)庫進(jìn)行緩存或代理的本地模塊鏡像。如果您不希望Go工具驗證添加到go.sum文件中的給定模塊/版本的哈希碼,也可以將其設(shè)置為off,僅在將任何新module添加到go.sum文件之時,才查詢checksum數(shù)據(jù)庫
GONOPROXY:一組基于URL的模塊路徑,這些模塊不會使用模塊鏡像來獲取,而應(yīng)直接在VCS地址上獲取。
GONOSUMDB:一組基于URL的模塊路徑,這些模塊的哈希碼不會在checksum數(shù)據(jù)庫中查找。
GOPRIVATE:一個方便變量,用于將GONOPROXY和GONOSUMDB設(shè)置為相同的默認(rèn)值
我們可以通過go env
來查看到這些默認(rèn)值
$ go env
GONOPROXY=""
GONOSUMDB=""
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOSUMDB="sum.golang.org"
這些默認(rèn)值告訴Go工具使用Google模塊鏡像和Google checksum數(shù)據(jù)庫。如果這些Google服務(wù)可以訪問您所需的所有代碼,則建議使用此配置。如果Google模塊鏡像恰好以410(消失)或404(未找到)響應(yīng),則使用direct(這是GOPROXY配置的一部分)將允許Go工具更改路線并直接獲取模塊/版本VCS位置。
例如,如果我們需要訪問所有代理服務(wù)器,例如需要權(quán)限的位于gitlab
等地的代碼,我們可以使用export GOPRIVATE=gitlab.XXX.com,gitlab.XXX-XX.com,XXX.io
多個域名用逗號分隔。
Athens是一個私有模塊鏡像,可以用于搭建私有模塊鏡像。使用私有模塊鏡像的一個原因是允許緩存公共模塊鏡像無法訪問的私有模塊。Athens項目提供了一個在Docker Hub
上發(fā)布的Docker
容器,因此不需要特殊的安裝。
docker run -p '3000:3000' gomods/athens:latest
接下來,啟動一個新的終端會話以運行Athens,為大家演示其用法。啟動Athens服務(wù)并通過額外的參數(shù)調(diào)試日志(請確保系統(tǒng)已經(jīng)安裝并啟動了docker)并有科學(xué)*上網(wǎng)的環(huán)境
$ docker run -p '3000:3000' -e ATHENS_LOG_LEVEL=debug -e GO_ENV=development gomods/athens:latest
INFO[7:11AM]: Exporter not specified. Traces won't be exported
2020-03-06 07:11:30.671249 I | Starting application at port :3000
接著我們修改GOPROXY參數(shù),指向本地3000
端口,初始化我們之前的項目,再次執(zhí)行go mod tidy
$ export GOPROXY="http://localhost:3000,direct"
$ rm go.*
$ go mod init github.com/dreamerjackson/mathlib
$ go mod tidy
在Athens日志中即可查看對應(yīng)信息
INFO[7:39AM]: incoming request http-method=GET http-path=/github.com/dreamerjackson/mydiv/@v/list http-status=200
INFO[7:39AM]: incoming request http-method=GET http-path=/github.com/dreamerjackson/minidiv/@v/list http-status=200
INFO[7:39AM]: incoming request http-method=GET http-path=/github.com/dreamerjackson/minidiv/@latest http-status=200
詳細(xì)信息,查看參考資料中Athens的官方網(wǎng)站
提供脫離gopath
管理go代碼的優(yōu)勢
提供了代碼捆綁、版本控制、依賴管理的功能
供全球開發(fā)人員使用、構(gòu)建,下載,授權(quán)、驗證,獲取,緩存和重用模塊(可以通過搭建自己的代理服務(wù)器來實現(xiàn)這些功能)
可以驗證模塊(對于任何給定的版本)始終包含完全相同的代碼,而不管它被構(gòu)建了多少次,從何處獲取以及由誰獲取
本文題目:golang中的gomodule的介紹和使用方法
文章網(wǎng)址:http://jinyejixie.com/article36/ggeosg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作、面包屑導(dǎo)航、靜態(tài)網(wǎng)站、企業(yè)建站、外貿(mào)網(wǎng)站建設(shè)、ChatGPT
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)