8 ms·
If your dependency isn't publishing their own versions of their libraries, maybe they shouldn't be depended upon. What I mean is... there's a clear and easy wa
by NateDad 12y ago
If your dependency isn't publishing their own versions of their libraries, maybe they shouldn't be depended upon.
What I mean is... there's a clear and easy way to version libraries in Go - you encode the version in the import path in some way. When the version changes, the import path changes (which means it's a completely different dependency, as far as Go is concerned). How you get those versions in the import path is up to you - you can use gopkg.in, you can host your own redirector, or just have different repos for each version. It's really not rocket science.
For example, I released github.com/natefinch/lumberjack as v1... when I decided I needed to break the API, I released v2 as gopkg.in/natefinch/lumberjack.v2 (which redirects to the v2 branch of the same repo). The very fact that I'm using version numbers indicates I have a commitment to keeping my library stable for third parties. Now, you don't have to trust me, you can use godep or another tool to pin your code to a specific revision of my repo, and if you're really paranoid, you can use godep to vendor my code into your own repo, to insulate you from the possibility that I delete my repo in a fit of anger. (though in theory, that would only stop you for a short period of time, since you should have a copy of my code on every machine that has ever built your code that uses my library).
I just don't understand why everyone thinks versioning in Go is a problem. It's not. It's solved... seven ways to Sunday. It's just solved in a slightly different way than other languages solve it... but so what?
- slimsag 12y agoI agree with you: package versioning in Go is solved already. I think the thing that conflicts people most often is that there is truly no "official" opinion on the subject aside from what you mentioned: use a different import path.
- jbooth 12y agoI disagree that it's solved. 90% of community libraries aren't even following the gp's recommendation, let alone minor and incremental release versions. And as you said, there's no standard. With nexus/maven repos, when you push v1.4.2 of your library, that's it, it's only published once and everyone sees the same thing. Bug fixes can go out in 1.4.3, new features in 1.5.x and incompatible features in 2.x. Right now, even if everyone followed GP'S advice, I still risk a bug fix breaking my code, or different behavior depending on when I last ran go get.
- slimsag 12y agoIt is solved -- just not widely employed. There is no official stance on package versions, because the core Go development doesn't really need/use it. The Go 1 compatibility guarantees no backwards incompat changes to stdlib. Experimental package development occurs at golang.org/x/foo ("x" for experimental, presumably). Those packages are unstable, and there are no versions. If they change at all you have to update. People follow the 'official' approach blindly, but aren't experienced enough to know what the tradeoff's in the official approach are.
- NateDad 12y agoI don't understand how any software can possibly enforce semantic versioning. Sure, you can ensure that 1.4.2 is immutable, but you can't enforce that breaking changes aren't put in 1.4.3. As I said, there are tools that let you freeze the exact commit number your code depends on, which effectively gives you frozen minor version numbers if you want it. And of course you can also copy the code into your repo with godep, and not need any external services outside your own VCS.
- frowaway001 12y ago> you can't enforce that breaking changes aren't put in 1.4.3 Eh ... why? In some languages, it's standard to run source/binary compatibility checks against new versions and fail a build if the new version doesn't satisfy the requirements.
- NateDad 12y agoWith decent static analysis you could check that the signatures of all types and functions are identical or compatible, I suppose, but checking that the functionality is compatible in any kind of generic way is impossible. The former is necessary, but not sufficient.
- frowaway001 12y ago> With decent static analysis you could check that the signatures of all types and functions are identical or compatible, I suppose "I suppose"? This has been done for years already. There are even GUIs for that (so that people don't have to use the CLI) which tell you "between 1.2.3 and 1.2.4 you did the following: ... This will break compatibility in the following cases: ..." So it's better to not even try? Additionally, for many changes it is reasonable and possible to check whether behavior has changed. Not every function has an unlimited number of inputs and outputs. That's one of the biggest reasons I avoid Go and PHP: It's not only that the developers ignore existing solutions if they haven't "invented" them themselves, but that they don't even care about improving things where no "perfect" solution is available. Ignorance and arrogance is a combination which doesn't make me trust them, and products based on their software. (OwnCloud, Docker, ...)