Go Modules基础

文章目录

      • 1. 简介
      • 2. 基础命令
      • 3. 基本使用
        • 3.1 go mod init
        • 3.1 下载指定版本的依赖库
        • 3.2 更新依赖库
        • 3.3 go get简介

1. 简介

GO Modules 也称作 go mod 是golang 官方最新的几个golang 版本中推出的 管理方式或者称作模块支持

golang 中 modules (模块)是什么意思呢?

一个模块是一系列 Go 代码包 的集合,它们保存在同一个文件树中。文件树的根目录中包含了一个 go.mod 文件。go.mod 文件定义了一个模块的 module path,这就是模块根目录的导入路径。go.mod 文件还定义了模块的 dependency requirements(依赖项要求),即为了编译本模块,需要用到哪些其它的模块。每一项依赖项要求都包含了依赖项的 module path,还要指定它的语义版本号。

在最新的golang版本golang 1.13中是默认的包管理方式,那么在golang的后期版本中 Go Modules 基本可以认为是官方推荐的依赖管理工具

GO modules 是解决啥问题的?

Golang在早期的版本中(golang 1.11版本之前) 包管理一直没有一个统一方案,表现出问题如:

  1. 所有的依赖包都必须在GOPATH同一个库只能保存一个版本的代码,那么不同的项目要依赖同一个包的不同版本那就很尴尬了.
  2. 工作目录必须在 GOPATH/src 目录下

使用了Go Modules 之后就可在GOPATh/src 之外创建目录和管理包了

我们大概回顾一下

  1. golang 1.5 版本之前所有的依赖包都必须放在 GOPATH 下面,没有版本管理
  2. golang 1.5 版本之后推出 vendor 机制
  3. golang 1.9 版本出现了包管理工具 dep
  4. golang1.11 版本推出 modules 机制对包进行管理,在之后的版本中modules 逐步得到了加强, 在golang1.13 中成为默认的包管理方式并且是默认开启的

2. 基础命令

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  [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 " for more information about a command.

显示的 go mod 实际命令只有如下几个

命令 意思
go mod download 下载依赖的Module到本地缓存
go mod edit 编辑go.mod文件
go mod graph 打印模块依赖图
go mod init 初始化当前目录中的新模块,创建go.mod文件
go mod tidy 增加缺失的Module,删除无效的Module
go mod vendor 将依赖复制到vendor下
go mod verify 校验依赖
go mod why 解释package或者modules为啥被依赖

3. 基本使用

3.1 go mod init

我们在非GOPATH/src 目录下执行

go mod init 后面是模块名称 ,名称自定义即可

$ go mod init github.com/captain/modDemo
go: creating new go.mod: module github.com/captain/modDemo

这样在项目(模块)目录下多出了一个文件go.mod 文件

我们看看go.mod 中的内容

module github.com/captain/modDemo

go 1.12

我们下载一个依赖包试试

// 执行 如下命令
go get -u github.com/gin-gonic/gin

初次执行下依赖包的命令后会多出一个文件 go.sum

go.sum 是由 go命令行工具维护的,其中记录了每个依赖库的版本和哈希值,其作用是确保项目依赖的模块不会发生变化

执行完之后,我们再看看go.mod 的内容

module github.com/apiDemo

go 1.12

require (
	github.com/gin-gonic/gin v1.5.0 // indirect
	github.com/go-playground/universal-translator v0.17.0 // indirect
	github.com/json-iterator/go v1.1.8 // indirect
	github.com/leodido/go-urn v1.2.0 // indirect
	github.com/mattn/go-isatty v0.0.10 // indirect
	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
	github.com/modern-go/reflect2 v1.0.1 // indirect
	github.com/stretchr/objx v0.2.0 // indirect
	golang.org/x/crypto v0.0.0-20191128160524-b544559bb6d1 // indirect
	golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933 // indirect
	golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect
	golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 // indirect
	golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d // indirect
	golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 // indirect
	gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
	gopkg.in/go-playground/validator.v9 v9.30.2 // indirect
	gopkg.in/yaml.v2 v2.2.7 // indirect
)

go.mod 文件简介:

module 用来定义包名和我们初始化的包名是一致的

require 定义依赖的包及其对应的版本

indirect 标识间接引用

3.1 下载指定版本的依赖库

go list -m all 列出当前模块和它的依赖库

$ go list -m all
github.com/captain/modDemo
github.com/davecgh/go-spew v1.1.1
github.com/gin-contrib/sse v0.1.0
github.com/gin-gonic/gin v1.5.0
github.com/go-playground/locales v0.13.0
github.com/go-playground/universal-translator v0.17.0
github.com/golang/protobuf v1.3.2
github.com/google/gofuzz v1.0.0
github.com/json-iterator/go v1.1.8
github.com/leodido/go-urn v1.2.0
github.com/mattn/go-isatty v0.0.10
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
github.com/modern-go/reflect2 v1.0.1
github.com/pmezard/go-difflib v1.0.0
github.com/stretchr/objx v0.2.0
github.com/stretchr/testify v1.4.0
github.com/ugorji/go v1.1.7
github.com/ugorji/go/codec v1.1.7
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413
golang.org/x/net v0.0.0-20191207000613-e7e4b65ae663
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e
golang.org/x/sys v0.0.0-20191206220618-eeba5f6aabab
golang.org/x/text v0.3.2
golang.org/x/tools v0.0.0-20191206204035-259af5ff87bd
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15
gopkg.in/go-playground/assert.v1 v1.2.1
gopkg.in/go-playground/validator.v9 v9.30.2
gopkg.in/yaml.v2 v2.2.7

go list -m -versions 库名地址 列出一个模块能用的版本

$ go list -m -versions github.com/gin-gonic/gin
github.com/gin-gonic/gin v1.1.1 v1.1.2 v1.1.3 v1.1.4 v1.3.0 v1.4.0 v1.5.0

go mod tidy 删除无效的modules

$ go mod tidy
$ go list -m all
github.com/captain/modDemo

我们拿比较常见的 一个库xrom做示例 下载指定的版本

可见 xorm可用的版本很多

$ go list -m -versions github.com/go-xorm/xorm
github.com/go-xorm/xorm v0.2.1 v0.2.2 v0.2.3 v0.3.1 v0.3.2 v0.4.1 v0.4.2 v0.4.3 v0.4.4 v0.4.5 v0.5.0 v0.5.1 v0.5.2 v0.5.3 v0.5.4 v0.5.6 v0.5.7 v0.5.8 v0.6.2 v0.6.3 v0.6.4 v0.6.5 v0.6.6 v0.7.0 v0.7.1 v0.7.2 v0.7.3 v0.7.4 v0.7.5 v0.7.6 v0.7.7 v0.7.8 v0.7.9

go mod 想下载指定的版本 通常我们有三种做法

  1. go get 包路径@v版本号
  2. go get 包路径@分支 分支是指在github上提交的分支
  3. go get 包路径@git提交的哈希

我们看到目前 xorm 最新版本是 v0.7.9 但是我想下载比较旧一点的版本 v0.7.5

$ go get github.com/go-xorm/[email protected]
go: finding github.com/go-xorm/xorm v0.7.5
go: finding github.com/jackc/pgx v3.3.0+incompatible
go: finding xorm.io/core v0.7.0
go: finding github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4
go: finding github.com/cockroachdb/apd v1.1.0
go: finding xorm.io/builder v0.3.5
go: finding github.com/jackc/fake v0.0.0-20150926172116-812a484cc733
go: finding github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24
go: finding github.com/ziutek/mymysql v1.5.4
go: finding github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a
go: finding golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468
go: finding google.golang.org/appengine v1.6.0
go: finding golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed
go: downloading github.com/go-xorm/xorm v0.7.5
go: extracting github.com/go-xorm/xorm v0.7.5
go: downloading xorm.io/builder v0.3.5
go: downloading xorm.io/core v0.7.0
go: extracting xorm.io/builder v0.3.5
go: extracting xorm.io/core v0.7.0

$ cat go.mod
module github.com/captain/modDemo

go 1.12

require github.com/go-xorm/xorm v0.7.5 // indirect

3.2 更新依赖库

通常下载一个包没有明确指定版本,那么下载的包就是当前的最新版本

我们还是拿 xorm 包作为示例

$ go get github.com/go-xorm/xorm
go: finding github.com/jackc/pgx v3.6.0+incompatible
go: finding xorm.io/builder v0.3.6
go: finding xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb
go: downloading github.com/go-xorm/xorm v0.7.9
go: extracting github.com/go-xorm/xorm v0.7.9
go: downloading xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb
go: downloading xorm.io/builder v0.3.6
go: extracting xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb
go: extracting xorm.io/builder v0.3.6
$ cat go.mod
module github.com/captain/modDemo

go 1.12

require (
        github.com/go-xorm/xorm v0.7.9 // indirect
        github.com/golang/protobuf v1.3.1 // indirect
        github.com/kr/pretty v0.1.0 // indirect
        github.com/satori/go.uuid v1.2.0 // indirect
        golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 // indirect
        golang.org/x/net v0.0.0-20190603091049-60506f45cf65 // indirect
        golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed // indirect
        golang.org/x/text v0.3.2 // indirect
        golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468 // indirect
)

我们看到了结果现在xorm 更新到了当前最新版本v0.7.9

那我可不可以更新到一个指定的版本呢?其实做法是一样的就是指定一个版本号就可以了

$ go get github.com/go-xorm/[email protected]
go: finding github.com/go-xorm/xorm v0.7.7
go: finding xorm.io/builder v0.3.6-0.20190906062455-b937eb46ecfb
go: downloading github.com/go-xorm/xorm v0.7.7
go: extracting github.com/go-xorm/xorm v0.7.7

$ cat go.mod
module github.com/captain/modDemo

go 1.12

require (
        github.com/go-xorm/xorm v0.7.7 // indirect
        github.com/golang/protobuf v1.3.1 // indirect
        github.com/kr/pretty v0.1.0 // indirect
        github.com/satori/go.uuid v1.2.0 // indirect
        golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 // indirect
        golang.org/x/net v0.0.0-20190603091049-60506f45cf65 // indirect
        golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed // indirect
        golang.org/x/text v0.3.2 // indirect
        golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468 // indirect
        xorm.io/builder v0.3.6 // indirect
        xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb // indirect
)

3.3 go get简介

go get 命令可以远程拉取更新代码包和依赖包,并自动完成编译和安装

go get 命令实际是分成了两步操作 1. 下载源码包 2.执行 go insert

简单的理解是 :

go get = git clone + go insert

这是一个常见的远程包的格式 : github.com/go-xorm/xorm

github.com 是网站域名

go-xorm 我们可以理解问作者或者机构名称

xorm 就是项目名称

go get 命令的具体详情可以查看它的帮助命令

对命令附带的可用参数有很详细的介绍

$ go help get
usage: go get [-d] [-m] [-u] [-v] [-insecure] [build flags] [packages]

Get resolves and adds dependencies to the current development module
and then builds and installs them.

The first step is to resolve which dependencies to add.

我们只看几个很常见的

-d 只下载,而不安装

-u 强制使用网络去更新包和它的依赖包

-v 显示执行的命令

-t 同时也下载需要为运行测试所需要的包

-fix 让命令程序在下载代码包后先执行修正动作,而后再进行编译和安装。

-x 打印安装的具体过程

-insecure 允许命令程序使用非安全的scheme(如HTTP)去下载指定的代码包

-f 仅在使用-u标记时才有效。该标记会让命令程序忽略掉对已下载代码包的导入路径的检查

你可能感兴趣的:(Golang)