golang包管理的古往今来

https://golang.org/

before GO1.5-GOPATH

在GO1.5之前用GOPATH以及GOROOT这两个环境变量来决定包的位置。

GOROOT就是告知当前go的安装位置,编译的时候从GOROOT去找sdk的system library。

GOPATH的目的是为了告知go,需要代码的时候,去哪里查找。注意这里的代码,包括本项目和引用外部项目的代码。GOPATH可以随着项目的不同而重新设置。 从go 1.8开始,如果GOPATH没有被设置,会有一个默认值,在Unix上为$HOME/go,在Windows上为%USERPROFILE%/go

GOPATH下会有3个目录:src, bin, pkg。

  • src目录:go编译时查找代码的地方
  • bin目录:go get、godep这种bin工具的时候,二进制文件下载的目的地
  • pkg目录:编译生成的lib文件存储的地方。

go允许import不同代码库的代码,例如github.com, k8s.io, golang.org等等;对于需要import的代码,可以使用 go get 命令取下来放到GOPATH对应的目录中去。例如go get github.com/silenceshell/hcache,会下载到$GOPATH/src/github.com/silenceshell/hcache中去,当其他项目在import github.com/silenceshell/hcache的时候也就能找到对应的代码了。

看到这里也就明白了,对于go来说,其实并不care你的代码是内部还是外部的,总之都在GOPATH里,任何import包的路径都是从GOPATH开始的;唯一的区别,就是内部依赖的包是开发者自己写的,外部依赖的包是go get下来的。

存在问题:

  • 不能区分版本,以至于令开发者以最后一项包名作为版本划分
  • 依赖 列表/关系 无法持久化到本地,需要找出所有依赖包然后一个个 go get
  • 只能依赖本地全局仓库($GOPATH/GOROOT),无法将库放置于局部仓库($PROJECT_HOME/vendor)

GO1.5-vendor

GO1.5使用vendor需要手动设置环境变量 GO15VENDOREXPERIMENT=1 ,GO1.6该环境变量默认设为1,在1.7版本时,已去掉该环境变量,默认开启vendor特性。

项目必须在$GOPATH/src目录下

在项目的目录下增加一个 vendor 目录来存放外部的包 , 在这种模式下,会将第三方依赖的源码下载到本地,不同项目下可以有自己不同的vendor。但是这样做又引入了新的问题,因为随着项目的依赖增多,代码库会越来越大,尤其很多带前端资源的项目,几十M到几百M都是很常见的,你的项目可以就依赖它某一点内容,但是却集成了全部资源。

go vendor的管理工具

  • godep
  • govendor
  • glide

go官方wiki给了一个比较全面的对比

godep更直观,使用者也多一些,一些个人的小项目可以用;glide功能更丰富,更接近maven(例如glide.lock跟maven的pom.xml比较类似,可以指定获取某一个版本),新的项目可以考虑使用glide。

GO1.11-go modules

基于vgo演变而来,是Golang官方的包管理工具。

configure

目前Modules并不是默认启用的,可以通过环境变量GO111MODULE开启或者关闭,它有三个可选值:off、on、auto,默认值是 auto。

  1. off。关闭支持,go 会从GOPATH和vendor文件夹寻找包。
  2. on。开启支持,go 会忽略 GOPATH 和 vendor 文件夹,只根据go.mod下载依赖。
  3. auto。当项目在$GOPATH/src,且项目根目录有go.mod文件时,开启模块支持,否则依旧使用GOPATH以及vendor。

go modules使用:

add dependencies

go mod init example.com/hello

go mod命令生成一个go.mod文件,go.mod文件出现在模块的根目录中。 子目录中的程序包具有由模块路径以及子目录路径组成的导入路径。 例如,如果我们创建了一个子目录world,则无需(也不希望)在那里运行go mod init。 该软件包将自动被识别为example.com/hello模块的一部分,导入路径为example.com/hello/world

go命令使用go.mod中列出的特定依赖项模块版本来解析导入。 当遇到未由go.mod中的任何模块提供的包的导入时,go命令将自动使用最新版本查找包含该软件包的模块,并将其添加到go.mod中。 (“最新”定义为最新的标记稳定(非预发行)版本,或者最新的标记预发行版本,或者最新的未标记版本。)在我们的示例中,go test将新的导入rsc.io/quote解析为 rsc.io/quote v1.5.2模块 它还下载了rsc.io/quote使用的两个依赖项,即rsc.io/samplergolang.org/x/text仅直接依赖项记录在go.mod文件中。

go modules 下载的包在 GOPATH/pkg/mod,这就是前面所说的 ‘maven way’;安装的命令仍在 $GOPATH/bin

除了go.mod之外,go命令还会维护一个名为go.sum的文件,其中包含特定模块版本内容的预期 cryptographic hashes

go命令使用go.sum文件来确保这些模块的将来下载与第一次下载时检索的位相同,以确保您的项目所依赖的模块不会由于恶意,意外或其他原因而意外更改。 应该将go.mod和go.sum都检查到版本控制中。

go list -m all  # 列出当前的所有模块以及依赖

update dependencies

版本的表示使用语义版本标签,包括三部分:major;minor;patch。例如v0.2.1,major就是0,minor就是2,patch就是1.

  对于minor级别上的升级: 

go get golang.org/x/text  # 自动下载最新版本

  可能会通过,可能出现版本不兼容,

go list -m -versions rsc.io/sampler # 列出此模块可获得的标签版本
go get rsc.io/[email protected]3.1 # 下载相应的版本,注意用@再加版本信息,不加版本信息默认@latest

  对于major级别上的升级:

  Go模块的每个不同的主要版本(v1,v2等)都使用不同的模块路径:从v2开始,该路径必须以主要版本结尾。在示例中,rsc.io/quote的v3不再是rsc.io/quote:而是由模块路径rsc.io/quote/v3标识。此约定称为语义导入版本控制,它为不兼容的程序包(具有不同主要版本的程序包)提供了不同的名称。相反,rsc.io/quote的v1.6.0应该与v1.5.2向后兼容,因此它重用了名称rsc.io/quote。 (在上一节中,rsc.io/sampler v1.99.99应该已经与rsc.io/sampler v1.3.0向后兼容,但是关于模块行为的错误或错误的客户端假设都可能发生。)

  go命令允许构建最多包含任何特定模块路径的一个版本,即每个major版本至多:一个rsc.io/quote,一个rsc.io/quote/v2,一个rsc.io/quote/ v3,依此类推。这为模块作者提供了关于可能重复单个模块路径的明确规则:程序无法同时使用rsc.io/quote v1.5.2和rsc.io/quote v1.6.0来构建。同时,允许模块的不同major版本(因为它们具有不同的路径)使模块使用者可以逐步升级到新的主要版本。在此示例中,我们想使用rsc / quote / v3 v3.1.0中的quote.Concurrency,但尚未准备好迁移rsc.io/quote v1.5.2的使用。在大型程序或代码库中,增量迁移的能力尤其重要。

remove unused dependencies

尽管有的模块我们可能不使用了,但是go list -m all还是会显示,以及在go.mod中也会有,不会自动删除。仅在检查模块中的所有软件包以及这些包的所有可能的构建标记组合之后,才能删除依赖项。 普通的build命令不会加载此信息,因此它不能安全地删除依赖项。

go mod tidy # 清除未使用的模块

参考内容:

https://ieevee.com/tech/2017/07/10/go-import.html

http://www.sohu.com/a/330500438_470018

https://blog.golang.org/using-go-modules

https://juejin.im/post/5c6ac37cf265da2de7134242

原文地址:https://www.cnblogs.com/vert/p/golangPackageManage.html

时间: 2024-08-29 08:57:19

golang包管理的古往今来的相关文章

window下golang包管理glide使用说明

golang是一门简洁高效的开发 语言,但是包管理一直是一个痛点,如图 : 很多开源项目特别是github.com中的大量应用golang.org和google.golang.org中的源码,且由于被墙的原因也会导致各种不顺利,复制GOPATH里内容在团队人比较多的时候较复杂 包之前关系复杂,无法确切的知道自己包里引用哪些项目源,甚至可能有 一些被误删导致的问题 无法准确管理引用包源的版本,可能会导致一些项目编译不通过 不像java里有maven或者jar.donet里有dll文件等等,让使用方

Golang包管理工具之govendor的使用

1. govendor简介 golang工程的依赖包经常使用go get命令来获取,例如:go get github.com/kardianos/govendor ,会将依赖包下载到GOPATH的路径下. 常用的依赖包管理工具有godep,govendor等,在Golang1.5之后,Go提供了 GO15VENDOREXPERIMENT 环境变量(Go 1.6版本默认开启该环境变量),用于将go build时的应用路径搜索调整成为 当前项目目录/vendor 目录方式.通过这种形式,我们可以实现

告别GOPATH,快速使用 go mod(Golang包管理工具)

https://studygolang.com/articles/17508?fr=sidebar 文中的wserver为module名,route为本地的包名,go.mod所在的目录名不一定非要和module名一致,把wserver文件夹重命名为其他的名称也可以,只要go mod init wserver,就import "wserver/本地包名" 原文地址:https://www.cnblogs.com/answercard/p/10605542.html

Golang学习--包管理工具glide

上一篇文章中我们已经成功的运行了go的代码,这是我们迈出的最基础的一步. 一个项目通常会依赖很多外部的库,当依赖的库比较多的时候,手工管理就会比较麻烦,这个时候就需要包管理工具出场了,帮你管理好所有依赖的库. php项目中使用composer,javascript项目中使用npm,那么在go项目中,我们需要使用什么? 包依赖工具的选择 当前go的包管理工具有glide.godep.govendor和gvt等,相关对比的文章可以查看<go依赖包管理工具对比>. 功能对比可以参考如下内容(虽然跟上

理解Golang包导入

转自:http://tonybai.com/2015/03/09/understanding-import-packages/ Golang使用包(package)这种语法元素来组织源码,所有语法可见性均定义在package这个级别,与Java .python等语言相比,这算不上什么创新,但与C传统的include相比,则是显得“先进”了许多. Golang中包的定义和使用看起来十分简单: 通过package关键字定义包: package xxx 使用import关键字,导入要使用的标准库包或第

go包管理之glide

go语言的包是没有中央库来统一管理的,通过使用go get命令从远程代码库(github.com,goolge code 等)拉取,直接跳过中央版本库的约束,让代码的拉取直接基于源代码版本控制库,开发者间的协同直接依赖于源代码的版本控制.直接去除了库版本的概念.没有明显的包版本标识,感觉还是有点不适应,官方的建议是把外部依赖的代码全部复制到自己可控的源代码库中,进行统一管理,从而做到对依赖包的可控管理. 1.5版本的vendor目录特性后,官方wiki推荐了多种支持这种特性的包管理工具如:God

golang项目git-subtree完美解决差异包管理

目标: 1.把golang官方已移动过url的包跟随自己的项目git代码上传到项目源码中. 2.把或自己修改过的差异化fork包跟随自己的项目git代码上传到项目源码中. 解决方案: 方案1.第三方包管理 http://tleyden.github.io/blog/2016/02/08/adding-vendoring-to-a-go-project/ 方案2.手动处理过程 a.在项目根目录下创业文件夹 "/vendor/src" b.通过git-subtree下拉包到上一步目录下,红

亲测可用的golang sql例程与包管理

sqlite与golang package main import ( "database/sql" "fmt" "time" _ "github.com/mattn/go-sqlite3" ) func main() { //打开数据库,如果不存在,则创建 db, err := sql.Open("sqlite3", "./foo.db") checkErr(err) //创建表 sq

Golang高阶:Golang1.5到Golang1.12包管理

Golang1.5到Golang1.12包管理 1. 前言 Golang 是一门到如今有十年的静态高级语言了,2009年的时候算是正式推出了,然后到最近的一两年,2017-2018年的时候,突然直线上升,爆火了,得益于容器化运维/直播/短视频/区块链... Golang 语法简单,简单即是复杂,软件构建的核心在于将复杂的东西简单化,处理好复杂度. 作为一个 gopher,我们要知道他的包管理,这样才能合理化代码结构,做好工程管理.(gopher:地鼠) 2. GOPATH/ Golang 1.5