<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
最近由於換工作,開始交接工作。整理以前的工作內容,由於組內就我一個在做go和巨量資料。 所以開發沒有規劃,當時是怎麼快怎麼來。go也是使用最傳統的go path的方式管理的。都是手動管理依賴的。現在交接給他人,需要多人開發,發現很多問題。比如版本問題,各種依賴的問題等等。
由於工作原因,幾乎所有主流語言都寫過。所以,對應語言套件管理工具也都瞭解和使用過。我前面有寫過maven的使用。
maven是使用過的功能最強大的包管理工具了,maven定位是專案管理工具。pip和npm都是及格的產品。
我個人覺得,一個包管理工具應該有以下功能:
基本功能
加分:
對比上面幾點:
目前做的最好的也就 maven了,gradle沒有使用過,不知道。
今天主角是go mod,先來談談沒有使用go mod之前的問題。
從這個看, go path不算包管理工具
go modules 是 golang 1.11 新加的特性。現在1.12 已經發布了,是時候用起來了。Modules官方定義為:
模組是相關Go包的集合。modules是原始碼交換和版本控制的單元。 go命令直接支援使用modules,包括記錄和解析對其他模組的依賴性。modules替換舊的基於GOPATH的方法來指定在給定構建中使用哪些原始檔。
首先,必須升級go到1.11,目前版本是1.14
下面我以我自己升級演示:
### 解除安裝舊版本,刪除對應檔案 brew uninstall -f go ### 更新一下brew brew update ### 安裝go brew install go
上面升級完了,使用 go version
看下版本
go version go1.14.1 darwin/amd64
下面設定go mod和go proxy
go env -w GOBIN=/Users/youdi/go/bin go env -w GO111MODULE=on go env -w GOPROXY=https://goproxy.cn,direct // 使用七牛雲的
注意: go env -w會將設定寫到 GOENV="/Users/youdi/Library/Application Support/go/env"
下面看下我的設定
GO111MODULE="on" GOARCH="amd64" GOBIN="/Users/youdi/go/bin" GOCACHE="/Users/youdi/Library/Caches/go-build" GOENV="/Users/youdi/Library/Application Support/go/env" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="darwin" GOINSECURE="" GONOPROXY="" GONOSUMDB="" GOOS="darwin" GOPATH="/Users/youdi/go" GOPRIVATE="" GOPROXY="https://goproxy.cn,direct" GOROOT="/usr/local/go" GOSUMDB="off" GOTMPDIR="" GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64" GCCGO="gccgo" AR="ar" CC="clang" CXX="clang++" CGO_ENABLED="1" GOMOD="/dev/null" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/8m/v_1j4dgs7rzgqq4p_4_8k_nr0000gn/T/go-build221113671=/tmp/go-build -gno-record-gcc-switches -fno-common"
我們看一下,我修改的內容
cat /Users/youdi/Library/Application Support/go/env
GO111MODULE=on GOBIN=/Users/youdi/go/bin GOPROXY=https://goproxy.cn,direct GOSUMDB=off
GO111MODULE 有三個值:off, on和auto(預設值)。
當前目錄在GOPATH/src之外且該目錄包含go.mod檔案
當前檔案在包含go.mod檔案的目錄下面。
當modules功能啟用時,依賴包的存放位置變更為$GOPATH/pkg,允許同一個package多個版本並存,且多個專案可以共用快取的 module
我們看下目錄:
cd /Users/youdi/go/pkg
├── darwin_amd64
│ ├── github.com
│ ├── go.etcd.io
│ ├── golang
│ ├── golang.org
│ ├── gopkg.in
│ ├── quickstart
│ └── uc.a
├── mod
│ ├── cache
│ ├── github.com
│ ├── golang.org
│ ├── google.golang.org
│ └── gopkg.in
└── sumdb
└── sum.golang.org
golang 提供了 go mod
命令來管理包。
go help mod
Go mod provides access to operations on modules. Note that support for modules is built into all the go commands, not just 'go mod'. For example, day-to-day adding, removing, upgrading, and downgrading of dependencies should be done using 'go get'. See 'go help modules' for an overview of module functionality. Usage: go mod <command> [arguments] The commands are: download download modules to local cache edit edit go.mod from tools or scripts graph print module requirement graph init initialize new module in current directory tidy add missing and remove unused modules vendor make vendored copy of dependencies verify verify dependencies have expected content why explain why packages or modules are needed Use "go help mod <command>" for more information about a command.
go mod 有以下命令:
命令 | 說明 |
---|---|
download | download modules to local cache(下載依賴包) |
edit | edit go.mod from tools or scripts(編輯go.mod) |
graph | print module requirement graph (列印模組依賴圖) |
verify | initialize new module in current directory(在當前目錄初始化mod) |
tidy | add missing and remove unused modules(拉取缺少的模組,移除不用的模組) |
vendor | make vendored copy of dependencies(將依賴複製到vendor下) |
verify | verify dependencies have expected content (驗證依賴是否正確) |
why | explain why packages or modules are needed(解釋為什麼需要依賴) |
比較常用的是 init
,tidy
, edit
可以隨便找一個目錄建立專案,我使用習慣用IDEA進行建立
mkdir Gone cd Gone go mod init Gone
檢視一下 go.mod檔案
module Gone go 1.14
go.mod檔案一旦建立後,它的內容將會被go toolchain全面掌控。go toolchain會在各類命令執行時,比如go get、go build、go mod等修改和維護go.mod檔案。
go.mod 提供了module, require、replace和exclude 四個命令
module
語句指定包的名字(路徑)require
語句指定的依賴項模組replace
語句可以替換依賴項模組exclude
語句可以忽略依賴項模組建立 main.go檔案
package main import ( "github.com/gin-gonic/gin" ) func main() { r := gin.Default() r.GET("/ping", func(c *gin.Context) { c.JSON(200, gin.H{ "message": "pong", }) }) r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080") }
執行 go run main.go 執行程式碼會發現 go mod 會自動查詢依賴自動下載
再檢視 go.mod
module Gone go 1.14 require github.com/gin-gonic/gin v1.6.3
go module 安裝 package 的原則是先拉最新的 release tag,若無tag則拉最新的commit
go 會自動生成一個 go.sum 檔案來記錄 dependency tree
再次執行指令碼 go run main.go發現跳過了檢查並安裝依賴的步驟。
可以使用命令 go list -m -u all 來檢查可以升級的package,使用go get -u need-upgrade-package 升級後會將新的依賴版本更新到go.mod * 也可以使用 go get -u 升級所有依賴
去mod包快取下看看
/Users/youdi/go/pkg/mod/github.com/gin-gonic/gin@v1.6.3
由於某些已知的原因,並不是所有的package都能成功下載,比如:golang.org下的包。
modules 可以通過在 go.mod 檔案中使用 replace 指令替換成github上對應的庫,比如:
replace ( golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a => github.com/golang/crypto v0.0.0-20190313024323-a1f597ede03a )
參考Roberto Selbach寫的go mod入門文章,文末,我給出連結
如果你設定好go mod了,那你就可以在任何目錄下隨便建立
$mkdir gomodone $cd gomodone
在這個目錄下建立一個檔案say.go
package gomodone import "fmt" // say Hi to someone func SayHi(name string) string { return fmt.Sprintf("Hi, %s", name) }
初始化一個 go.mod
檔案
$ go mod init github.com/jacksonyoudi/gomodone go: creating new go.mod: module github.com/jacksonyoudi/gomodone
檢視 go.mod內容如下:
github.com/jacksonyoudi/gomodone go 1.14
下面我們要將這個module釋出到github上,然後在另外一個程式使用
$git init $vim .gitiiignore $git commit -am "init" // github建立對應的repo $git remote add origin git@github.com:jacksonyoudi/gomodone.git $git push -u origin master
執行完,上面我們就相當於釋出完了。
如果有人需要使用,就可以使用
go get github.com/jacksonyoudi/gomodone
這個時候沒有加tag,所以,沒有版本的控制。預設是v0.0.0後面接上時間和commitid。如下:
gomodone@v0.0.0-20200517004046-ee882713fd1e
官方不建議這樣做,沒有進行版本控制管理。
使用tag,進行版本控制
git tag v1.0.0 git push --tags
操作完,我們的module就釋出了一個v1.0.0的版本了。
推薦在這個狀態下,再切出一個分支,用於後續v1.0.0的修復推播,不要直接在master分支修復
$git checkout -b v1 $git push -u origin v1
上面已經發布了一個v1.0.0的版本,我們可以在另一個專案中使用,建立一個go的專案
$mkdir Gone $cd Gone $vim main.go
package main import ( "fmt" "github.com/jacksonyoudi/gomodone" ) func main() { fmt.Println(gomodone.SayHi("Roberto")) }
程式碼寫好了,我們生成 go mod檔案
go mod init Gone
上面命令執行完,會生成 go mod檔案
看下mod檔案:
module Gone go 1.14 require ( github.com/jacksonyoudi/gomodone v1.0.0 )
$go mod tidy go: finding module for package github.com/jacksonyoudi/gomodone go: found github.com/jacksonyoudi/gomodone in github.com/jacksonyoudi/gomodone v1.0.0
同時還生成了go.sum, 其中包含軟體包的雜湊值,以確保我們具有正確的版本和檔案。
github.com/jacksonyoudi/gomodone v1.0.1 h1:jFd+qZlAB0R3zqrC9kwO8IgPrAdayMUS0rSHMDc/uG8= github.com/jacksonyoudi/gomodone v1.0.1/go.mod h1:XWi+BLbuiuC2YM8Qz4yQzTSPtHt3T3hrlNN2pNlyA94= github.com/jacksonyoudi/gomodone/v2 v2.0.0 h1:GpzGeXCx/Xv2ueiZJ8hEhFwLu7xjxLBjkOYSmg8Ya/w= github.com/jacksonyoudi/gomodone/v2 v2.0.0/go.mod h1:L8uFPSZNHoAhpaePWUfKmGinjufYdw9c2i70xtBorSw=
這個內容是下面的,需要操作執行的結果
go run main.go就可以執行了
假如fix一個bug,我們在v1版本上進行修復
修改程式碼如下:
// say Hi to someone func SayHi(name string) string { - return fmt.Sprintf("Hi, %s", name) + return fmt.Sprintf("Hi, %s!", name) }
修復好,我們開始push
$ git commit -m "Emphasize our friendliness" say.go $ git tag v1.0.1 $ git push --tags origin v1
剛才fix bug,所以要在我們使用專案中更新
這個需要我們手動執行更新module操作
我們通過使用我們的好朋友來做到這一點go get:
go get -u
以使用最新的 minor 版本或修補程式版本(即它將從1.0.0更新到例如1.0.1,或者,如果可用,則更新為1.1.0)目前module最新的也是v1.0.1
// 更新最新 $go get -u $go get -u=patch //指定包,指定版本 $go get github.com/jacksonyoudi/gomodone@v1.0.1
操作完,go.mod檔案會修改如下:
module Gone go 1.14 require ( github.com/jacksonyoudi/gomodone v1.0.1 )
根據語意版本語意,主要版本與次要版本 不同。主要版本可能會破壞向後相容性。從Go模組的角度來看,主要版本是 完全不同的軟體包。乍一看這聽起來很奇怪,但這是有道理的:兩個不相容的庫版本是兩個不同的庫。
比如下面修改,完全破壞了相容性。
package gomodone import ( "errors" "fmt" ) // Hi returns a friendly greeting // Hi returns a friendly greeting in language lang func SayHi(name, lang string) (string, error) { switch lang { case "en": return fmt.Sprintf("Hi, %s!", name), nil case "pt": return fmt.Sprintf("Oi, %s!", name), nil case "es": return fmt.Sprintf("¡Hola, %s!", name), nil case "fr": return fmt.Sprintf("Bonjour, %s!", name), nil default: return "", errors.New("unknown language") } }
如上,我們需要不同的大版本,這種情況下
修改 go.mod如下
module github.com/jacksonyoudi/gomodone/v2 go 1.14
然後,重新tag,push
$ git commit say.go -m "Change Hi to allow multilang" $ git checkout -b v2 # 用於v2版本,後續修復v2 $ git commit go.mod -m "Bump version to v2" $ git tag v2.0.0 $ git push --tags origin v2
即使釋出了庫的新不相容版本,現有軟體 也不會中斷,因為它將繼續使用現有版本1.0.1。go get -u 將不會獲得版本2.0.0。
如果想使用v2.0.0,程式碼改成如下:
package main import ( "fmt" "github.com/jacksonyoudi/gomodone/v2" ) func main() { g, err := gomodone.SayHi("Roberto", "pt") if err != nil { panic(err) } fmt.Println(g) }
執行 go mod tidy
go: finding module for package github.com/jacksonyoudi/gomodone/v2 go: downloading github.com/jacksonyoudi/gomodone/v2 v2.0.0 go: found github.com/jacksonyoudi/gomodone/v2 in github.com/jacksonyoudi/gomodone/v2 v2.0.0
當然,兩個版本都可以同時使用, 使用別名
如下:
package main import ( "fmt" "github.com/jacksonyoudi/gomodone" mv2 "github.com/jacksonyoudi/gomodone/v2" ) func main() { g, err := mv2.SayHi("Roberto", "pt") if err != nil { panic(err) } fmt.Println(g) fmt.Println(gomodone.SayHi("Roberto")) }
執行一下 go mod tidy
預設是忽略vendor的,如果想在專案目錄下有vendor可以執行下面命令
$go vendor
當然,如果構建程式的時候,希望使用vendor中的依賴,
$ go build -mod vendor
建立完專案,會自動生成go mod檔案
如果需要修改,可以手動修改,加入git等操作
寫業務邏輯程式碼
解決依賴,更新go.mod
到此這篇關於go mod詳細使用教學的文章就介紹到這了,更多相關go mod使用內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45