golang系列的文章包含多篇文章,总篇如下,其中包含各篇文章的指引
前文中我们说到,若需要将整个项目共享给同事,那么需要将thirdparty中使用的依赖库摘选出来,然后打包给同事。当项目很多的时候,很难准确的摘选出那么多依赖库,所以golang就定义了vendor机制。同时,为了方便的进行依赖库的管理,golang还提供了go get命令。下面以此给出讲解。
vendor机制
前文中提到的是早期golang项目的依赖库的管理方法:将所有的项目的依赖库都统一放在同一个目录下,也就是说所有项目的依赖库都去同一个目录下寻找,这导致thirdparty目录下的库文件过多且不易管理。那么很自然的就想到,那我们干脆把各个项目的依赖库都放在自己的目录下不就OK了。每个项目管理自己的依赖库,虽然占用空间(可以忽略)且依赖库会重复,但是带来的便利性却是不言而喻的。鉴于此,golang团队定义了vendor机制,vendor翻译为供应商、摊贩,可以理解为依赖库的供应商,所以vendor目录可以理解为依赖库的仓库。程序在链接依赖库时,会按照以下顺序开始查找:
- 项目下的vendor目录
- GOROOT/src
- GOPATH/src
所以,我们在项目中基于vendor机制构建项目如下图所示。例如下图中,vendor目录中已经包含json库。
值得提醒的是,hello_world项目必须在GOPATH/src下,同时GOPATH必须已经添加到系统环境变量中,这个我们在前文中已经完成。所以,总结vendor机制就是:在系统环境变量中所包含的GOPATH目录下,构建我们的项目目录,并在项目目录中添加vendor目录用于管理项目的所有依赖库。如此一来,每个项目就有自己的vendor目录下就保存自己的依赖库了,如果需要将项目分享给别人,那直接将项目目录整个打包发送即可,例如将整个hello_world目录打包发送。
go get
好,既然有了存放依赖库的仓库,那么如何才能获取依赖库呢?golang团队提供了go get命令来完成依赖库的远程获取。类似Linux有apt-get,macOS有brew等,go get是golang自己的包下载命令。
go get命令能够远程拉取代码及其依赖包到本地,同时自动进行编译和安装。那go get如何和vendor机制协作的呢?先让我们回忆一下:Linux下的apt-get命令也实现自动安装程序,例如:
这条指令自动将nginx安装到/usr/share下,同学们可以尝试按照更多的程序,可以发现apt-get都将程序默认安装在/usr/share下。同样,go get命令也会将程序安装在某个目录下,这个目录就是我们添加的GOPATH下的src目录。只要我们使用go get命令获取依赖库,然后将下载得到的文件移动到项目中的vendor目录下,那么vendor机制保证链接依赖库时就会从vendor目录开始查找。例如
则我们会在go_project/src下得到mysql的文件,然后将其移动到go_project/src/vendor下即可。
govendor
虽然go get命令能够帮我们下载所需要的依赖库,但是依旧需要我们手动的copy到vendor目录,那有没有方法直接帮我们下载到vendor下呢?这就催生了很多第三方golang的包管理器,例如常用的govendor。相比于go get指令,govendor是一个比较完善的包管理器,go get只能算下载器而已。govendor提供下载,更新,移除、添加等多种管理命令。所以在项目中,我们一般使用govendor来管理所有的依赖库。
如果按照前文配置好环境,那么三分钟即可入门govendor。
1、安装govendor
这个命令是下载govendor到GOPATH/src下,同时可执行文件govendor会被自动安装到GOPATH/bin下。前文说过,该目录已经被添加到系统环境变量中,那么我们可以在任意目录下执行govendor命令。那为了在hello_world项目中利用govendor管理依赖库,我们需要在hello_world中使用govendor命令
2、需要在项目中初始化govendor,这将在vendor目录下生成vendor.json用于记录各个库的状态,大家感兴趣可以深入研究一下
3、初始化完成后,我们就能根据实际的项目需要下载依赖库了。例如我们需要mysql
这样我们就能在vendor下找到mysql,也能在项目中导入了。
至此,golang项目管理已经讲述完了。总结一下,在golang项目中,我们需要先将GOPATH和GOROOT的相关路径加入到系统环境中;然后构建所需的目录结构,并部署golang的第三方包管理器govendor;最后就可以进行开发了,同时可以利用govendor来完成库的管理。之后的文章计划将正式进入golang的语法学习阶段。