4 ms·
Strict semver all too often ends up "47.0.0 => 53.0.0" because in the spirit of xkcd 1172 "every change breaks someone's workflow" almost everything can be seen
by usrusr 6y ago
Strict semver all too often ends up "47.0.0 => 53.0.0" because in the spirit of xkcd 1172 "every change breaks someone's workflow" almost everything can be seen as an API change. 47=>53 could be a quick succession of tiny but technically breaking fixes in some backwater part of the API that hardly anyone uses or it could include a once-in-a-decade major API redesign or two.
- yjftsjthsd-h 6y agoI honestly feel like that's a symptom of a poor API design in the first place, although I'm willing to agree that there can be a little wiggle room in the "is it a breaking change if someone depends on a bug?" middle. If you have to bump your major that often, at best maybe consider why, and at worst at least you're still making it clear to the downstream users that that's what's happening! Better to explicitly mark "yeah, we broke API compatibility again" rather than "we incremented the version integer again; good luck finding out why unless you read the complete changelog".
- usrusr 6y agoA lot depends on typed on typedness. If breaking changes are identified during compilation then the cost of minor breakage somewhere is low. The quantity of change is far more interesting than strict absence/presence. And it takes so little change to get unexpected client code broken that I'm very sceptical of attempts to prevent it in API design. Take classic java for example. If you have a public interface adding a method can break someone's client code because nothing can keep them from implementing that interface and the implementing class might already have a method with a colliding interface. If you went completely over the top with compatibility expectations you could even argue that it's impossible (pre-modules I think?) to add any class or interface at all because someone at foo.com might have rudely put a client code class with the same name in your precious org.bar namespace. Nothing in the language prevents that. Trying to design out the possibility of breakage isn't worth it, you'll end up with conventions that soften the definition of "breaking change" anyways (or with the antipattern of major-only increments)
- usrusr 6y agoPS: on the topic of timestamps, I think that the bugfix level would be much better served with a date than with an increment. A "2.7.3" could be both much older or much younger than the corresponding "2.5.6" or contain exactly the same important fixes. When assessing the risk of running something that contains an older version your most important information is often before or after $famousvulnerability and increments can be quite deceptive. I think I might be happy with major.minor.date, where both major and minor are allowed to be breaking, with meaning "most client codebases will need change" and minor means "most client codebases will be fine". For languages leaning towards typed I'd lump the "only added features" together with minor breakage, for more dynamic languages the existing semver (plus date instead of bugfix increment) is probably fine.