7 ms·
I never really liked semver as its a mixture of release number and an abstraction/categorization of risk that nobody can agree on, making it hard to tell how st
by extrapickles 10y ago
I never really liked semver as its a mixture of release number and an abstraction/categorization of risk that nobody can agree on, making it hard to tell how stable an update will be. It was fine back when you only had a release or two a year, but now the abstraction is no longer good enough.
I prefer the first number to be a simple release number, then the second to be the amount of risk from the previous release. That way for projects with a dozen or two releases one can normalize the risk values between projects to get everyone more or less on the same page without them having to change their behavior and it can introduce the ability for you to manually correct the risk for different libraries (eg: Library X is super critical for me, so *2 the risk).
Automated tools for calculating risk are possible with this scheme and additional risk can be added for the update (eg: tool sees you are using method X or API call Y that was changed, so the risk is increased).
With release.risk you can say "Automatically update when total risk is <X" and actually have it be tolerable to you. Even when manually updating, you can get an idea of how much trouble its going to be, and possibly have a tool generate a list of areas you should put extra attention towards (eg: library X has a risky update, check to see if it breaks your corner cases).
- rmattes 10y agoWhat do you mean by risk? How would you quantify it? As I understand it, all semver is trying to tell you is when backwards-compatible changes happen, and when backwards-incompatible changes happen. If the project developer wants to add some sort of indication that "this package contains changes that are alpha quality, and may not respect semver for the next few releases" then that developer can append a pre-release identifer to the version, as described in the semver spec. Once that identifier goes away, the risk that a package violates semver should be gone, and you should be free to update based on the semver relation to the previous release. Ultimately, it's up to the project to verify that their releases don't violate the semver spec by being diligent with respect to their public API. If you find that a project isn't disciplined in documenting API changes (semver or otherwise,) then coming upw ith new rules to convey the information they're already not conveying isn't going to help anything.
- iopq 10y agoWell, backwards-compatibility is sometimes a probability. For example, a change in the public signature of a function to accept a wider class of arguments might be considered backwards-compatible since the previous calls to the function will still work. But if your language has type inference, now the previous calls have to actually specify the type of their arguments since the type inference algorithm can no longer resolve all the types. So you can break SOMEONE'S build by accepting more types of arguments. It will be a one line fix, but if that fix has to be made upstream...
- rmattes 10y agoThat's an interesting point. If you're using a language that adds more rules to the API compatibility than the language that a module is released in, it's probably not possible to rely on semver in the general case. Unless the author is aware of those issues and versioning accordingly, any minor release could be breaking.
- iopq 10y agoEven in the same language, how do you prove that your changes didn't break things like type inference? Any change to the signature of a function (even accepting MORE types than before) can potentially break someone's code.
- rmattes 10y agoIf you can't definitively prove that a class of changes won't break things, then you probably have to treat that class of changes as breaking and version accordingly, no?
- extrapickles 10y agoRisk is simply an integer expressing how likely the project is to work if you use the previous release. Anything else is left up to the project to determine what things get a specific amount of risk. Or another way of putting is that the only requirement is that the risk number be correlated to the probability of running into issues running that release over the previous. Risk can even go negative to signal that the previous release had a showstopping bug that was fixed and that the new release should be used in all cases over the previous. Also, some of the risk calculation can be pushed down onto tooling and the community. As an example, if more than the normal amounts of issues are reported against a release, the risk for the release can be automatically increased without anyone needing to be diligent in updating it and things can get automatically rolled back if the change was found to be too risky. Semver requires a project to be more diligent than many projects are willing/able to be, and requires all changes fit nicely into the semver categories. Too many changes don't fit neatly into semver, especially when libraries are used cross platform and in different programming languages. Say a project switches from GCC to Clang, semver has no official way to express that. Release.Risk can handle it by assigning a amount of risk to the update and pretty much any other unforeseen corner case too as it doesn't try and categorize the risk. Also different projects have different risk profiles which semver completely ignores the concept of (glibc is more risk adverse than the JS library of the day). Semver also doesn't indicate any difference between a new feature that is self contained or one that touches a core piece of code, the former is much less risky than the later.