betway必威-betway必威官方网站
做最好的网站

get实行李包裹管理,简明使用指南

golang的包管理是一直是为人诟病之处,从golang1.5引入的vendor机制,到准官方工具dep,目前为止还没一个简便的解决方案。

上一篇文章里我们介绍了go modules的初步使用,现在我们来更深入的了解一下如何使用go get在module中管理依赖。

download download modules to local cache (下载依赖的module到本地cache))edit edit go.mod from tools or scripts (编辑go.mod文件)graph print module requirement graph init initialize new module in current directory (再当前文件夹下初始化一个新的module, 创建go.mod文件))tidy add missing and remove unused modules (增加丢失的module,去掉未用的module)vendor make vendored copy of dependencies (将依赖复制到vendor下)verify verify dependencies have expected content why explain why packages or modules are needed (解释为什么需要依赖)

不过现在go modules随着golang1.11的发布而和我们见面了,这是官方提倡的新的包管理,乃至项目管理机制,可以不再需要GOPATH的存在。

module下的包管理

首先我们介绍过go mod edit修改go.mod,然而它有两点缺陷:

  • 首先是它的-require必须接受“package@version”这种形式,缺一不可,而且不能识别文档规定的master和latest标志。
  • 其次是edit只适合用于修改依赖版本,给package改名,屏蔽特定的package这三个功能,不适用于添加依赖。

好消息是go get现在有了在modules中添加/修改/更新package的能力。

想要完整体验go modules,我们需要选择一个GOPATH以外的目录,并且设置GO11MODULE=on,这样使用go get时只会影响当前的main module,不会污染GOPATH。

这次我选用自己做着玩的玩具项目演示在没有进行包管理的项目中使用go modules。(关于vendor的迁移,可以使用go mod vendor -v,详细介绍以后会有)。

我们将项目clone到非GOPATH的路径下,然后使用

go mod init [project name]

初始化module。初始化后的目录:

图片 1

这时go.mod还是空的,我们知道go build会更新go.mod,所以我们先go build

图片 2

默认会使用go get获得latest的package,现在go.mod已经被更新了,项目也成功被编译,这是go.mod:

module schanclientrequire (    github.com/PuerkitoBio/goquery v1.4.1    github.com/andybalholm/cascadia v1.0.0 // indirect    github.com/chromedp/chromedp v0.1.2    golang.org/x/net v0.0.0-20180826012351-8a410e7b638d // indirect)

indirect的意思是指这个package被子module/package依赖了,但是main module并没有直接import使用,也就是所谓的间接引用。

通常,go.mod使用默认行为就可以很好地完成包管理,不过生活中总是有些例外。

我们看到chromedp使用了0.1.2版本,这是三个月前的版本了,最新的commit在上个月,go mod edit需要明确指定版本号或者commit的时间 checksum,显然这很麻烦,不是我们希望的。

那么我们要如何才能使用最新的版本而不是最新的tags呢?

又或者我们不想要最新的版本,需要某个特定版本的package呢?

这就是版本选择的内容了。

其它命令可以通过go help mod来查看。

go module的初始化

现在modules机制仍在早期阶段,所以golang提供了一个环境变量“GO111MODULE”,默认值为auto,如果当前目录里有go.mod文件,就使用go modules,否则使用旧的GOPATH和vendor机制,因为在modules机制下go get只会下载go modules,这一行为会在以后版本中成为默认值,这里我们保持auto即可,如果你想直接使用modules而不需要从GOPATH过度,那么把“GO111MODULE”设置为on。

modules和传统的GOPATH不同,不需要包含例如src,bin这样的子目录,一个源代码目录甚至是空目录都可以作为module,只要其中包含有go.mod文件。

我们就用一个空目录来创建我们的第一个module:

要初始化modules,需要使用如下命令(假设已经安装配置好golang1.11):

go mod init [module name]

我们的module叫test,所以就是:

go mod init test

初始完成后会在目录下生成一个go.mod文件,里面的内容只有一行“module test”。

go get的新特性——版本选择

以前有过gopkg.in go get这种解决方案,而新的go get所支持的版本选择则是这一方案的进一步扩展,看几条规则:

  • go get会自动下载并安装package,然后更新到go.mod中
  • 可以使用go get package[@version]来安装指定版本的package,不指定version时默认行为和go get package@latest一样
  • version可以是vx.y.z这种形式或者直接使用commit的checksum,也可以是master或者latest
  • 当version是latest时,也就是默认行为,对于有tags的package,会选取最新的tag,对于没有tags的package,则选取最新的commit
  • 当version是master时,不管package有没有打tag,都会选择master分支的最新commit
  • 可以在version前使用>,>=,<,<=,表示选取的版本不得超过/低于version,在这个范围内的符合latest条件的版本
  • go get -u可以更新package到latest版本
  • go get -u=patch将只更新小版本,例如从v1.2.4到v1.2.5
  • 当想要修改package的版本时,只需要go get package@指定的version即可

那么我们想要把chromedp改用最新版本就很简单了:

go get github.com/chromedp/chromedp@master

现在go.mod里已经将chromedp更新了:

module schanclientrequire (github.com/PuerkitoBio/goquery v1.4.1github.com/andybalholm/cascadia v1.0.0 // indirectgithub.com/chromedp/chromedp v0.1.3-0.20180717231922-bf52fed0d3e6golang.org/x/net v0.0.0-20180826012351-8a410e7b638d // indirect)

如果我们现在想要添加额外的package呢?

直接使用go get就可以了,比如我现在想用gorm往数据库存数据:

go get github.com/jinzhu/gorm

更新后的go.mod

module schanclientrequire (github.com/PuerkitoBio/goquery v1.4.1github.com/andybalholm/cascadia v1.0.0 // indirectgithub.com/chromedp/chromedp v0.1.3-0.20180717231922-bf52fed0d3e6github.com/jinzhu/gorm v1.9.1 // indirectgithub.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a // indirectgolang.org/x/net v0.0.0-20180826012351-8a410e7b638d // indirect)

我们看到latest版本的gorm已经被添加了,当然因为我们在main module里没有import使用它,所以是indirect的。

如果我们想用v1.9的gorm:

go get github.com/jinzhu/gorm@v1.9

很遗憾,版本选择是从大版本到小版本的顺序,如果有v1.9和v1.9.1,那么当你指定v1.9时会自动选取小版本号最高的版本,除非除了v1.9之外没有其他的v1.9.z的tag存在,在这里就是v1.9.1。

还有一点值得一提,go build和go test只会将go.mod中没有的package添加进去,不会覆盖或者改变go get引入的规则,所以不用担心他们会冲突。

是不是觉得和venv pip很像,没错,这说明go的包管理工具也逐渐步入现代化了。

至于屏蔽package,删除package以及为package改名(比如golang.org/x/...的访问不了的package),这些是go mod edit的功能,具体的请查看go help mod edit。

因为go modules的资料还不完善,所以我也是对着文档边看边做,难免会有疏漏和错误,欢迎大家指正!

可以用环境变量 GO111MODULE 开启或关闭模块支持,它有三个可选值:off、on、auto,默认值是 auto。

本文由betway必威发布于编程开发,转载请注明出处:get实行李包裹管理,简明使用指南

TAG标签: betway必威
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。