1. 程式人生 > >Golang官方依賴管理工具:dep

Golang官方依賴管理工具:dep

go golag dep

在這裏聲明一下,百度或者google看到的godep不是我這篇博文說的dep,那它們是什麽關系呢?按照Peter Bourgon博文來說,它們的作者都有相同的人,但是一個是dep是官方版本,godep是第三方工具。
我今天介紹的是dep,之前也有介紹過glide,有興趣的可以到Golang依賴管理工具:glide從入門到精通使用看看。 現在還有一個疑問是為什麽官方現在要支持依賴管理了呢?我個人認為有如下原因(勿噴,如果不同或者遺漏歡迎留言補充):

  • 第三方依賴管理很多,雖然很好用,但是很少可以兼容的,結果--亂;

  • 官方的包管理為了增加社區的凝聚力,保持Go開箱即用的簡單特性,不需要大家再安裝各種第三方工具了,而且第三方工具都會過來兼容官方版的;

  • 還有一個官話,為了go更好的發展;
    dep的FAQ中有一段描述depgo get 的網址,也是側面說了依賴管理工具和go get關系, 一句話概括:依賴管理工具是為應用管理代碼的,go get是為GOPATH管理代碼的。

下面進入教程。

介紹

dep是一個原型依賴管理工具,需要在Go 1.7及更高的版本中使用,說明第三方工具近期還是有市場的。
PS:本博客的dep基於v0.3。

安裝

環境準備。

//設置環境變量 使用vendor目錄GO15VENDOREXPERIMENT=1

安裝dep

等到dep正式集成到Golang中時候,也許是Golang 1.10 ,廣大吃瓜群眾就可以直接使用go dep命令。現在還是需要自己安裝的。

$ go get -u github.com/golang/dep/cmd/dep

驗證安裝

$ dep
dep is a tool for managing dependencies for Go projectsUsage: dep <command>Commands:  init    Initialize a new project with manifest and lock files
  status  Report the status of the project‘s dependencies
  ensure  Ensure a dependency is safely vendored in the project
  prune   Prune the vendor tree of unused packagesExamples:
  dep init                               set up a new project
  dep ensure                             install the project‘s dependencies
  dep ensure -update                     update the locked versions of all dependencies
  dep ensure -add github.com/pkg/errors  add a dependency to the projectUse "dep help [command]" for more information about a command.

有一個很重要的選項ensure中文含義是確保;保證;擔保,作者想傳達的意思是確保所有本地狀態-代碼樹、清單、鎖和供應商彼此同步

看到這個說明已經安裝好了。

使用

老規矩,篇幅有限,我只介紹經常使用到的。 先進入在GOPATH的一個項目中。

cd $GOPATH/src/foordep

初始化(dep init)

$ cd foordep/
$ dep init
$ ll
total 12
-rw-rw-r-- 1 qiangmzsx qiangmzsx  286 Aug  7 11:45 Gopkg.lock-rw-rw-r-- 1 qiangmzsx qiangmzsx  535 Aug  7 11:45 Gopkg.tomldrwxrwxr-x 2 qiangmzsx qiangmzsx 4096 Aug  7 11:45 vendor

大家發現了,應用foordep目錄下出現了兩個文件(Gopkg.lock、Gopkg.toml)和一個目錄(vendor)。 它們是什麽關系呢?
技術分享
所以出現Gopkg.toml and Gopkg.lock are out of sync.時候最好執行一下dep ensure

下面看看它們的內容。

$ cat Gopkg.lock 
# This file is autogenerated, do not edit; changes may be undone by the next ‘dep ensure‘.[solve-meta]
  analyzer-name = "dep"
  analyzer-version = 1
  inputs-digest = "ab4fef131ee828e96ba67d31a7d690bd5f2f42040c6766b1b12fe856f87e0ff7"
  solver-name = "gps-cdcl"
  solver-version = 1$ cat Gopkg.toml 

# Gopkg.toml example## Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md# for detailed Gopkg.toml documentation.## required = ["github.com/user/thing/cmd/thing"]# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]## [[constraint]]#   name = "github.com/user/project"#   version = "1.0.0"## [[constraint]]#   name = "github.com/user/project2"#   branch = "dev"#   source = "github.com/myfork/project2"## [[override]]#  name = "github.com/x/y"#  version = "2.4.0"

dep ensure

我們寫一個Gopkg.toml看看效果。

# 必需包required = ["github.com/astaxie/beego"]# 忽略包ignored = ["golang.org/x/crypto"]# 項目元數據[metadata]
homepage = "https://github.com/qiangmzsx"license = "MIT"owners_name_1 = "qiangmzsx"owners_email_1 = "[email protected]"owners_homepage_1 = "https://github.com/qiangmzsx"# 約束條件[[constraint]]
  name = "github.com/astaxie/beego"
  # 可選:版本
  version = "=1.8.0"
  # 分支
  #branch = "master"
  # 修訂
  #revision = "beego 1.8.0"
  # 可選:指定來源
  source = "github.com/astaxie/beego"

但是怎麽樣執行?可以執行如下命令尋找幫助:

$ dep help ensureUsage: dep ensure [-update | -add] [-no-vendor | -vendor-only] [-dry-run] [<spec>...]Project spec:

  <import path>[:alt source URL][@<constraint>]


Ensure gets a project into a complete, reproducible, and likely compilable state:

  * All non-stdlib imports are fulfilled
  * All rules in Gopkg.toml are respected
  * Gopkg.lock records precise versions for all dependencies
  * vendor/ is populated according to Gopkg.lock

Ensure has fast techniques to determine that some of these steps may be
unnecessary. If that determination is made, ensure may skip some steps. Flags
may be passed to bypass these checks; -vendor-only will allow an out-of-date
Gopkg.lock to populate vendor/, and -no-vendor will update Gopkg.lock (ifneeded), but never touch vendor/.

The effect of passing project spec arguments varies slightly depending on the
combination of flags that are passed.


Examples:

  dep ensure                                 Populate vendor from existing Gopkg.toml and Gopkg.lock
  dep ensure -add github.com/pkg/foo         Introduce a named dependency at its newest version
  dep ensure -add github.com/pkg/foo@^1.0.1  Introduce a named dependency with a particular constraintFor more detailed usage examples, see dep ensure -examples.

Flags:

  -add          add new dependencies, or populate Gopkg.toml with constraints for existing dependencies (default: false)
  -dry-run      only report the changes that would be made (default: false)
  -examples     print detailed usage examples (default: false)
  -no-vendor    update Gopkg.lock (if needed), but do not update vendor/ (default: false)
  -update       update the named dependencies (or all, if none are named) in Gopkg.lock to the latest allowed by Gopkg.toml (default: false)
  -v            enable verbose logging (default: false)
  -vendor-only  populate vendor/ from Gopkg.lock without updating it first (default: false)

執行一下

$ dep ensureall dirs lacked any go code

錯誤了,這是因為foordep目錄下沒有任何的go代碼,只能加上一個看看。

$ vim main.gopackage mainimport (    "github.com/astaxie/beego"
    "runtime")func main() {
    maxCPU := runtime.NumCPU()
    runtime.GOMAXPROCS(maxCPU)
    beego.Run()
}

再來試試看。

$ dep ensure$ ll vendor/
total 4drwxrwxr-x 3 qiangmzsx qiangmzsx 4096 Aug  7 16:29 github.com

看看Gopkg.lock的內容。

# This file is autogenerated, do not edit; changes may be undone by the next ‘dep ensure‘.[[projects]]
  name = "github.com/astaxie/beego"
  packages = [".","config","context","grace","logs","session","toolbox","utils"]
  revision = "323a1c4214101331a4b71922c23d19b7409ac71f"
  source = "github.com/astaxie/beego"
  version = "v1.8.0"[solve-meta]
  analyzer-name = "dep"
  analyzer-version = 1
  inputs-digest = "6fb93334da1b165aaab11f170d871a92b40033575e66e2cf4289e77e0d64551d"
  solver-name = "gps-cdcl"
  solver-version = 1

現在需要解析json,我們試試使用命令行的方式導入github.com/bitly/go-simplejson包。

$ dep ensure -add github.com/bitly/go-simplejson
$ Gopkg.lock
# This file is autogenerated, do not edit; changes may be undone by the next ‘dep ensure‘.[[projects]]
  name = "github.com/astaxie/beego"
  packages = [".","config","context","grace","logs","session","toolbox","utils"]
  revision = "323a1c4214101331a4b71922c23d19b7409ac71f"
  source = "github.com/astaxie/beego"
  version = "v1.8.0"[[projects]]
  name = "github.com/bitly/go-simplejson"
  packages = ["."]
  revision = "aabad6e819789e569bd6aabf444c935aa9ba1e44"
  version = "v0.5.0"[solve-meta]
  analyzer-name = "dep"
  analyzer-version = 1
  inputs-digest = "6fb93334da1b165aaab11f170d871a92b40033575e66e2cf4289e77e0d64551d"
  solver-name = "gps-cdcl"
  solver-version = 1

可以發現多了github.com/bitly/go-simplejson,但是Gopkg.toml並沒有任何改變。 註意:執行dep ensure -add時候報錯

$ dep ensure -add github.com/bitly/go-simplejson
Gopkg.toml and Gopkg.lock are out of sync. Run a plain dep ensure to resync them before attempting to -add

還可以指定依賴的版本:

$ dep ensure -add github.com/bitly/go-simplejson@=0.4.3

是因為Gopkg.tomlGopkg.lock不同步了,需要重新執行一下dep ensure即可。 重新整理一下Gopkg.toml

# 必需包
required = ["github.com/astaxie/beego"]
# 忽略包
ignored = ["golang.org/x/crypto"]
# 項目元數據
[metadata]
homepage = "https://github.com/qiangmzsx"license = "MIT"owners_name_1 = "qiangmzsx"owners_email_1 = "[email protected]"owners_homepage_1 = "https://github.com/qiangmzsx"# 約束條件[[constraint]]
  name = "github.com/astaxie/beego"
  # 可選:版本
  version = "=1.8.0"
  # 分支
  #branch = "master"
  # 修訂
  #revision = "beego 1.8.0"
  # 可選:指定來源
  source = "github.com/astaxie/beego"[[constraint]]
  name = "github.com/bitly/go-simplejson"
  branch = "master"
  source = "https://github.com/bitly/go-simplejson.git"

Gopkg.tomlversion規則: ~=version使用的操作符規則,如果僅僅是指定version = "1.8.0",那麽dep會自動加上^,表示最左邊的非零位的版本加一

^1.2.3 意味 1.2.3 <= X < 2.0.0^0.2.3 意味 0.2.3 <= X < 0.3.0^0.0.3 意味 0.0.3 <= X < 0.1.0

如果執行dep ensure時候出現

$ dep  ensure 
error while parsing /home/users/qiangmzsx/golang/src/foordep/Gopkg.toml: multiple constraints specified for github.com/astaxie/beego, can only specify one

說明配置寫錯了,需要看看Gopkg.toml文件中是不是同時配置了versionbranchrevision

空配置

我們現在嘗試著把foordep目錄情況就留下main.go

package mainimport (    "github.com/astaxie/beego"
    "github.com/bitly/go-simplejson"
    "runtime")func main() {    maxCPU := runtime.NumCPU()
    runtime.GOMAXPROCS(maxCPU)    strJson := `{"announcer": {"nickname": "非議講史", "kind": "user", "created_at": 1494904539000, "updated_at": 1494983507000, "track_id": 38088960}}`
    mapJson,_:=simplejson.NewJson([]byte(strJson))    println(mapJson)
    beego.Run()
}

執行dep ensure 為了更好地看到過程,加上參數-v

$ dep init -v
Root project is "foordep"
 1 transitively valid internal packages
 2 external packages imported from 2 projects
(0)    select (root)
(1)    ? attempt github.com/bitly/go-simplejson with 1 pkgs; 5 versions to try
(1)        try [email protected]
(1)     select [email protected] w/1 pkgs
(2)    ? attempt github.com/astaxie/beego with 1 pkgs; 23 versions to try
(2)        try [email protected]
(2)     select [email protected] w/9 pkgs
   found solution with 10 packages from 2 projects

Solver wall times by segment:
     b-list-versions: 3.926086724s
         b-list-pkgs: 285.209471ms
              b-gmal: 266.828805ms         select-atom:   3.417834ms
             satisfy:   3.126864ms         select-root:    428.276μs            new-atom:    234.106μs
               other:     45.014μs
     b-source-exists:      6.946μs
  b-deduce-proj-root:      3.472μs

  TOTAL: 4.485387512s  Using ^0.5.0 as constraint for direct dep github.com/bitly/go-simplejson
  Locking in v0.5.0 (aabad6e) for direct dep github.com/bitly/go-simplejson  Using ^1.8.3 as constraint for direct dep github.com/astaxie/beego
  Locking in v1.8.3 (cab8458) for direct dep github.com/astaxie/beego

此時再查看Gopkg.tomlGopkg.lock文件:

$ vim Gopkg.toml[[constraint]]
  name = "github.com/astaxie/beego"
  version = "1.8.3"[[constraint]]
  name = "github.com/bitly/go-simplejson"
  version = "0.5.0"$ vim Gopkg.lock[[projects]]
  name = "github.com/astaxie/beego"
  packages = [".","config","context","context/param","grace","logs","session","toolbox","utils"]
  revision = "cab8458c1c4a5a3b4bf5192922be620e6dede15b"
  version = "v1.8.3"[[projects]]
  name = "github.com/bitly/go-simplejson"
  packages = ["."]
  revision = "aabad6e819789e569bd6aabf444c935aa9ba1e44"
  version = "v0.5.0"[solve-meta]
  analyzer-name = "dep"
  analyzer-version = 1
  inputs-digest = "dc040fb12390d61768be6388ad2935bdd7f9cc93d4b1fdda421a284058277c80"
  solver-name = "gps-cdcl"
  solver-version = 1

glide一樣,具有自舉功能,不知道這個名詞用得對不對。dep會自動根據代碼生成Gopkg.tomlGopkg.lock配置文件。
PS:但是不建議使用,因為其拉取的依賴包都是最新的,可能出現不兼容,再者我國是一個被墻的地方。

dep cache

看到這裏時候很多人都會有疑問?dep的依賴包每一次都是拉取新的還是優先使用本地cache呢?可以肯定的是 dep也是有本地緩存的,大家可以打開$GOPATH/pkg/dep/看看,是不是存在呢!
下面我們做兩個測試看看。

$GOPATH/src不存在依賴包

環境準備,將原來的cache和vendor清空,別遺漏了$GOPATH/src中的github.com/bitly/go-simplejson

$ ll
total 4-rwxr--r-- 1 qiangmzsx qiangmzsx 990 Aug  7 16:39 main.go
$ vim main.go 
package mainimport (    "github.com/astaxie/beego"
    "github.com/bitly/go-simplejson"
    "runtime")

func main() {    maxCPU := runtime.NumCPU()
    runtime.GOMAXPROCS(maxCPU)    strJson := `{"announcer": {"nickname": "非議講史", "kind": "user", "updated_at": 1494983507000, "track_id": 38088960}}`
    mapJson,_:=simplejson.NewJson([]byte(strJson))
    println(mapJson)
    beego.Run()
}

執行dep init -gopath -v查看初始化過程。

$ ll
total 4
-rwxr--r-- 1 qiangmzsx qiangmzsx 382 Aug  8 12:47 main.go$ dep  init -gopath -v
Searching GOPATH for projects...
Following dependencies were not found in GOPATH. Dep will use the most recent versions of these projects.
  github.com/bitly/go-simplejson
Root project is "foordep"
 1 transitively valid internal packages 2 external packages imported from 2 projects
(0)    select (root)
(1)    ? attempt github.com/astaxie/beego with 1 pkgs; at least 1 versions to try
(1)        try [email protected]
(1)       Unable to update checked out version: fatal: reference is not a tree: 76ce912a30f9255d8d353d365ab99cb069fd29e0
(1)        try [email protected](1)     select [email protected] w/9 pkgs
(2)    ? attempt github.com/bitly/go-simplejson with 1 pkgs; 5 versions to try
(2)        try [email protected]
(2)     select [email protected] w/1 pkgs
   found solution with 10 packages from 2 projects

Solver wall times by segment:
         b-list-pkgs: 320.955115ms
              b-gmal: 274.950203ms
             satisfy:   8.179966ms         select-atom:    2.62224ms            new-atom:    392.168μs
     b-list-versions:    254.937μs         select-root:    209.152μs
  b-deduce-proj-root:      40.45μs
               other:      37.01μs
     b-source-exists:       5.83μs

  TOTAL: 607.647071ms  Using ^1.8.3 as constraint for direct dep github.com/astaxie/beego
  Locking in v1.8.3 (cab8458) for direct dep github.com/astaxie/beego  Using ^0.5.0 as constraint for direct dep github.com/bitly/go-simplejson
  Locking in v0.5.0 (aabad6e) for direct dep github.com/bitly/go-simplejson

日誌顯示,dep首先從$GOPATH查找github.com/bitly/go-simplejson,因為沒有找到才從網絡下載。

$GOPATH存在依賴包

環境準備,將原來的cache和vendor清空,註意$GOPATH/src中的github.com/bitly/go-simplejson存在。

$ ll
total 4
-rwxr--r-- 1 qiangmzsx qiangmzsx 382 Aug  8 12:47 main.go$ dep  init -gopath -v
Searching GOPATH for projects...
  Using master as constraint for direct dep github.com/bitly/go-simplejson
  Locking in master (da1a892) for direct dep github.com/bitly/go-simplejson
Root project is "foordep"
 1 transitively valid internal packages
 2 external packages imported from 2 projects
(0)    select (root)
(1)    ? attempt github.com/astaxie/beego with 1 pkgs; at least 1 versions to try
(1)        try [email protected]
(1)       Unable to update checked out version: fatal: reference is not a tree: 76ce912a30f9255d8d353d365ab99cb069fd29e0
(1)        try [email protected](1)     select [email protected] w/9 pkgs
(2)    ? attempt github.com/bitly/go-simplejson with 1 pkgs; at least 1 versions to try
(2)        try [email protected]
(2)     select [email protected] w/1 pkgs
   found solution with 10 packages from 2 projects

Solver wall times by segment:
         b-list-pkgs: 312.646734ms
              b-gmal: 265.066047ms
             satisfy:   6.488056ms         select-atom:   3.287416ms            new-atom:    397.837μs         select-root:    373.267μs
     b-list-versions:    108.466μs
               other:      47.43μs
     b-source-exists:       7.71μs
  b-deduce-proj-root:      6.568μs

  TOTAL: 588.429531ms  Using ^1.8.3 as constraint for direct dep github.com/astaxie/beego
  Locking in v1.8.3 (cab8458) for direct dep github.com/astaxie/beego

可以看到github.com/bitly/go-simplejson是優先從$GOPATH獲取的。 好處我個人認為有兩個:

  • 節省時間;

  • 本地類庫的穩定性和兼容性已經經過用戶驗證了。

dep v0.1時候還不需要手動加上-gopath選項,dep工具會自動判斷,但是dep v0.3後如果沒有加上-gopath那麽默認就是從網絡下載。

更新配置 (dep ensure -update)

現在修改foordep項目的Gopkg.toml內容為:

$ vim  Gopkg.toml
[[constraint]]
  name = "github.com/astaxie/beego"
  # 約束為1.8.0
  version = "=1.8.0"[[constraint]]
  name = "github.com/bitly/go-simplejson"
  version = "0.5.0"$ dep  ensure -update
Gopkg.toml and Gopkg.lock are out of sync. Run a plain dep ensure to resync them before attempting to -update$ dep  ensure $ dep  ensure -update -v
Root project is "foordep"
 1 transitively valid internal packages 2 external packages imported from 2 projects
(0)    select (root)
(1)    ? attempt github.com/astaxie/beego with 1 pkgs; 23 versions to try
(1)        try [email protected](2)       [email protected] not allowed by constraint 1.8.0:
(2)        1.8.0 from (root)
(1)        try [email protected](2)       [email protected] not allowed by constraint 1.8.0:
(2)        1.8.0 from (root)
(1)        try [email protected](2)       [email protected] not allowed by constraint 1.8.0:
(2)        1.8.0 from (root)
(1)        try [email protected](1)     select [email protected] w/8 pkgs
(2)    ? attempt github.com/bitly/go-simplejson with 1 pkgs; 5 versions to try
(2)        try [email protected](2)     select [email protected] w/1 pkgs
   found solution with 9 packages from 2 projects

Solver wall times by segment:
  b-source-exists:  4.00794324s
      b-list-pkgs: 2.545452669s
           b-gmal: 276.070372ms          satisfy:   5.179016ms
      select-atom:   4.337704ms
         new-atom:   1.359055ms
  b-list-versions:    467.799μs
        b-matches:    371.239μs
      select-root:    193.471μs
       b-pair-rev:    127.992μs            other:     25.962μs
   b-pair-version:      7.866μs  TOTAL: 6.841536385s$ dep status
PROJECT                         CONSTRAINT  VERSION  REVISION  LATEST   PKGS USED
github.com/astaxie/beego        1.8.0       v1.8.0   323a1c4   323a1c4  8  github.com/bitly/go-simplejson  ^0.5.0      v0.5.0   aabad6e   aabad6e  1

後記

看到了這裏,那麽對dep已經可以進行基本的使用了,不過目前而言,dep還不夠穩定,誰也不知道後續會怎麽樣更改,嘗鮮可以,個人還不建議使用在線上。 如果大家喜歡這篇博文請點贊或者留言,有不同見解的也請留言討論。


本文出自 “夢朝思夕” 博客,請務必保留此出處http://qiangmzsx.blog.51cto.com/2052549/1954603

Golang官方依賴管理工具:dep