Yes, and that is why it is the developer's fault and not Go's. The script tag doesn't magically know that this is a specific version of jquery, it will happily let you reference code from a version that will change from under you too. The script tag simply allows importing any external code, its up to you to choose a good source. In exactly the same way, this Go feature can be used to reference code that is not expected to change (for example, by referencing a specific tag in a github repo), but can also be "misused" by referencing something that will change from under you. There exists no way to write this feature such that it only allows linking to "immutable sources". Its the same as writing a bootstrap script that downloads HEAD sources and compiles them, and then getting angry at bash or wget because it should "know about versioning".
There is no discussion about versioning in the 'Remote Packages' section - instead we are told "This convention is the easiest way to make your Go packages available for others to use.” My reading is that importing from HEAD is a Go convention.
Importing from HEAD _is_ the Go convention (so far as I can tell from others' code); it's also Go convention (again, in my experience) to have each system in its own source tree specified in GOPATH, with all remote dependencies installed locally at a known version.
Again, as I mentioned elsethread, I'm pretty new to Go, so perhaps I've been misusing it.
with all remote dependencies installed locally at a known version.
How would you guarantee that known version? Using the normal import above would not do this, esp. if you are working with other developers or have to switch computer/reinstall your dev environment/update. You'd get the current head (not a known version) of all dependencies whenever you run go get on a fresh install, because there is no package versioning in go import statements or go get.
The only way currently to guarantee you get a known version is to fork your dependencies, put all the code in your own repository and update them manually. That's not the end of the world but it's not as elegant as the rest of the go build system.
> How would you guarantee that known version? Using the normal import above would not do this
Because that's the source code sitting in your src tree. That's actually exactly what 'go get' will do: pull the source code of the current version of the dependency into your src tree and build objects in your pkg tree.
> The only way currently to guarantee you get a known version is to fork your dependencies, put all the code in your own repository and update them manually.
Nope, you just use (e.g.) a git submodule for the dependency. When you need to, but only when you need to, you can update each dependency or all at once.
There are definitely workarounds (submodules would be even better than forking probably), but default go get behaviour is to clone dependencies into your src tree - not a known version of them, but just the latest head. So if you're sharing a package with dependencies, you'd have to first check in your dependencies and not rely on go get to manage them.
Using go get on its own is not enough to end up with a known version - each go get can pull different code, unless you have manually set up dependencies first as part of the package or checked in the entire src tree and shared that. This works fine for one person working on code but obviously requires a bit more work if you're sharing code with dependencies with others.
I not trying to say it's impossible to manage or a huge flaw in go get, but it does require you to deal with dependency versions explicitly yourself, unlike many other packaging systems.
> So if you're sharing a package with dependencies, you'd have to first check in your dependencies and not rely on go get to manage them.
That's what I was describing. The developer of the dependent code pulls in the dependency with go get, and then other developers see both his dependent code and the dependency he was using.
Go feature can be used to reference code that is not expected to change (for example, by referencing a specific tag in a github repo)
No it doesn't. Go get or import doesn't let you specify a tag of a repo - if it had the developers would have an easy way out of this situation as they could specify their dependencies on import when first importing. That's not to say this is the go developers fault, but it does highlight a weakness in go dependency management:
Go get always checks out the HEAD. They have a scheme for checking out tags only for golang versions so they have the code to handle tags etc in popular repos, but hardly anyone uses the language versioning support because it just isn't (and shouldn't be) required, and requires a specific scheme of tag names to work anyway. At present golang versioning is only used for this, and it's not widely used as a result.
Of course you can work around this, and it's hardly a showstopper - at the simplest level you could go get then checkout a specific branch with git instead before building, or fork the repo, keep local copies in your source control etc. you only have to do this once for dependencies and then they won't change unless you decide to update them.
The bizarre thing is that go get does know about git tags and versioning it just refuses to make that useful for users unless they want to version the language, not the libraries they use - I imagine this was useful in early language development, but now that they've hit 1.0 and are promising to be backwards compatible it seems pretty pointless.
> I imagine this was useful in early language development, but now that they've hit 1.0 and are promising to be backwards compatible it seems pretty pointless.
I'm not sure why you think that. It's perfectly reasonable to want to use new features in Go 1.1 while maintaining backward compatibility (or an older version) for Go 1.0.
As go 1.1 is backwards compatible and much faster, and gofix makes the transition easy, I doubt many people will stay on 1.0 long enough to make this a useful feature to have built in. Have you used it? I think they initially tried to make the language versionless too but backed off and went back to versions when they realised this wasn't workable, I suspect the same will happen with packages and import long term.
I haven't seen much use of the go language auto-versioning feature in the wild, whereas lots of people have noticed the lack of support for versioning packages/imports and the implications for unpredictable builds - any dependency imported the normal way could break at some time in the future or for different coworkers who checked out at different times, unless you fork which has its own problems for maintenance. Personally I think versioning packages is more important, and would prefer to have that option rather than the option to maintain branches for different versions of go (which can be done manually where really required and is unlikely to be an issue in the 1.x series).
> Personally I think versioning packages is more important, and would prefer to have that option rather than the option to maintain branches for different versions of go (which can be done manually where really required and is unlikely to be an issue in the 1.x series).
The features have nothing to do with each other---it's not an "either or" deal.
I haven't used the `go1.0` or `go1.1` tags myself.
People have tried setting up versioned packages, but it hasn't taken. As for me, I'm quite happy with the simplicity of `go get`. It's been working great for me for over a year.
Go get fetches a go1.0 tag or similar automatically with the version of the language, if it exists. This would break for obvious reasons if it also wanted to fetch a specific tagged version of a package repo, thus I considered the two features related and exclusive.
I also like the simplicity of go get and don't feel this is big deal, but having used other packaging systems suspect that go will start versioning packages eventually as it makes life a lot easier if you are building on code from elsewhere and want to share code. The present setup works fine, with the caveat that if you don't fork all dependencies, other users might see different build results for the same code.
> but having used other packaging systems suspect that go will start versioning packages eventually as it makes life a lot easier if you are building on code from elsewhere and want to share code
I strongly disagree. I've used other packaging systems and they are a constant source of grief. I very rarely need to pin dependencies so it doesn't make sense to work with a super-powerful tool that allows dependency management at the version level. If I did, then I understand the need for the power.
> The present setup works fine, with the caveat that if you don't fork all dependencies, other users might see different build results for the same code.
That's not a caveat; that's a strength. When this happens, I get a bug report from a user, and I fix my software. Then it works.
Bitrot is a damn hard problem to solve. I'd rather it smack me in the face then creep up on me and strike when I least expect it.
N.B. I fully understand there are scenarios when reliability of builds is important. If I were in that scenario, I'd accept the pain of pinning dependencies or writing my own tool to do so. The great thing about Go is that I could do that with relatively little pain. (Its standard library contains amazing tools for analyzing Go source files.)