I appreciate your thoughts as always. I'm sure this is frustrating for you because you have a bunch of users yelling at you to do something in a way you don't agree with, and it's not like they pay you for the right to do that.
A couple comments:
> Node doesn't follow SemVer, Rails doesn't do it, Python doesn't do it, Ruby doesn't do it, jQuery doesn't (really) do it
Node does (because it's <1.0.0 where semver's rules are different). Everything else you list is older than semver, so short of a time machine or a radical change to their long-established versioning policies, there's not much they can do.
> the responsible way is to set aside five or ten minutes, every once in a while, to go through and update your dependencies, and make any minor changes that need to be made at that time.
That works fine for your immediate dependencies. The reason why I think things like semver are important is that the above doesn't work at all with transitive dependencies.
If my app uses foo which uses bar which uses baz and the maintainers of baz decide to make a breaking change in a minor version, I'm not in a happy place when that wolf in sheep's clothing appears in my dependency graph. I'll see that my app is broken, but unless I want to fork bar and maybe foo and start mucking around in code I've never touched before, my options are pretty limited.
I don't think semver is perfect, but I find it does make transitive and shared dependencies a lot more reliable to work with. I'm willing to sacrifice human-meaningful version numbers to get that.
> Node does (because it's <1.0.0 where semver's rules are different)
You might've missed the paragraph preëmptively responding to that (it was added in an edit).
SemVer says that you shouldn't be pre-1.0.0 if you're actively used in production anywhere. Node has been out for years. Treating the current versions of Node as pre-1.0.0 is a joke.
From the semver.org FAQ:
> How do I know when to release 1.0.0?
> If your software is being used in production, it should probably already be 1.0.0. If you have a stable API on which users have come to depend, you should be 1.0.0. If you're worrying a lot about backwards compatibility, you should probably already be 1.0.0.
There is no way an author / project can control when someone is going to use their software 'in production', I would certainly argue that condition is the weakest of indicators as to whether something is 1.0.0 or not.
Aside from that, the other 2 indicators definitely do not apply to Node (API is not stable, there is not a lot of worry about backwards compatibility as you'll see in the upcoming 0.12 release).
Part of what I'm saying is that your transitive dependencies shouldn't be changing willy-nilly in the first place. The code you depend on is ultimate code you're responsible for — and having changes happening deep down that you're not aware of is a recipe for trouble.
Immediate dependencies are a relative thing, after all — foo's deep dependency is bar's immediate dependency. And if SemVer'ing them only works some of the time, but won't save you all of the time, then why bother pretending in the first place?
The actual appearance of breaking changes in software that end up affecting you occurs at the same interval regardless of the version number we decide to label them with. We can do better for determining compatibility than a three or four character version number.
A couple comments:
> Node doesn't follow SemVer, Rails doesn't do it, Python doesn't do it, Ruby doesn't do it, jQuery doesn't (really) do it
Node does (because it's <1.0.0 where semver's rules are different). Everything else you list is older than semver, so short of a time machine or a radical change to their long-established versioning policies, there's not much they can do.
> the responsible way is to set aside five or ten minutes, every once in a while, to go through and update your dependencies, and make any minor changes that need to be made at that time.
That works fine for your immediate dependencies. The reason why I think things like semver are important is that the above doesn't work at all with transitive dependencies.
If my app uses foo which uses bar which uses baz and the maintainers of baz decide to make a breaking change in a minor version, I'm not in a happy place when that wolf in sheep's clothing appears in my dependency graph. I'll see that my app is broken, but unless I want to fork bar and maybe foo and start mucking around in code I've never touched before, my options are pretty limited.
I don't think semver is perfect, but I find it does make transitive and shared dependencies a lot more reliable to work with. I'm willing to sacrifice human-meaningful version numbers to get that.