简体   繁体   中英

How to avoid updating myself with `go get`

I have a package structure that looks like this:

GOPATH
   src
      github.com/myname
         mymainproject
            something.go //imports things from github
            mysubproject
               main.go //imports "github.com/myname/mymainproject" + others

As part of m build I run, go get -u -t ./.. from the main directory. This works great if building from master, but I have jenkins configured to build from any branch.

When building from another branch though, when it updates dependencies of mysubproject it updates the full working directory to master, which is very much not what I want.

I only have two real ideas that might work:

  1. After I run go get , check out the original branch that I want to build. I still worry that switching branches mid go-get could cause it to skip some dependencies that exist only in the branch, or fetch unnecessarily ones that exist only in master, so I'm not sure this is a good solution.
  2. Tag the current commit on the branch with the magic go1 tag. I believe this would have to be done on the remote as well, which makes it much less appealing.

Is there any way to prevent go-get from touching my main repository?

While I don't recommend go get -u as part of a production build (like Google, I recommend vendoring your packages so you can reproduce old builds and manage package versioning on branches), it's not that hard to get what you want with a small script using list and some filtering. Something like this should work:

go get -u -t `go list ./... | grep -v mysubproject`

That would exclude mysubproject . Or you could exclude mymainproject , or otherwise filter to get rid of whatever you don't want to update.

You should also look at godep to help you manage your dependencies and update them when you mean to.


UPDATE: You can take this to another level and explicitly list all the packages that you import:

go list -f '{{join .Imports "\n"}}' github.com/mymainproject/mysubproject | sort -u

This lists everything that mysubproject directly imports. You can filter out mymainproject and then update that list (which won't include mysubproject or mymainproject". This includes system packages, too, but those won't update, so it's ok (though you could filter them if you wanted).

Godep is currently adding a -r option that will rewrite imports, so you can vendor your dependencies into your tree, and import them as github.com/mymainproject/mysubproject/Godeps/_workspace/src/github.com/<package> . This is on the rewrite branch. The advantage of this approach is that it means your library uses the version you tested with rather than whatever version happens to be on the final consumer's machine. The downside is that the final consumer may wind up with multiple copies of the same package.

You should always take times like these to ask yourself if you really need the dependency in your library. Transitive dependencies have seemingly never-ending problems like these. You can work around them, and you should for a dependency that is really important to you, but I've more than once picked up the two functions I actually needed and copied them into my package to avoid a dependency. I'm not saying reusing code is bad; just make sure the cost is worth it in each case.

What appears to work for me is to not use go get -u as Rob suggests. Instead I make sure I fully clean my gopath before a build., then I can simply do a go get -t ./... to fetch all dependencies not already on disk.

This takes lokger to fetch all dependencies, but it works well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM