drwf69817 2016-05-15 10:17
浏览 24
已采纳

我应该如何在Go 1.6中使用供应商?

First I have read this answer: Vendoring in Go 1.6, then I use it as my example.

My gopath is GOPATH="/Users/thinkerou/xyz/", and the follow like:

thinkerou@MacBook-Pro-thinkerou:~/xyz/src/ou$ pwd
/Users/baidu/xyz/src/ou
thinkerou@MacBook-Pro-thinkerou:~/xyz/src/ou$ ls
main.go vendor

Now, I use go get, then becomes this:

thinkerou@MacBook-Pro-thinkerou:~/xyz/src/ou$ ls
main.go vendor
thinkerou@MacBook-Pro-thinkerou:~/xyz/src/ou$ cd vendor/
thinkerou@MacBook-Pro-thinkerou:~/xyz/src/ou/vendor$ ls
vendor.json
thinkerou@MacBook-Pro-thinkerou:~/xyz/src/ou/vendor$ cd ../..
thinkerou@MacBook-Pro-thinkerou:~/xyz/src$ ls
github.com ou
thinkerou@MacBook-Pro-thinkerou:~/xyz/src$ cd github.com/
thinkerou@MacBook-Pro-thinkerou:~/xyz/src/github.com$ ls
zenazn

vendor.json is this:

{
    "comment": "",
    "package": [
        {
            "path": "github.com/zenazn/goji"
        }
    ]
}

then, I should use what commands? why have no use vendor? My go version is 1.6.2.

  • 写回答

1条回答 默认 最新

  • dongmuzhan4705 2016-05-15 12:20
    关注

    With Go1.6, vendoring is built in as you read. What does this mean? Only one thing to keep in mind:

    When using the go tools such as go build or go run, they first check to see if the dependencies are located in ./vendor/. If so, use it. If not, revert to the $GOPATH/src/ directory.

    The actual "lookup paths" in Go 1.6 are, in order:

    ./vendor/github.com/zenazn/goji
    $GOPATH/src/github.com/zenazn/goji
    $GOROOT/src/github.com/zenazn/goji
    

    With that said, go get will continue to install into you $GOPATH/src; and, go install will install into $GOPATH/bin for binaries or $GOPATH/pkg for package caching.

    So, how do I use ./vendor?!?!

    Hehe, armed with the knowledge above, it's pretty simple:

    mkdir -p $GOPATH/src/ou/vendor/github.com/zenazn/goji
    cp -r $GOPATH/src/github.com/zenazn/goji/ $GOPATH/src/ou/vendor/github.com/zenazn/goji
    

    In short, to use vendoring, you copy the files using the same github.com/zenazn/goji full path, into your vendor director.

    Now, the go build/install/run tooling will see and use your vendor folder.

    An easier way instead of copying everything manually

    Instead of finding and copying all 25+ vendor items, managing their versions, updating other projects etc... It would be better to use a dependency management tool. There are many out there and a little googling will point to you several.

    Let me mention two that works with the vendor folder and doesn't fight you:

    • godep
    • govendor

    In short, these tools will inspect your ou code, find the remote dependencies, and copy them from your $GOPATH/src to your $GOPATH/src/ou/vendor directory (actually, whatever current directory you are in when you run them).

    For example, say you have all of your dependencies installed and working normally in your $GOPATH/src/ou/ project using the normal GOPATH/src/github installation of your dependencies. Your project runs and your tests validate everything is working with the exact version of the repos you have. With Godep as an example, you'd run this from your project root folder $GOPATH/src/ou/:

    godep save ./...
    

    This would copy all dependencies your project uses into your ./vendor folder.

    Godep is by far and large the most popular. They have their own Slack channel on the Gopher Slack group. And, it's the one I use on my teams.

    Govendor is another alternative I read has a nice sync feature. I haven't used it though.

    Over Usage of Dependency Management Tool

    This is purely opinion, and I'm sure haters will downvote... But as I need to finish my blog post on the subject, let me mention here that most people worry too much about depdency management in Go.

    Yes, there is a need to lock in a repo to a version you depend on so you can ensure your system builds in production. Yes there is a need to ensure no breaking changes to a way a dependency is interrupting something.

    Use dependency management for those, absolutely.

    But, there is overuse of simple projects that lock in huge amounts of dependencies when in reality...

    You may only need to lock in only 1 dependencies; otherwise, you want the latest version of MySQL drivers and test assertion frameworks for bug fixes.

    This is where using the ./vendor/ folder apart from dependency managrment tools can really shine: you'd only need to copy that repo that need you lock in.

    You selectively pick the one misbehaving repo and put it into your ./vendor/ folder. By doing this, you are telling your consumers:

    Hey, this one repo needs to be held back at this revision. All others are fine and use the latest of those and update often with go get -u ./...; but, this one failed with newer versions so don't upgrade this one repo.

    But if blanketly saving all your dependencies with a dependency management tool, you are basically telling your consumers:

    There may or may not be a problem with one or more repos out of the 20 in the vendor folder. You may or may not be able to update them. You may or may not be able to get the latest MySQL driver. We simply don't know which may or may not be causing problems and just locked in something that worked at the time that I ran godep save. So yeah, upgrade at your own risk.

    Personally, I have ran into this several times. A dependency was updated with a breaking change, and we have dozens of repos dependent on it. Vendoring just that one repo in /vendor allows us to use that one version of dependency, while go get ./... continues to run normally for all other repos to get the latest. We run with the latest bug fixes in PSQL and MySQL and others (there are constant fixes for these!) and so on.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 iOS绕地区网络检测
  • ¥15 python验证码滑块图像识别
  • ¥15 根据背景及设计要求撰写设计报告
  • ¥15 QT6颜色选择对话框显示不完整
  • ¥20 能提供一下思路或者代码吗
  • ¥15 用twincat控制!
  • ¥15 请问一下这个运行结果是怎么来的
  • ¥15 单通道放大电路的工作原理
  • ¥30 YOLO检测微调结果p为1
  • ¥15 DS18B20内部ADC模数转换器