Go和依赖管理
请将以下内容以中文为母语的方式改写,只需要一种选择:
お題
据悉,对于Go语言来说,版本管理和依赖包管理(有时也称之为版本控制)一直是一个长期的问题。类似于“Go没有泛型!”这样的热门讨论,关于这个问题的争论屡见不鲜。
在这些讨论中,目前可供尝试的最新工具是称为“Go module”的东西。
根据我的经验,在Go语言的1.7和1.9版本中,我使用过一些vendoring工具,比如glide和dep。
个人而言,我对这些工具没有太大的不满(当然也遇到了一些问题,实际情况下可能也会遇到类似的挑战,无论使用哪个工具都一样),但如果官方能提供(dep本身也是为了让Go语言拥有vendoring(版本控制)功能而开发的实验性工具)一个工具,我仍然更倾向于使用官方提供的工具。
所以,让我们尝试使用Go模块,顺便回顾一下我之前使用的工具方法。
开发环境。
操作系统
You only need one option, right?
你只需要一个选项,对吗?
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="17.10 (Artful Aardvark)"
# Go语言
$ go version
go version go1.11.2 linux/amd64
版本的切换是通过goenv来实现的。
实践
■使用GOPATH解决依赖包
试行源代码如下:
https://github.com/sky0621/go-modules/tree/4f5e5a5187c79413550655c9620d539923c65615
在环境变量中设置GOPATH。
$ env | grep GOPATH
GOPATH=/work/src/golang
将源代码放置在GOPATH下
$ pwd
/work/src/golang/src/github.com/sky0621/go-modules
$ tree
.
├── cmd
│ └── main.go
└── rootpackage.go
主要.go
执行同一项目中不同包的函数”github.com/sky0621/go-modules”。
同时,执行另一个项目(github.com/satori/go.uuid)的函数。
请确保将上述内容放置在GOPATH下通过命令$ go get github.com/satori/go.uuid进行安装。
package main
import (
"fmt"
"github.com/sky0621/go-modules"
uuid "github.com/satori/go.uuid"
)
func main() {
fmt.Println("Hello, World!")
modules.SayBye()
u1 := uuid.Must(uuid.NewV4())
fmt.Printf("UUIDv4: %s\n", u1)
}
执行结果。
$ pwd
/work/src/golang/src/github.com/sky0621/go-modules/cmd
$ go run main.go
Hello, World!
Bye!
UUIDv4: 2a601fdb-fe9d-49e7-81b8-15b554d2e42e
备考
我从来没有使用GOPATH指定的方式来构建和部署产品。
例如,如果使用Kubernetes(或者即使不用Kubernetes,只使用Docker容器),可能需要在Dockerfile中设置GOPATH,并且还要添加一系列外部依赖包的”go get”语句。然后,将其编译成可执行文件。
在 Glide(一个用于管理依赖包的工具)中解决依赖包的问题。
举例来说,如果在GOPATH目录下没有应用程序使用的包,则在运行go run时将会出现错误。
$ env | grep GOPATH
GOPATH=/work/src/golang
$ ll /work/src/golang/src/github.com/satori
ls: '/work/src/golang/src/github.com/satori' にアクセスできません: そのようなファイルやディレクトリはありません
$ pwd
/tmp/go-modules/cmd
$
$ go run main.go
main.go:8:2: cannot find package "github.com/satori/go.uuid" in any of:
/home/koge/.goenv/versions/1.11.2/src/github.com/satori/go.uuid (from $GOROOT)
/work/src/golang/src/github.com/satori/go.uuid (from $GOPATH)
main.go:6:2: cannot find package "github.com/sky0621/go-modules" in any of:
/home/koge/.goenv/versions/1.11.2/src/github.com/sky0621/go-modules (from $GOROOT)
/work/src/golang/src/github.com/sky0621/go-modules (from $GOPATH)
安装和应用glide
安装
$ curl https://glide.sh/get | sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 4833 100 4833 0 0 1611 0 0:00:03 0:00:03 --:--:-- 1294
〜〜〜 省略 〜〜〜
Downloading https://github.com/Masterminds/glide/releases/download/v0.13.2/glide-v0.13.2-linux-amd64.tar.gz
glide version v0.13.2 installed successfully
适用 – shì
$ pwd
/tmp/go-modules
$
$ glide init
[INFO] Generating a YAML configuration file and guessing the dependencies
〜〜〜 省略 〜〜〜
[INFO] Writing updates to configuration file (glide.yaml)
[INFO] You can now edit the glide.yaml file.:
[INFO] --> For more information on versions and ranges see https://glide.sh/docs/versions/
[INFO] --> For details on additional metadata see https://glide.sh/docs/glide.yaml/
确认生成文件
$ tree
.
├── cmd
│ └── main.go
├── glide.yaml
└── rootpackage.go
glide.yaml的内容
$ cat glide.yaml
package: .
import:
- package: github.com/satori/go.uuid
version: ~1.2.0
- package: github.com/sky0621/go-modules
依赖包的打包
$ glide up
[INFO] Downloading dependencies. Please wait...
[INFO] --> Fetching github.com/sky0621/go-modules
[INFO] --> Fetching github.com/satori/go.uuid
[INFO] --> Detected semantic version. Setting version for github.com/satori/go.uuid to v1.2.0
[INFO] Resolving imports
[INFO] Downloading dependencies. Please wait...
[INFO] Setting references for remaining imports
[INFO] Exporting resolved dependencies...
[INFO] --> Exporting github.com/sky0621/go-modules
[INFO] --> Exporting github.com/satori/go.uuid
[INFO] Replacing existing vendor dependencies
[INFO] Project relies on 2 dependencies.
glide.lock已生成并在vendor目录下获取了依赖包的源代码。
$ tree
.
├── cmd
│ └── main.go
├── glide.lock
├── glide.yaml
├── rootpackage.go
└── vendor
└── github.com
├── satori
│ └── go.uuid
│ ├── LICENSE
│ ├── README.md
│ ├── codec.go
│ ├── codec_test.go
│ ├── generator.go
│ ├── generator_test.go
│ ├── sql.go
│ ├── sql_test.go
│ ├── uuid.go
│ └── uuid_test.go
└── sky0621
└── go-modules
├── README.md
├── cmd
│ └── main.go
└── rootpackage.go
滑行锁定
$ cat glide.lock
hash: 450d4cce664d8e157d796b280456c6e33dbcf1a6529a42bd413a990516ba6bef
updated: 2018-11-19T01:58:50.856499847+09:00
imports:
- name: github.com/satori/go.uuid
version: f58768cc1a7a7e77a3bd49e98cdd21419399b6a3
- name: github.com/sky0621/go-modules
version: 4f5e5a5187c79413550655c9620d539923c65615
testImports: []
如果对这个文件进行源代码管理,即使在某个时刻由于依赖关系的问题导致构建失败,也可以恢复到正常的状态。
* 如果只有glide.yaml文件,因为根据设定,次要版本或补丁版本可能会在执行glide up命令时升级到指定版本,所以修复依赖关系可能会变得困难。
好的,现在进行操作确认。
在GOPATH之外尝试
$ pwd
/tmp/go-modules/cmd
$
$ go run main.go
main.go:8:2: cannot find package "github.com/satori/go.uuid" in any of:
/home/koge/.goenv/versions/1.11.2/src/github.com/satori/go.uuid (from $GOROOT)
/work/src/golang/src/github.com/satori/go.uuid (from $GOPATH)
main.go:6:2: no Go files in /work/src/golang/src/github.com/sky0621/go-modules
哎呀???
嗯,看起来,在glide中,如果源代码不在GOPATH目录下,最终无法使用vendoring。
参考:https://qiita.com/mom0tomo/items/b66203b2718dd2626fd3#glideで何が問題になるのか-confused
在GOPATH目录下尝试一下
$ pwd
/work/src/golang/src/github.com/sky0621/go-modules/cmd
$
$ go run main.go
Hello, World!
Bye!
UUIDv4: 46225e42-8129-47de-b284-146d16d7a948
可以行。
暫時,我確認了在GOPATH下的main.go所引入的「github.com/satori/go.uuid」不存在,但好像最終還是依賴於GOPATH。
试验源代码如下:
https://github.com/sky0621/go-modules/tree/94e18719957dc74129667a0fb95b286e9169f08a
■使用Vendoring(依赖)解决依赖包问题。
安装和应用dep。
请安装
$ curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
〜〜〜 省略 〜〜〜
Setting executable permissions.
Moving executable to /work/src/golang/bin/dep
在GOPATH之外生效
$ pwd
/tmp/go-modules
$
$ dep init
init failed: unable to detect the containing GOPATH: /tmp/go-modules is not within a known GOPATH/src
哎呀,看来只有在GOPATH内才行啊,dep才有效。
在GOPATH中应用
$ pwd
/work/src/golang/src/github.com/sky0621/go-modules
$
$ dep init
Using ^1.2.0 as constraint for direct dep github.com/satori/go.uuid
Locking in v1.2.0 (f58768c) for direct dep github.com/satori/go.uuid
Gopkg.toml和Gopkg.lock已生成,获取了依赖包源码并放置在vendor目录下。
$ tree
.
├── Gopkg.lock
├── Gopkg.toml
├── cmd
│ └── main.go
├── rootpackage.go
└── vendor
└── github.com
└── satori
└── go.uuid
├── LICENSE
├── README.md
├── codec.go
├── generator.go
├── sql.go
└── uuid.go
现在,让我们来确认一下操作吧。
$ pwd
/work/src/golang/src/github.com/sky0621/go-modules/cmd
$
$ go run main.go
Hello, World!
Bye!
UUIDv4: b5e4a50f-b1bc-4044-8bc5-cea56d770992
试行源代码如下:
https://github.com/sky0621/go-modules/tree/0e9b65282b80d3064528baf13c464e35e95bb573
概述
因为时间已经用完了,所以试用Go模块将会在下次。
顺便提一下,虽然不是真正写代码试用,但是这里记录了关于Go和版本控制的历史信息。(英文)
有翻译这段内容的Qiita文章,真厉害。