Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to Calendar Versioning #2251

Open
2 of 3 tasks
uncenter opened this issue Jan 27, 2025 · 8 comments
Open
2 of 3 tasks

Switch to Calendar Versioning #2251

uncenter opened this issue Jan 27, 2025 · 8 comments
Labels
feature New feature request RFC Request for Comments

Comments

@uncenter
Copy link
Contributor

yazi --debug output

N/A

Please describe the problem you're trying to solve

I think Calendar Versioning (CalVer)](https://calver.org/) would make a lot of sense for a project like Yazi. With Yazi making breaking changes most releases, Semantic Versioning (SemVer) doesn't really make much sense. For example, see Helix, where they release every ~4 months using CalVer: https://github.com/helix-editor/helix/releases - so the versions look like 24.07 and 25.01.

Would you be willing to contribute this feature?

  • Yes, I'll give it a shot

Describe the solution you'd like

Release the next version using Calendar Versioning.

Additional context

It could look like (assuming it was released today): 2025.01.27 (YYYY.MM.DD), 2025.01 (YYYY.MM), 25.01 (YY.MM, what Helix uses as mentioned above), 25.01.27 (YY.MM.DD), etc. If a format without the day as the third number (e.g. YY.MM) is used, another digit can be added for subsequent versions in the same month. So versioning might go like 25.01 (one release in January), 25.01.1 (another January release), 25.02 (now a release in February), 25.02.1 (another February release), 25.02.3 (yet another February release), 26.4 (a release in April of the next year), etc...

Checklist

  • I have searched the existing issues/discussions
  • The latest nightly build doesn't already have this feature
@uncenter uncenter added the feature New feature request label Jan 27, 2025
@sxyazi
Copy link
Owner

sxyazi commented Jan 27, 2025

+1 for this.

I read about Calendar Versioning and think Yazi fits well with the Ubuntu example it describes:

Even a simple operating system involves many, many parts, making it difficult to communicate much meaning with an arbitrary number

Yazi consists of several functional submodules (plugin system, ya CLI, flavors), and any breaking change within one of them is considered a breaking change for the whole Yazi, even if it only affects that one submodule. Current semantic versioning doesn't describe this situation very well.

I like the idea of pinpointing version numbers down to the day, like 25.01.27, and for nightly builds, using the build date. This way, plugins can depend on a feature exclusive to nightly versions by specifying the minimum required Yazi version in their metadata:

--- @minVersion 25.01.27

return {
  entry = funcion() end
}

Before running a plugin, Yazi can check for this requirement and notify the user in a more user-friendly way if they need to upgrade.

The mount.yazi plugin is a great example – it's currently only available in Yazi nightly. The inspiration came from yazi-rs/plugins#55 (comment), thanks to @aMOPel for the suggestion.

@sxyazi
Copy link
Owner

sxyazi commented Jan 28, 2025

I just tried it, and it seems like cargo doesn't support it very well:

error: invalid leading zero in minor version number
 --> yazi-adapter/Cargo.toml:3:15
  |
3 | version     = "25.01.28"
  |               ^^^^^^^^^^
  |

I checked how Helix does it - their Cargo.toml uses 25.1.1, but the release version uses 25.01.1, which leads to two versions. I'm not sure if that's the path Yazi should take, any thoughts?

@uncenter
Copy link
Contributor Author

See helix-editor/helix#12414. Cargo doesn't support leading zeros, as that error says. The only place that uses the non-leading-zero padded version is Cargo, and the command line --version was modified to pad with leading zero: helix-editor/helix@03f35af.

@sxyazi
Copy link
Owner

sxyazi commented Jan 28, 2025

The Yazi version on crate.io will not have zero padding which will be inconsistent with the versions in other distribution packages, Helix hasn't released it on crate.io, so this isn't really an issue for them, but Yazi does

@aMOPel
Copy link

aMOPel commented Jan 29, 2025

--- @minVersion 25.01.27

return {
  entry = funcion() end
}

If I understand the implications here correctly, you will also need a way in plugins to check for the max version, if you ever plan to permanently deprecate functions in your lua api. That sort of thing is much easier with semver, though. With calver the plugin author needs to somewhen notice that his api usage is out of date and add a max version guard, where they probably by trial and error or some research in the yazi gitlog have to find out the actual calver that is the culprit. That is, if the author is still maintaining the plugin at all. After all, they can't know the max version when they write the plugin, since by then it is not known at what version some api functions will be deprecated.

For that sort of thing you probably want to have some system in place. Either it's well documented at what calver you deprecate lua api functions. Or you come up with some smarter idea to solve this problem. Maybe you just keep around dummies for all deprecated lua api functions and show a nice error message to the user that the plugin is outdated (maybe you do that already :D). Then it's not on the plugin author to keep track of that.

However the user only finds out if the plugin works with their version after they have installed and used it, unfortunately. The way I see it, that problem can only be solved if the plugin author keeps track of the max version, though.

@uncenter
Copy link
Contributor Author

With calver the plugin author needs to somewhen notice that his api usage is out of date and add a max version guard, where they probably by trial and error or some research in the yazi gitlog have to find out the actual calver that is the culprit.

What? Regular releases would still happen at the same pace, just the number would be different. It isn't like release notes are disappearing either 😅

@sxyazi
Copy link
Owner

sxyazi commented Jan 29, 2025

I'm not sure if max version is really necessary or if there are any real-world examples where it's needed. For instance, is there any plugin right now that requires it?

If it is necessary, using semantic versioning would definitely make it easier. The plugin could simply specify something like --- @maxVersion 0.4, indicating that the plugin is guaranteed to work with version 0.4.

Then, we would just need to ensure that the Yazi plugin API doesn't change in 0.4, or perhaps create an internal version number for the plugin system (and any subsystems). For example, Yazi could be at version 0.4, and the plugin system could be at 0.18, indicating the 18th major change.

However, this would undoubtedly add more maintenance overhead, as it would require keeping track of multiple version numbers.

@sxyazi sxyazi added the RFC Request for Comments label Jan 29, 2025
@aMOPel
Copy link

aMOPel commented Jan 30, 2025

What? Regular releases would still happen at the same pace, just the number would be different.

Not talking about release pace here.

Sorry if this is not helpful. Just tell me I'll stop.

My point is basically this:

There is an implicit tradeoff when choosing calver over semver, iff you break backwards compatibility.

If the lua API breaks backwards compatibility ever, then some plugins will stop working.

If the plugin author is not around to notice that their plugin stopped working due to a breaking change, they won't adapt their plugin. They won't make it comply to the changed API nor will they add a max version guard nor will they add a note to the readme.

The user will then install a plugin, expect it work, to find out it doesn't. Without a max version check the error the user gets will be confusing.

With semver you can prevent this, because the plugin author can write a max version guard into their plugin at the time they create it and if the plugin breaks, semver will protect the plugin from being executed, catching the error early, helping the user experience.

When using calver, you could also get around this issue by simply saying, every time you break the lua API, you keep the deprecated functions around, but calling such a broken/deprecated function from Lua will result in a user friendly error. Telling the user what plugin is broken and why.

Neither semver nor this workaround solve the greater issue that users will sometimes install plugins that don't work any more and that your plugin eco system will shrink a little every time you break backwards compatibility, since you lose the functionality of some unmaintained plugins.

All those issues would go away if you never break backwards compatibility. But that brings with it other problems of course.

Edit: also I wanna emphasize that I'm not advocating for either semver or calver here. I just wanna point out some tradeoffs they bring with them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature request RFC Request for Comments
Projects
None yet
Development

No branches or pull requests

3 participants