Despite the confusing nomenclature, Go 1.11 finally added a proper package management system, which they called modules.
The first time I used Go I uttered a series of WTFs when I was told I had to put the code in a specific place in the file system (the infamous
GOPATH), with a specific naming scheme matching the git repository and other stuff like this. For 2018 it seemed we were going backwards. I'm sure there were perfectly good reasons for it to be like that, I just didn't care coming from languages that had solved (more or less) the issue of how to manage packages a long time ago. I ended up adapting to the go way but not happily.
Fortunately soon after that I discovered
go dep which allows the developer to have more control about what happens (but still inside
GOPATH). Dep works by having a file in which you list dependencies with their versions and revisions and by creating a
lock file (a concept many package managers share) while vendoring dependencies in a
vendor folder (usually ignored by .gitignore). This way, when you build the app (locally, on CI, on a server, or elsewhere) you can be sure about which versions of what packages the app is using.
The Go community decided to go one step further and create a preliminary version of what will likely be the official tool to handle packages:
go mod and modules. This new tool is out with Go 1.11.
The tool works this way:
- you write your app declaring which packages you need
- it creates a
lock fileand handles semantic versioning
- it can optionally vendor files
What I love about it:
- it's dead simple and it's builtin
- it forces the developers to tag their libraries following semantic versioning. I hate having to go through master revisions to figure out what has changed because devs are too lazy to release their code. This will also probably encourage them to write changelogs for such tags
- it can clean up after itself (removing modules no longer used by the app)
- it tells you why you have this or that package installed
- it does not upgrade to a major version by itself (this is huge for large projects)
- it allows multiple versions of the same package in the same app (this is amazing! I can envision future scenarios of runtime hot code replacement a-la Erlang or Common Lisp, but maybe I'm over-reaching)