James Scott

7 minute read

I’ve been tinkering around with Go for a while. Occasionally, I would just get distracted with something else. However, every time I come back to Go, I’m always excited to see the new tools and how much has improved since the last time. One of the biggest gripes I had with Go was the necessity to modify your GOPATH if you ever wanted to jump from one major project to another. This post will walkthrough my (re)setup of Go, useful tools, and talk about any great workflow.

The Go Gopher!

(Photo by Noah Lorang.)

Table of Contents

  • Go Version Manager (GVM)
  • Vim-go
  • Go Versioning Packager (GVP)
  • Go Package Manager (GPM)
  • Workflows
  • Next post

##

Go Version Manager

This cool tool, as you can imply from the name, manages the versions of Go you use. This is very helpful for when you want to make reproducible builds despite Go updating itself every ~6 months.   Installing GVM Follow the steps here to install GMV for your environment: https://github.com/moovweb/gvm   Using GVM Install latest go.

gvm install go1.3

That takes a while. Do not panic.

You can see my existing go installation was labeled ‘system’. (it is version 1.2 fyi) But now, I can easily switch. Since 1.3 has come out since the last time I used it, lets go ahead and update which one I use by default.

Now, whenever I open a terminal, 1.3 will be used.

Vim-go

Another pain that any developer can relate to is having a decent development editor / IDE. Previously, I have tried Goclipse and LiteIde. LiteIde didn’t have enough bells and whistles. Goclipse uses eclipse, so it’s a memory hog. (I like to take breaks to watch videos and play games without closing windows)   Refer to https://github.com/fatih/vim-go for the how-to  install for your system. I use Pathogen when it comes to plugins for vim, worked fine for me this time as well.   Two edits that I added to my .vimrc are the following:

  • Commented of the autocmd for Fmt. (I was getting some error every time I saved)
  • And then I set this go_fmt_autosave  to 0 to make sure Fmt didn’t run every time I saved.

Update 10-14

After installing vim-go, it’s important to use :GoInstallBinaries from within vim-go to make sure you get all the tools AND do it after installing Go Versioning Packager (GVP; the next step below) to ensure the binaries are stored in the right $GOBIN

Go Versioning Packager

Earlier I mentioned my gripe about having to manually set your GOPATH accordingly if you wanted to switch between projects in Go. Go Versioning Packager (GVP) solves that problem marvelously.

gvp init
# creates go ".godeps" folder within your workspace.

This folder will contain all the source and compiled libraries / executables for your dependencies that you can download into your project.

source gvp in
# will set your GOPATH, GOBIN, and GOROOT variables appropriately.
# (source gvp out restores your  old GOPATH, GOBIN, and GOROOT)

If you ever look at the GOPATH  variable, you will see that there are actually two folders: GOPATH=/.godeps: This is how Go is able to separate the libraries you download from your own source as mentioned earlier. The first folder (.godeps in our case) will always be the destination for any external libraries. So now you can subject the second folder to version control like Git but still not have external code pollute your repository by excluding the .godeps folder from version control. In this simple example, we will do a hello world example as described here: http://golang.org/doc/code.html#Command

Tada, it works!

Weird that bin folder is named “bin:” instead of “bin” Let’s see what’s going on.

On github, latest is 1.0.  I’m sure they had to have fixed this weird problem. Looking through the github commits, I found the culprit! There was a fix for this weird typo in the GOBIN environment variable.

Need to run:

brew update
brew unlink gvp
brew install gvp

This should install the right version of gvp. Delete your .godeps

rm -rf .godeps

Back through the steps..

gvp init
source gvp in

We are in good shape now. Now with my slightly modified program…

(GOTCHAS: It’s important that the package name is main and we have a main function so that it can produce the executable) .. We can go ahead and run “go install”. I’m choosing to run from the root of my workspace.  However, that doesn’t really matter. “Go install” can be ran from two locations 1) The current directory of the project “go install .” and 2) anywhere else “go install ”. That’s just another GOTCHA. Which actually means you can’t do tab auto-complete to get to the path in case you happened to be in root of your workspace. Go is smart enough that it can pick projects out of your GOPATH/src folder. “go install src/github.com/jcscottiii/hello” won’t work and will complain about being unable to find packages because $GOPATH/src/src/ does not even exist and should not. “go install github.com/jcscottiii/hello” will work though.

Now to run it:

Go Package Manager

I just mentioned GVP helps separate external code from your code. Now, let say developer 1 uses library A and builds an application. A week later, developer 2 is introduced to the project while developer 1 is on vacation. Practicing good version control, there should be just should just be their source code and not the external code. Go has a handy feature where developer 2 can just run “go get” and it will download all the latest versions of the external packages that their application uses (and if GVP is setup, it will download them to the untracked .godeps folder). Developer 2, runs “go build” and stuff starts to break. Errors like missing functions and variables. This is a classic example of  how external libraries can become outdated and break your code that rely upon them. As of now, out of the box, Go has no way of versioning the external libraries downloaded to ensure developer 1 and developer 2 used the same version of library A. This is where Go Package Manager comes into play. GPM adds meta data about versioning of external packages. You will need two tools:

  1. GPM itself https://github.com/pote/gpm
  2. GPM-Bootstrap https://github.com/pote/homebrew-gpm_plugins

This meta data is stored in this file called Godeps. Now, instead of putting all the external libraries in your source control repo, you can just put that Godeps file in there. Run GPM and it will get the appropriate versions of the libraries you need. GPM-Bootstrap is just used for the initial Godeps file. First, let’s add a library to illustrate a sample workflow. We will pick a simple logging library:  https://github.com/kdar/factorlog

go get github.com/kdar/factorlog
# Retrieve the source for the library.

Using vim-go to edit the file

You can easily import things. Modify the import afterwards to alias it to “log”

Auto-correction should work like so:

Run the executable

Now to create your Godeps file:

Now, just push this Godeps file to your source control repo so your fellow collaborators can successfully replicate a working environment.

Have an existing Godeps file? Just need to run “gpm install” Need to update the packages used by your project?

  1. Want a specific version and/or want to update a subset of your  libraries?
    • Edit the Godeps file to include the specific revision/tag for each library you want to update.
  2. Want to update all to the latest?
    • Run go get -u then run gpm boostrap to create a new Godeps file.

Workflows:

Coming soon.

Next Post:

The next Go post will be exploring Google App Engine for Go. Recently, they have changed the architecture to be more forward with modules. My initial thoughts are to of course have one or many backends, each being a module, and a frontend module.

Below is the sketch of how they have modularized Google App Engine.

comments powered by Disqus