GoLang: Vendor directory for github branches other than master

Using 3rd party packages from github is made very simple in the Go language with the import statement.  But one problem is that “go get” will always pull the HEAD of the master branch and there is no way to explicitly specify another branch.

The ultimate answer would be to use a package dependency manager like Glide, which I describe in this article.  But if you cannot introduce Glide into your workflow yet then manually populating the vendor directory (enabled by default since 1.6) is a viable alternative.

Example projects

I have created two Go projects on github, go-vendortest1 and go-myutil. The “vendortest” project calls the method in the “myutil” package as shown below:

package main

import (
	"fmt"
	"github.com/fabianlee/go-myutil/myutil"
)

func main() {
	fmt.Println("Version: ",myutil.GetBranch())
}

The “myutil” package is even simpler, and just returns a static string.

package myutil

func GetBranch() string {
  return "master"
}

If you build and run this project in the standard manner:

$ mkdir -p $GOPATH/src
$ cd $GOPATH/src
$ git clone https://github.com/fabianlee/go-vendortest1.git
$ cd go-vendortest1/vendortest
$ go get
$ go build
$ ./vendortest
Version: master

So far, everything is as expected and the 3rd party package is being pulled from the HEAD of the master branch.

Non-master branch

But, now take notice that the go-myutil package also has a second branch named “mybranch1“, and the ‘myutil/myutil.go‘ file is this branch just slightly altered to return the string ‘mybranch1’.

package myutil

func GetBranch() string {
  return "mybranch1"
}

However, this file is never going to be pulled by “go get” because it is not on the HEAD of the master branch.

Vendor directory

This is where the “vendor” directory comes into play.  If you create a directory named “vendor” under the project and manually put the “myutil” module inside, then it will be recognized first and used.

$ cd $GOPATH/src/go-vendortest1/vendortest

$ mkdir vendor

$ cd vendor

$ mkdir -p github.com/fabianlee

$ cd github.com/fabianlee

$ git clone https://github.com/fabianlee/go-myutil.git -b mybranch1

Notice that we are checking out the ‘mybranch1′ branch from github in the last command.

Now we need to rebuild the project and try again:

$ cd $GOPATH/src/go-vendortest1/vendortest
$ go get
$ go build
$ ./vendortest
Version: mybranch1

As you can see, we are now using the non-master ‘mybranch1’ version of the 3rd party package.

If you have a need for package management, I would suggest using Glide, which you can read more about in my article here.

 

REFERENCES

http://stackoverflow.com/questions/24855081/how-do-i-import-a-specific-version-of-a-package-using-go-get

https://golang.org/cmd/go/#hdr-Vendor_Directories

https://github.com/Masterminds/glide

http://blog.rommelrico.com/setting-up-the-vendor-branch-pattern-on-github/