[i18n] readingTime
Go Proxy
I’ve been using a lot of Go lately and I don’t have a whole lot of meaningful complaints about it, but I am still figuring out all the bastard gotchas. The most recent one I learned about the hard way was module caching using the Go proxy while building several microservices for a side project. Because it’s a side project, a lot of the planning has been done on a whiteboard and by writing shitty throw away code before implementing anything useful. A side effect from this is that the data structures used across the microservices are defined in each service which is fine while everything is still in flux.
Once changes to the data structures slowed down a bit I started to define them in a more respectable way by putting them in a common library to be used across services. This was great but because naming is extremely difficult, I went back and forth a few times with the module name and its packages. Well, this broke all my services using the common library and gave me dependency naming errors that I knew damn well were wrong. I tried all the fixes I found on the internets:
go mod tidygo clean -modcachego clean -cache- Manually deleting the dependencies in
GOPATH
I even tried a nonsensical Hail Mary of deleting my go.mod and generating a new one. Nothing. Eventually I scrolled
way down on a Stack Overflow post and found something that didn’t even
cross my mind:
Since Go 1.13, the go command by default downloads and authenticates modules using the Go module mirror and Go checksum database.
Ah! That’s why it worked at first but started failing when I made changes to the common library quickly, the changes
hadn’t been picked up by the proxy cache yet. This works perfectly if you just need a specific version of a dependency
but not so much for rapid development. To directly interact with the dependency’s repo without any caching, you just
need to configure GOPROXY like so:
GOPROXY=direct go build main.go
Bonus
Even though this solves my initial problem of quickly updating my common library, I still need to commit changes, push changes, and pull those changes back to my workstation which is pretty cumbersome. Fortunately, Go has an answer for this with the replace directive which allows you to point your dependency to a different location:
go mod edit -replace gitlab.com/common/lib=../common/lib
This will update your go.mod to seamlessly use the local module in ../common/lib instead of the remote module at
gitlab.com/common/lib. Then, once you’re done making frequent changes to the dependency, you can put it back to use
the original remote location for the dependency:
go mod edit -drporeplace gitlab.com/common/lib
This is awesome for making changes quickly. Now I just have to figure out a way to use this when I want to do rapid development using containers…