问题一: 依赖包的版本是怎么控制的?
下载的依赖包 ($GOPATH/pkg/mod) 是存在版本定义的(如:github.com/astaxie/beego@v1.11.1 )最后会有一个版本号 1.11.1,也就是说,$GOPATH/pkg/mod里可以保存相同包的不同版本。
版本是在go.mod中指定的:
- 如果,在go.mod中没有指定,go命令会自动下载代码中的依赖的最新版本,本例就是自动下载最新的版本。
- 如果,在go.mod用require语句指定包和版本 ,go命令会根据指定的路径和版本下载包, 指定版本时可以用latest,这样它会自动下载指定包的最新版本;
是包的发布者标记的版本号,格式为 vn.n.n (n代表数字),本例中的beego的历史版本可以在其代码仓库release看到Releases · astaxie/beego · GitHub
如果包的作者还没有标记版本,默认为 v0.0.0
问题二: 依赖包中的地址失效了怎么办?比如 golang.org/x/… 下的包都无法下载怎么办? 在go快速发展的过程中,有一些依赖包地址变更了。 以前的做法
修改源码,用新路径替换import的地址 git clone 或 go get 新包后,copy到$GOPATH/src里旧的路径下 无论什么方法,都不便于维护,特别是多人协同开发时。
使用go.mod就简单了,在go.mod文件里用 replace 替换包,例如
replace golang.org/x/text => github.com/golang/text latest
这样,go会用 github.com/golang/text 替代golang.org/x/text,原理就是下载github.com/golang/text 的最新版本到 $GOPATH/pkg/mod/golang.org/x/text下。
问题三: init生成的go.mod的模块名称有什么用?本例里,用 go mod init hello 生成的go.mod文件里的第一行会申明 module hello
因为我们的项目已经不在$GOPATH/src里了,那么引用自己怎么办?就用模块名+路径。
例如,在项目下新建目录 utils,创建一个tools.go文件:
package utils
import “fmt”
func PrintText(text string) {
fmt.Println(text)
}
在根目录下的hello.go文件就可以 import “hello/utils” 引用utils
package main
import (
"hello/utils"
"github.com/astaxie/beego"
)
func main() {
utils.PrintText("Hi")
beego.Run()
}
问题四:以前老项目如何用新的包管理 - 如果用auto模式,把项目移动到$GOPATH/src外
- 进入目录,运行 go mod init [模块名称]
- go build 或者 go run 一次
// 注意:项目目录下操作
$ go get github.com/isbrick/tools@c87b277
$ go mod vendor
注 : 根据官方的说法,从Go 1.13开始,模块管理模式将是Go语言开发的默认模式。
问题六:Go 如何 import private的代码仓库的包对于 public 的仓库,大家知道是可以直接import的,而对于 private 代码仓库我们则需要如下操作:
- 对于本地开发环境
- The Because of go module proxy site just like Maven default repo go also has a proxy site( 所以我们需要通过声明GOPRIVATE环境变量来绕过, 如果 GOPRIVATE有多个值通过逗号来分隔。
go env -w GOPRIVATE=git.repoxxx.com/[groupName]
注 : The new GO PRIVATE environment variable indicates module paths that are not publicly available. It serves as the default value for the lower-level GONOPROXY and GONOSUMDB variables, which provide finer-grained control over which modules are fetched via proxy and verified using the checksum database.
- 添加 access_token或是 ssh key 解决私有仓库的验证问题。
# access_token 可以在对应用户下配置
$ git config --global url."{username}:${access_token}@private.gitrepo.com".insteadOf /
"#34;
# Or use ssh-key 将私钥放置下对应的用户下
# 也许,这个 ssh-key 私钥的并不是默认路径,那么你可以通过这个方式指定
# $ cat ~/.ssh/config
# Host yourserver
# Hostname something.domain.tld
# IdentityFile /var/www/html/ma.ttias.be/.ssh/id_rsa
# IdentitiesOnly yes
$ git config --global url."git@yourserver".insteadOf /
"#34;
特别说明 : 不论使用access_token或是ssh key, 强烈建议使用独立的用户,另外对于步骤2中insteadOf 的地址建议尽量精确些, 避免其他的同站下的git项目产生影响, 如下:
$ cat ~/.gitconfig |grep url -A3
[url "#34;]
insteadOf =
- 对于CI/CD
如果你的项目已经将vendor随代码一起提交,那么你 go build 时可以直接用 -mod vendor的方式来 build, 倘若你的项目里没有管理vendor项目,那么Dockerfile里也要有类似于 对于本地开发环境 的设置。
Dockerfile部分示例
...
RUN go env -w GOPRIVATE=github.com/colynn
# 确认 build 环境里包含 git command
RUN apk add git
RUN git config --global url."#34;.insteadOf "#34;
...