5 ms·
tldr: Semver dictates three version fields with specific definitions. At least one of those fields as defined is always useless to everyone except in a very rar
by BugsJustFindMe 3y ago
tldr: Semver dictates three version fields with specific definitions. At least one of those fields as defined is always useless to everyone except in a very rare circumstance. Another of those fields as defined is always risky to trust except in a very rare circumstance. Semver itself is silly. Better tooling is great but won't fix that.
...
This article starts with the wrong assumption that semver is itself meaningfully correct and useful. Semver is neither of those things except in a very specific circumstance that almost nobody has.
Semver violations are common because:
1. Semver as defined by semver.org is founded on the fundamentally false/flawed premise that you can predict whether a change will break compatibility. You can't. You should still try, but you should also recognize that sometimes you will guess wrong. And sometimes when you guess right you will still be wrong. The notion that just because you didn't add/remove an input or output parameter means you didn't change your API is extremely naive.
But this isn't the important reason. The important reason is...
2. Even if that weren't the case, it still would only make sense for approximately 0% of all versioned software projects, because almost no projects in the wild continually preserve separate feature branches with backported bug fixes, and continually preserved feature branches with backported bug fixes is the only scenario where semver's separation of features that aren't expected to break compatibility and fixes that aren't expected to break compatibility makes any kind of sense, because there is no such thing as a clean separation between feature and fix.
I hope that the truth of #1 is obvious to everyone, but if it isn't please refer to https://xkcd.com/1172/ https://xkcd.com/1172/
Less pithily, internal changes alter outward behavior literally all the time in unintentional ways, and no software project on the planet defines and constrains the expectations for its interface with sufficient clarity to avoid that. Not one. It's probably not even possible.
As for #2, consider the following scenario...
You have released version 1.0.0 of something. Then you add a feature and fix a bug unrelated to that feature. Are you at version 1.1.0 or 1.1.1? Well, it depends on the order you added your changes, doesn't it? If you fixed the bug first you'll go from 1.0.0 to 1.0.1 to 1.1.0, and if you add the feature first you'll go from 1.0.0 to 1.1.0 to 1.1.1. And if that difference doesn't matter, then the last digit doesn't matter.
The problem here is that Semver treats feature and fix as fundamentally distinct from each other. But non-breaking is non-breaking. The user on the other side of the fence wants the best version of whatever you have that doesn't break compatibility with what they're doing. If they trust you to make that distinction, then they only care about your major versions. If they don't trust you to make that distinction, then they only care about strictly matching the whole string. If you trust yourself (lol), you can cater to both groups with two-part major.minor. If you don't trust yourself, you can just use a single value that increases over time. But semver has three fields, and one of those fields is basically always completely useless except to satisfy a contractual obligation.
There is only one scenario where three version fields matter, and that's when a government defense contract forces you to fork development at the start of each project and then maintain separate code branches for separate projects, where they only get the features they ask for and you only fix the bugs they ask you to fix (this is exactly how defense contracts work), and you laboriously backport bug fixes to all of them, and the major and minor versions indicate the point of the fork, and the patch version is all the changes applied to that fork.
- burntsushi 3y ago> You should still try Great, you agree then that this tool is useful because it will help you try to predict whether a change will break compatibility. I can barely follow the rest of your comment. Semver is useful in, at least, a decentralized set of actors trying to minimally cooperate with one another by using a short number to communicate coarse but important information with respect to compatibility. Guess what that describes? A FOSS software ecosystem. So... > Semver is neither of those things except in a very specific circumstance that almost nobody has. Nope. I would say FOSS is pretty popular.
- BugsJustFindMe 3y ago> Great, you agree then that this tool is useful because it will help you try to predict whether a change will break compatibility. No. I guess you didn't actually read what I said, and decided instead to construct a strawman by carving very few words out of it completely ignoring the rest of the words around them. > I can barely follow the rest of your comment. Ah ha. > Semver is useful in, at least, a decentralized set of actors trying to minimally cooperate with one another by using a short number to communicate coarse but important information with respect to compatibility. It's not any more useful than a system with only either date/incremental (this is newer than that) or major.minor (I promise that this change breaks, and that other change might also break but I hope not) versioning except for the one case I mentioned, which FOSS decentralization has absolutely nothing to do with.
- obi1kenobi 3y agocargo-semver-checks checks almost entirely only major.minor versioning issues. Rust's flavor of semver doesn't impose or demand any particular rules about what is a minor and what is a patch version. So I'm a bit confused about the position you seem to be arguing against, when the tool and the entire ecosystem are doing exactly what you (AFAICT) consider a good idea.
- BugsJustFindMe 3y ago> Rust's flavor of semver doesn't... Semver.org says: Semantic Versioning 2.0.0 Summary Given a version number MAJOR.MINOR.PATCH, increment the: MAJOR version when you make incompatible API changes MINOR version when you add functionality in a backward compatible manner PATCH version when you make backward compatible bug fixes Three fields. If you're saying that cargo-semver-checks doesn't need three fields, then you're saying that it doesn't benefit from semver as defined by semver.org.