it might well be something tacit that golangers learn from each other directly? or otherwise it's so obvious and simple and I just haven't realized?
it feels like it's the kind of thing that just clicks one day possibly after a few years
it might well be something tacit that golangers learn from each other directly? or otherwise it's so obvious and simple and I just haven't realized?
it feels like it's the kind of thing that just clicks one day possibly after a few years
A little while ago we were hitting yet another issue with dependencies related to version pinning at work. I tried to divine what the disparate versions mean, and came up with this flow chart from a legalistic reading of stack overflow issues [1] and the go modules doc [2]:
has the package opted into go modules (i.e. is there a go.mod?)
yes
does the repository use semver?
yes
is the major version <= 1?
yes
=> normal versioning, e.g. github.com/stretchr/testify v1.3.0
no
=> when importing, we need add /vN at the end, e.g., import "github.com/my/mod/v4", and in go.mod it will behave like github.com/my/mod/v4 v4.1.0
no
=> pseudo-versioning will be used, e.g. github.com/kolo/xmlrpc v0.0.0-20190717152603-07c4ee3fd181
no
does the repository use semver?
yes
is the major version <= 1?
yes
=> pseudo-versioning will be used, e.g. github.com/kolo/xmlrpc v0.0.0-20190717152603-07c4ee3fd181
no
=> version will be marked as incompatible, e.g. github.com/zeromq/goczmq v4.1.0+incompatible
no
=> ???
I still don't know if this is right. But that's not really the point. I think the go authors painted themselves into a corner with such an anemic initial release. Now that they're trying to address shortcomings, the complexity is blowing up to handle the very large/diverse ecosystem. It reminds me a lot of java around 1.4 when they added in generics. In the long-run it was the right move, but man was it painful.1: https://stackoverflow.com/a/57372286 2: https://github.com/golang/go/wiki/Modules
I'll also add that fetching a golang package was complicated. As I remember, GitHub seemed to be special cased. Other URLs involved an HTTP request with a ?go-get=1 parameter, and then parsing the returned HTML for certain meta tags¹. (I thought only Python was guilty of that sin!) Some URLs I ended up just re-writing, because gopkg.in packages effectively redirect to GitHub in ways that, if abandoned, allow someone else to intercept[1].
And none of this is documented anywhere particularly coherent. Bits here and there, maybe.
(Why not use go itself? Because this platform's package manager wanted to verify that the software was being built from the correct source, by hashing the inputs. It also, then, fetched those inputs, so that there wasn't some form of bait & switch, and there is no network at build time to further prevent silliness. I considered vendoring, but it isn't clear to me how vendoring works with go modules, since it doesn't seem to take into account the module version? / the path layout only allows for a single version.)
[1]: https://github.com/go-fsnotify/fsnotify
¹some servers didn't even return the right Content-Type, either, but perhaps that's an implementation bug. But I didn't have a spec to know.
The current first Google result when looking for "go modules" is https://blog.golang.org/using-go-modules which is a very verbose post starting with "This post is part 1 in a series of 5 parts". Not very engaging.
In one year I've accumulated a few snippets that I use regularly and get used to `go mod` but it was painful at the beginning. I wish I could have contributed to this topic but Go is most of the time a language that only requires to read pkg.go.dev and the main blog posts to know what's next and this Go modules workflow is, like gopls, something that doesn't currently have a good place to be documented AFAIK.
Edit: Thaxll's comment gives a very nice URL to learn about Go modules, still too much for a beginner IMHO but it has a Q&A part that goes very deep.
On a day to day operation, you need to know 2/3 commands that's it.
- go mod init
- go mod tidy
- go get xxx
go team dropped the ball on this. i feel a sense of non-consensus among themselves on what modules should have been. and it's frustrating that there is no definite documentation either.
maybe one day...