GoMod 文档翻译

A_Donga · · 496 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

GO MOD

Go Mod : Golang 的包管理工具之一

中国代理

添加代理源

https://goproxy.cn

Go Mod 常用指令集

官方WIKI说明

链接:Go-Mod_Github/wiki

Go Mod 的使用

在使用Go Mod之前,需要将环境变量GO111MODULE设置为auto或者on,如果没有设置,将会默认开启。
也可以在运行Go指令之前,显示声明环境变量GO111MODULE=on

GO111MODULE 应该是 go mod 的1.11版本

项目初始化

$ go mod init <your project name>
$ # initialize new module in current directory
$ # 将当前目录初始化为Go Module

目录下会生成go.mod文件,该文件中声明了项目需要引用的依赖modules

文件的第一行声明了本项目的名称,通常你可以指定在为github.com/your name/project name

例如
$ go mod init github.com/A-Donga/Golangs

添加依赖

只需要在Go文件中加入需要引入的Mod即可。

官方示例
package main

import (
    "fmt"
    "rsc.io/quote"
)

func main(){
    fmt.Println(quote.Hello())
}
然后执行构建、编译指令(linux),最后运行即可。
$ go build -o hello
$ ./hello

示例代码

值得注意的是,上述过程中,没有使用go get指令。

常用指令

日常性操作

引用模块

  1. 将引用的代码加入到import中,当执行go build go test等指令时,go mod 会自动查找、下载、引用相关module

  2. 可以使用go get project@version的方式引用特定module的特定版本,也可以直接在go.mod文件夹直接写入相关信息。
    version可取的值

    1. 分支名称
    2. 版本号
    3. 提交git的记录ID

简单指令

  • go list -m all 查看所有引用Module(直接或间接)的版本。

  • go list -u -m all 查看所有引用Module(直接或间接)的最高版本信息。

  • go get -u ./... 或者 go get -u=patch ./... 将项目的所有引用Module(直接或间接)或者补丁升级到最新版本。

    patch指代补丁版本 go语言的版本规范:v(major).(minor).(patch)

  • go build ./... 从根目录编译项目,如果想要编译当前目录,去掉 ./...即可, 指令变为:go build

  • go test ./... 从根目录测试项目,如果想要测试当前目录,去掉 ./...即可,指令变为:go test

  • go mod tidy 去掉go.mod中不需要的依赖,并标注当前的系统信息。

  • go mod vendor 引导创建vendor目录。

Go Mod 概念声明

Modules

Modules是相关的Go软件包的集合,这些Go软件包一起作为一个单元进行了版本控制。

模块记录了每个依赖需求并创建了可以复用的构建。

通常,版本控制库(如Github、GitLib等)仅包含一个定义在存储库的根目录的一个模块。
(如果一个存储库中包含了多个模块将会导致更多的工作量)

存储库(Repositories)、模块(Modules)、包(Packages)之间的关系如下:

  • 一个存储库包含一个或多个Go模块。
  • 每个模块包含一个或多个Go包。
  • 每个包在一个目录下包含了一个或多Go源文件

模块必须根据Semver规范进行语义版本控制,通常采用v(major).(minor).(patch)的形式。

例如v0.1.0,v1.2.3或v1.5.0-rc.1(必须使用前置符号:v)。

如果使用Git工具,则标记为提交版本。

公共、私有模块存储库和代理都可以使用。

go.mod

模块被声明在Go源码文件树根目录下的go.mod文件中。模块源码可以存在于GOPATH环境变量之外。

四种等级:module require replace exclude

这里根据github.com/my/thing声明了一个示例:

module github.com/my/thing

require (
    github.com/some/dependency v1.2.3
    github.com/another/dependency/v4 v4.0.0
)

模块通过在go.mod中的module指令(通常为第一行)提供的模块路径声明其身份(标识符)。
模块路径作为该模块内所有包的工共前缀。
模块路径和模块内的Package的相对于go.mod文件的路径组合成为了该包的导入路径。

举例说明:

现在你有一个模块路径为github.com/user/mymod的模块仓库。
包含两个包:github.com/user/mymod/foogithub.com/user/mymod/bar
go.mod的第一行将被声明为module github.com/user/mymod,同时在磁盘上可能是如下的存在方式。

mymod
|-- bar
|   `-- bar.go
|-- foo
|   `-- foo.go
`-- go.mod

在Go的源码中,应该使用包含了模块路径的全路径进行引入指定包。
例如在上面的例子中,如果需要引用bar.go这个文件,你应该做如下声明:

import "github.com/user/mymod/bar"

excludereplace指令仅在当前模块上起作用。
在构建过程中,其他模块中的excludereplace指令将会被忽略。
因此,replace和exclude语句允许主模块完全控制其自身的构建,而不受依赖项的完全控制。

版本选择

如果在Go源码中,引入了一个没有在go.mod中声明的模块,在执行go build或者go test的指令时,将会自动寻找目标模块的最高版本,并使用require指令进行引入。
比如你想引用模块A,而模块A的当前最高版本为v1.2.3,然后在你的模块中,go.mod将会使用require指令引入M v1.2.3。
这代表着,你接受版本>=v1.2.3并且小于v2。(在规范中,v(y)于v(x)不兼容)

最小版本选择算法用于选择构建中使用的所有模块的版本。
对于构建中的每个模块,通过最小版本选择的版本始终是主模块中的require指令或其依赖项之一明确列出的版本的语义上最高的版本。

上述表达很难懂,没关系,看例子

你的模块中依赖了两个模块:A,B, A模块依赖D模块(v1.0.0),B模块依赖D模块(v1.1.1),那么此时最小版本选择算法将会选择Dv1.1.1
即使一段时间后,v1.2.0已经可用,但是最小版本仍会选择v1.1.1。当然你可以利用指令手动升级,升级到最新可用版本,或者直接手动选择版本。

如何使用模块

如果安装并支持模块

如果需要使用模块,有以下两种方式(个人推荐方式一)

当你完成安装后,你有一下两种方式启用模块支持

  • $GOPATH/src树之外的目录中调用go命令,并在当前目录或其任何父目录中使用有效的go.mod文件,并且未设置环境变量GO111MODULE(或将其显式设置为auto)。
  • 在设置了环境变量的GO111MODULE=on调用go命令。

如何声明一个模块

为一个已经存在的项目创建一个go.mod文件:

  1. 进入到项目根目录

    $ cd <project path>
    

    如果是GOPATH路径外,你不需要用GO111MOUDLE显式激活。

    如果你想要在GOPATH路径内使用:

    $ # for linux or mac
    $ export GO111MOUDLE=on
    $ cd $GOPATH/src/<project path>
    
  2. 对项目进行模块初始化,并将信息写入go.mod

    $ go mod init
    

    这一步将会创建go.mod并将模块信息写入,同时如果目录存在其他类型的模块管理工具,将会自动匹配并以require指令导入到go.mod文件中。
    共支持9种依赖引用格式:

    1. GLOCKFILE
    2. Godeps/Godeps.json
    3. Gopkg.lock
    4. dependencies.tsv
    5. glide.lock
    6. vendor.conf
    7. vendor.yaml
    8. vendor/manifest
    9. vendor/vendor.json

    有关此部分的详细信息请查看:Go-模块转换

    值得注意的是,如果你引用了v2+的模块,或者正在构建、初始化这类模块,需要在go mod init指令运行之后,手动编辑go.mod、Go文件,引用指定的模块路径。
    可以参考语义版本控制进行修正。
    即使已经从其他以来管理工中转换过来了。
    直到你成功运行go build指令后,你才可以使用go tidy指令。

  3. 正常操作希望操作的指令即可

    1. go build ./...
    2. go test ./...
    3. go test all

如何升级或降级依赖版本

日常的升级、降级操作通过指令go get自动更新go.mod文件来实现,当然,你可以选择直接编辑go.mod文件。

Go指令go buildgo test 甚至 go list也会将必要的依赖引入进来(更新go.mod文件,同时下载需要的依赖)。

将指定依赖升级到最高可用版本:

$ go get example.com/package

更新某个依赖项以及他的依赖到最新可用版本

$ go get -u example.com/package

查看所有依赖(直接或间接)的minorpatch的最高可用信息。

$ go list -u -m all

查看所有直接引用的模块的minorpatch版本信息

$ go list -u -f '{{if (and (not (or .Main .Indirect)) .Update)}}{{.Path}}: {{.Version}} -> {{.Update.Version}}{{end}}' -m all 2> /dev/null

go list -u -f 为格式化输出,-f后面跟上格式化方式,支持基本布尔运算。
这句话理解起来有些难度,用处不是特别大,比如你想查找所有的目录,可以使用:

$ go list -f {{.Dir}}

加上直接依赖

$ go list -f {{if (or .Main .Indirect)}}

后面的指令可以类推

更多详细的信息可以查看

$ go help list

在当前模块内,将所有直接或间接依赖升级到最新最新可用版本,在根目录运行:

$ go get -u ./...

$ go get -u=patch

升级指定包

$ go get foo

$ go get -u foo

发布模块

由于国内的网络问题,基本上官方文档的方案不可用,因此不做翻译,这里链接一个非常好的说明文档:https://studygolang.com/articles/26694?fr=sidebar

官方原文链接:https://github.com/golang/go/wiki/Modules#how-to-prepare-for-a-release


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:A_Donga

查看原文:GoMod 文档翻译

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

496 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传