TL;DR:

  • Run go mod init <your git repo> to make a go.mod file containing all your requirements
  • Run go get to work on dependency sources. This means setting $GOPATH.

I have been coding in Python for years now, and I am pretty used to the way Python handles modules and dependencies. I am currently trying to learn Go (since everything cloud related is written in Golang). For a Python programmer who is used to isolating work in virtual environments and tracking dependencies in a requirements.txt file, learning to program in Go has been very frustrating.

I wrote a business strategy generator in Go to get the hang of the syntax. I often refer back to it to jog my memory. Some time ago, I merged in a PR that refactored the code so it wasn’t a one file program. It’s now one of the functions in OpenFaaS’s function store (Thanks, Alex!). Being a Go N00b, I had no idea how to deal with this change as I had yet to deal with a dependency. One more PR later and I lost track of all of the changes to that original one file. Then life happened and all of my Go learnings were all…gone.

Since then, Go 1.11 was released with experimental support for Go modules. This seemed like a good way for me to keep track of dependencies. So I tried to make it work on the strategy generator.

A note before I go further: I almost exclusively work in a Linux terminal, so this may or may not apply for Windows of Mac OSX. Why would you want to use those anyway? ;)

I just needed to run go mod init github.com/nishakm/strategy_generator within the cloned github repository to create a file called go.mod. Because I don’t have any external dependencies, all that was in the file was module github.com/nishakm/strategy_generator. If a project did have external dependencies, those would be listed under a require line. Projects are versioned using semantic versioning (v1.2.3 for example). If a version doesn’t exist then the project gets pseudo-versioned with a combination of v0.0.0 and the git sha that is at the tip of the master branch.

What this means is that you could clone this project and test it out without having to set up a GOPATH. Be careful though - if the project does have some requirements and you run go build within the repo, it will be downloaded one directory level higher than your current working directory in a folder called pkg. This is annoying as the contents in pkg are all read-only, so in order to delete it, you will have to chmod+w all of the files first. So a safe thing to do is to first make a directory, then cd into that directory to clone the project and then cd into the project and run go build.

However, the GOPATH still seems to be required as without it, you cannot download source code. Imagine that for some reason, your project needs a business strategy generator and you’ve decided to use this one. You would also like to contribute improvements to it (I am a Go n00b after all). In this case you would want to work with the project’s source code as well. For this, you would run go get github.com/nishakm/strategy_generator. This will download the source code to $GOPATH/src/github.com/nishakm/strategy_generator.

I think this is a pretty exciting improvement for Golang. If you just want to try out something, there’s a no-pressure way of doing so. If you want to work on the project without bothering with the dependencies, you can do that too. If you want to work on the project and the dependencies, you can do that as well.

Working on existing projects with this kind of setup has been frustrating though. Some projects assume your workflow is primarily using go get while the ones that have a go.mod have not completely migrated their projects so there are still some issues with fetching all the dependent code. It doesn’t help that I have no experience in Go or that the documentation assumes you have experience in Go. I will continue with logging my frustrations but in the meantime, I think this is a good start to my learning journey.

By the way, http://github.com/nishakm/strategy_generator also works as a Go learning guide if you want to find out what GOPATH is.