Go 包依賴管理工具 —— govendor

govendor 是一個基於 vendor 機制實現的 Go 包依賴管理命令行工具。與原生 vendor 無侵入性融合,也支持從其他依賴管理工具遷移,可以很方便的實現同一個包在不同項目中不同版本、以及無相互侵入的開發和管理。

vendor 特性

最開始的時候,Go 並沒有提供較爲妥當的包管理工具。從 1.5 版本開始提供了 vendor 特性,但需要手動設置環境變量 GO15VENDOREXPERIMENT=1

在執行 go buildgo run 命令時,會按照以下順序去查找包:

  • 當前包下的 vendor 目錄
  • 向上級目錄查找,直到找到 src 下的 vendor 目錄
  • 在 GOROOT 目錄下查找
  • 在 GOPATH 下面查找依賴包

在發佈 1.6 版本時,該環境變量的值已經默認設置爲 1 了,該值可以使用 go env 命令查看。

在發佈 1.7 版本時,已去掉該環境變量,默認開啓 vendor 特性。

vendor 使用建議

  • 一個庫工程(不包含 mainpackage)不應該在自己的版本控制中存儲外部的包在 vendor 目錄中,除非有特殊原因並且知道爲什麼要這麼做。
  • 在一個應用中,(包含 mainpackage),建議只有一個 vendor 目錄,且在代碼庫一級目錄。

govendor 簡介

govendor 是一個基於 vendor 目錄機制的包管理工具。

  • 支持從項目源碼中分析出依賴的包,並從 $GOPATH 複製到項目的 vendor 目錄下
  • 支持包的指定版本,並用 vendor/vendor.json 進行包和版本管理,這點與 PHP 的 Composer 類似
  • 支持用 govendor add/update 命令從 $GOPATH 中複製依賴包
  • 如果忽略了 vendor/*/ 文件,可用 govendor sync 恢復依賴包
  • 可直接用 govendor fetch 添加或更新依賴包
  • 可用 govendor migrate 從其他 vendor 包管理工具中一鍵遷移到 govendor
  • 支持 Linux,macOS,Windows,甚至現有所有操作系統
  • 支持 Git、Hg、SVN,BZR(必須指定一個路徑)

govendor 使用

要求:

  • 項目必須在 $GOPATH/src 目錄下
  • 如果 Go 版本爲 1.5,則必須手動設置環境變量 set GO15VENDOREXPERIMENT=1

安裝

go get -u github.com/kardianos/govendor

爲了方便快捷使用 govendor,建議將 $GOPATH/bin 添加到 PATH 中。Linux/macOS 如下設置:

export PATH="$GOPATH/bin:$PATH"

初始化

在項目根目錄下執行以下命令進行 vendor 初始化:

govendor init

項目根目錄下即會自動生成 vendor 目錄和 vendor.json 文件。此時 vendor.json 文件內容爲:

{
    "comment": "",
    "ignore": "test",
    "package": [],
    "rootPath": "govendor-example"
}

常用命令

  • 將已被引用且在 $GOPATH 下的所有包複製到 vendor 目錄
govendor add +external
  • 僅從 $GOPATH 中複製指定包
govendor add gopkg.in/yaml.v2
  • 列出代碼中所有被引用到的包及其狀態
govendor list
 e  github.com/gin-contrib/sse
 e  github.com/gin-gonic/gin
 e  github.com/gin-gonic/gin/binding
 e  github.com/gin-gonic/gin/internal/json
 e  github.com/gin-gonic/gin/render
 e  github.com/golang/protobuf/proto
 e  github.com/mattn/go-isatty
 e  github.com/ugorji/go/codec
 e  gopkg.in/go-playground/validator.v8
 e  gopkg.in/yaml.v2
pl  govendor-example
  m github.com/json-iterator/go
  m golang.org/x/sys/unix
  • 列出一個包被哪些包引用
govendor list -v fmt
 s  fmt
    ├──  e  github.com/gin-contrib/sse
    ├──  e  github.com/gin-gonic/gin
    ├──  e  github.com/gin-gonic/gin/render
    ├──  e  github.com/golang/protobuf/proto
    ├──  e  github.com/ugorji/go/codec
    ├──  e  gopkg.in/go-playground/validator.v8
    ├──  e  gopkg.in/yaml.v2
    └── pl  govendor-example
  • 從遠程倉庫添加或更新某個包(不會$GOPATH 也存一份)
govendor fetch golang.org/x/net/context
  • 安裝指定版本的包
govendor fetch golang.org/x/net/context@a4bbce9fcae005b22ae5443f6af064d80a6f5a55
govendor fetch golang.org/x/net/context@v1   # Get latest v1.*.* tag or branch.
govendor fetch golang.org/x/net/context@=v1  # Get the tag or branch named "v1".
  • 只格式化項目自身代碼(vendor 目錄下的不變動)
govendor fmt +local
  • 只構建編譯項目內部的包
govendor install +local
  • 只測試項目內部的測試案例
govendor test +local
  • 構建所有 vendor
govendor install +vendor,^program
  • 拉取所有依賴的包到 vendor 目錄(包括 $GOPATH 存在或不存在的包)
govendor fetch +out
  • 包已在 vendor 目錄,但想從 $GOPATH 更新
govendor update +vendor
  • 已修改了 $GOPATH 裏的某個包,現在想將已修改且未提交的包更新到 vendor
govendor update -uncommitted <updated-package-import-path>
  • Fork 了某個包,但尚未合併,該如何引用到最新的代碼包
govendor fetch github.com/normal/pkg::github.com/myfork/pkg

此時將從 myfork 拉取代碼,而不是 normal

  • vendor.json 中記錄了依賴包信息,該如何拉取更新
govendor sync

govendor 子命令

各子命令詳細用法可通過 govendor COMMAND -h 或閱讀 github.com/kardianos/govendor/context 查看源碼包如何實現的。

子命令 功能
init 創建 vendor 目錄和 vendor.json 文件
list 列出&過濾依賴包及其狀態
add $GOPATH 複製包到項目 vendor 目錄
update $GOPATH 更新依賴包到項目 vendor 目錄
remove vendor 目錄移除依賴的包
status 列出所有缺失、過期和修改過的包
fetch 從遠程倉庫添加或更新包到項目 vendor 目錄(不會存儲到 $GOPATH)
sync 根據 vendor.json 拉取相匹配的包到 vendor 目錄
migrate 從其他基於 vendor 實現的包管理工具中一鍵遷移
get go get 類似,將包下載到 $GOPATH,再將依賴包複製到 vendor 目錄
license 列出所有依賴包的 LICENSE
shell 可一次性運行多個 govendor 命令

govendor 狀態參數

狀態 縮寫 含義
+local l 本地包,即項目內部編寫的包
+external e 外部包,即在 GOPATH 中、卻不在項目 vendor 目錄
+vendor v 已在 vendor 目錄下的包
+std s 標準庫裏的包
+excluded x 明確被排除的外部包
+unused u 未使用的包,即在 vendor 目錄下,但項目中並未引用到
+missing m 被引用了但卻找不到的包
+program p 主程序包,即可被編譯爲執行文件的包
+outside 相當於狀態爲 +external +missing
+all 所有包

支持狀態參數的子命令有:listaddupdateremovefetch

Go modules

普大喜奔的是,從 Go 1.11 版本開始,官方已內置了更爲強大的 Go modules 來一統多年來 Go 包依賴管理混亂的局面(Go 官方之前推出的 dep 工具也幾乎胎死腹中),並且將在 1.12 版本中正式默認開啓。

目前已受到社區的看好和強烈推薦,建議新項目採用 Go modules。

參考


感謝您的閱讀,覺得內容不錯,點個贊吧 😆
原文地址: https://shockerli.net/post/go...
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章