Golang vendor文件夹使用详解

olzhy · 2019-07-02 08:09:02 · 3375 次点击 · 预计阅读时间 3 分钟 · 大约8小时之前 开始浏览    
这是一个创建于 2019-07-02 08:09:02 的文章,其中的信息可能已经有所发展或是发生改变。

1 提出问题
我们知道,一个工程稍大一点,通常会依赖各种各样的包。而Go使用统一的GOPATH管理依赖包,且每个包仅保留一个版本。而不同的依赖包由各自的版本工具独立管理,所以当所依赖的包在新版本发生接口变更或删除时,会面临很多问题。 为避免此类问题,我们可能会为不同的工程设置不同的GOPATH,或者更改依赖包路径名称。这样手动维护起来也很头疼。


2 解决问题
Go 1.5引入了vendor文件夹,其对语言使用,go命令没有任何影响。若某个路径下边包含vendor文件夹,则在某处引用包时,会优先搜索vendor文件夹下的包。 在Go 1.5开启该项特性需设置GO15VENDOREXPERIMENT=1,而从Go 1.6开始,该项特性默认开启。


3 使用方式
3.1 vendor搜索方式 vendor包的搜索方式为:自包引用处,从其所在文件夹查询是否有vendor文件夹包含所引用包;若没有,然后从其所在文件夹的上层文件夹寻找是否有vendor文件夹包含所引用包,若没有,则再搜索上层文件夹的上层文件夹...,直至搜索至$GOPATH/src并搜索完成时止。 例如,如下代码中,$GOPATH/src/x/y/z/main.go引用了包"v",则不论vendor/v/v.go置于src/,src/x/,src/x/y/,src/x/y/z/中任意一个文件夹下,均可以找到。 $ cat $GOPATH/src/x/y/z/main.go

package main

import (
    "v"
)

func main() {
    v.V()
}

$ cat vendor/v/v.go

package v

import "fmt"

func V() {
    fmt.Println("I'm a vendor test")
}

$ go run main.go

I'm a vendor test
当vendor存在嵌套时,若不同的vendor文件夹包含相同的包,且该包在某处被引用,寻找策略仍遵循如上规则。即从包引用处起,逐层向上层文件夹搜索,首先找到的包即为所引,也就是从$GOPATH/src来看,哪个vendor包的路径最长,使用哪个。 如下代码中,$GOPATH/src/x/y/z/main.go所在工程有两个vendor文件夹(分别位于$GOPATH/src/x/vendor/v/,$GOPATH/src/x/y/z/vendor/v/)包含相同的包"v",目录树为: $ tree $GOPATH/src
src
 └ x
   ├ vendor
   │  └ v
   │     └ v.go
   └ y
     └ z
       ├ vendor
       │ └ v
       │    └ v.go
       └ main.go
$ cat $GOPATH/src/x/vendor/v/v.go
package v

import "fmt"

func V() {
    fmt.Println("I'm a vendor test, My path is x/vendor/v/")
}
$ cat $GOPATH/src/x/y/z/vendor/v/v.go
package v

import "fmt"

func V() {
    fmt.Println("I'm a vendor test, My path is x/y/z/vendor/v/")
}
输出为: $ go run main.go
I'm a vendor test, My path is x/y/z/vendor/v/
可以看到,真正调用的是$GOPATH/src/x/y/z/vendor/v/v.go。 3.2 vendor使用规约 使用vendor时,建议遵循如下两条规约。 a) 当欲将某包vendor时,可能想将所有依赖包均vendor; b) 尽量将vendor依赖包结构扁平化,不要vendor套vendor。 如下示例代码演示vendor扁平化使用。 main.go位于$GOPATH/src/github.com/olzhy/test下。
package main

import (
    "strings"
    "sync"
    "time"

    "github.com/z"
    "github.com/y"
    "golang.org/z"
)
...
$GOPATH/src/github.com/olzhy/test目录树。
├─ main.go
└─ vendor
    ├─ github.com
    │   ├─ x
    │   └─ y
    └─ golang.org
         └─ z

原文地址:https://leileiluoluo.com/posts/golang-vendoring.html


有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

3375 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传