七叶笔记 » golang编程 » Go Mod的包管理你已经用了吗,这6个常见问题记得收藏

Go Mod的包管理你已经用了吗,这6个常见问题记得收藏

问题一: 依赖包的版本是怎么控制的?

下载的依赖包 ($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()
}
  

问题四:以前老项目如何用新的包管理

  1. 如果用auto模式,把项目移动到$GOPATH/src外
  2. 进入目录,运行 go mod init [模块名称]
  3. go build 或者 go run 一次

问题五:mod形式下如何下载指定版本的包

 // 注意:项目目录下操作
$ go get github.com/isbrick/tools@c87b277
$ go mod vendor
  

: 根据官方的说法,从Go 1.13开始,模块管理模式将是Go语言开发的默认模式。

问题六:Go 如何 import private的代码仓库的包

对于 public 的仓库,大家知道是可以直接import的,而对于 private 代码仓库我们则需要如下操作:

  • 对于本地开发环境
  1. 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.

  1. 添加 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;
...  

相关文章