glide是一个golang的包管理工具,支持包版本管理,自动分析包依赖,用起来是很方便的。
但是glide使用时有一些项目结构规范需要遵循,下面记录一下关键点。
先翻墙
因为glide安装依赖是从github拖包下来的,所以需要给git配置一下环境变量,让它走我的shadowsocks代理,这样安装起来比较快。
1 2 |
git config --global http.proxy 'socks5://127.0.0.1:1080' git config --global https.proxy 'socks5://127.0.0.1:1080' |
另外,安装glide自身是通过curl完成的,所以需要给curl配置一下翻墙:
编辑~/.curlrc,添加如下内容:
1 |
socks5 = "127.0.0.1:1080" |
安装glide
首先,要export一下GOPATH环境变量,指向你的项目目录(包含src目录的那个目录),之后在GOPATH目录下建立一个bin目录。
之后,执行命令:
1 |
curl https://glide.sh/get | sh |
它会在$GOPATH/bin目录下创建一个二进制程序叫做glide,为了方便你可以考虑在环境变量PATH中加入$GOPATH/bin来方便的使用glide。
调整项目结构
glide要求项目按照一定的结构组织,即源代码全部放置在”$GOPATH/src/项目名称/”里面,举例来说:
我的GOPATH=/Users/smzdm/Documents/github/bigpipe,里面的内容如下:
1 2 3 4 5 6 7 8 |
liangdong:bigpipe smzdm$ pwd /Users/smzdm/Documents/github/bigpipe liangdong:bigpipe smzdm$ ll total 8 -rw-r--r-- 1 smzdm staff 3357 7 17 11:29 README.md drwxr-xr-x 3 smzdm staff 102 7 17 13:49 bin drwxr-xr-x 3 smzdm staff 102 7 17 09:29 conf drwxr-xr-x 3 smzdm staff 102 7 17 13:06 src |
bin里保存的就是刚才的glide程序:
1 2 3 4 5 6 7 8 9 |
liangdong:bigpipe smzdm$ ll total 8 -rw-r--r-- 1 smzdm staff 3357 7 17 11:29 README.md drwxr-xr-x 3 smzdm staff 102 7 17 13:49 bin drwxr-xr-x 3 smzdm staff 102 7 17 09:29 conf drwxr-xr-x 3 smzdm staff 102 7 17 13:06 src liangdong:bigpipe smzdm$ ll bin/ total 20456 -rwxr-xr-x 1 smzdm staff 10470228 7 17 13:49 glide |
而我的项目代码放在src/bigpipe之下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
liangdong:bigpipe smzdm$ ll src/bigpipe/ total 24 drwxr-xr-x 5 smzdm staff 170 7 17 13:21 client drwxr-xr-x 3 smzdm staff 102 7 17 13:19 config -rw-r--r-- 1 smzdm staff 269 7 17 13:14 glide.lock -rw-r--r-- 1 smzdm staff 122 7 17 13:11 glide.yaml drwxr-xr-x 4 smzdm staff 136 7 17 13:20 kafka drwxr-xr-x 4 smzdm staff 136 7 17 13:21 log -rw-r--r-- 1 smzdm staff 2084 7 17 13:34 main.go drwxr-xr-x 3 smzdm staff 102 7 14 15:47 proto drwxr-xr-x 4 smzdm staff 136 7 17 13:37 server drwxr-xr-x 3 smzdm staff 102 7 17 13:21 stats drwxr-xr-x 3 smzdm staff 102 7 14 09:28 util drwxr-xr-x 3 smzdm staff 102 7 17 13:14 vendor |
这基本是强制要求的(glide建议),GOPATH/src/项目名称 之内放置你的项目代码。
在程序中import包时,注意包的路径是从GOPATH/src开始的,也就是像这样引入config包:import “bigpipe/config”。
唯一可以放在src/bigpipe层级的就是main.go,令它属于package main即可。
glide安装项目
进入到GOPATH/src/bigpipe中,执行glide create来初始化glide项目。
它会分析你的程序引用了哪些外部包,并提供给你一些建议配置项,比如:选择包的版本等,我建议大家选择固定的依赖版本(不要包含任何版本区间),避免第三方包升级引入不可预期的问题。
之后它会在GOPATH/src/bigpipe中生成配置文件:glide.yaml,里面记录了项目依赖的外部包和版本等信息。
最后,执行glide install,它会根据glide.yaml中的依赖信息下载对应的包,全部保存到GOPATH/src/bigpipe/vender目录下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
liangdong:bigpipe smzdm$ ll total 24 drwxr-xr-x 5 smzdm staff 170 7 17 13:21 client drwxr-xr-x 3 smzdm staff 102 7 17 13:19 config -rw-r--r-- 1 smzdm staff 268 7 17 14:06 glide.lock -rw-r--r-- 1 smzdm staff 122 7 17 13:11 glide.yaml drwxr-xr-x 4 smzdm staff 136 7 17 13:20 kafka drwxr-xr-x 4 smzdm staff 136 7 17 13:21 log -rw-r--r-- 1 smzdm staff 2084 7 17 13:34 main.go drwxr-xr-x 3 smzdm staff 102 7 14 15:47 proto drwxr-xr-x 4 smzdm staff 136 7 17 13:37 server drwxr-xr-x 3 smzdm staff 102 7 17 13:21 stats drwxr-xr-x 3 smzdm staff 102 7 14 09:28 util drwxr-xr-x 3 smzdm staff 102 7 17 14:06 vendor liangdong:bigpipe smzdm$ ll vendor/ total 0 drwxr-xr-x 3 smzdm staff 102 7 17 14:06 github.com |
观察glide.yaml可以看见第一行写着package:bigpipe,其实这就是glide的一个规范而已,说明当前在GOPATH/src/bigpipe项目下。
编译项目
glide只能帮我们管理包,但是不负责编译项目。
我们知道go build命令可以编译项目,编译上述项目我们需要进入GOPATH/src/bigpipe目录中(项目源代码目录),然后执行go build即可。
在该目录下只有main.go属于package main,所以go build会以它为入口开始编译,产出的二进制名字与目录名一致叫做bigpipe。
第三方包保存在vender目录下,而代码引入的是import “github.com/xxxx…”,很显然GOPATH/src/github.com/xxxx…目录并不存在,那么go build为何可以编译通过呢?
这是golang 1.6之后的一个特性,也就是在引入包在src下找不到的情况下,会在vender目录中查找,这个查找的过程是(可以进一步阅读这里):
如果你是在src/a/b/c.go中引入了github.com/xxxx/yyyy包的话,它会依次在:
- src/a/b/vender/github.com/xxxx/yyyy
- src/a/vender/github.com/xxxx/yyyy
- src/vender/github.com/xxxx/yyyy
查找是否存在对应的包,所以上述bigpipe项目在GOPATH/src/bigpipe下使用glide安装了vender目录,所有bigpipe下的代码在引入github包时一定会扫描到GOPATH/src/bigpipe/vender,这就是glide的原理了。
一个例子
如果有疑惑可以参考这个项目作为例子:https://github.com/owenliang/bigpipe。