jimporter / mike

Manage multiple versions of your MkDocs-powered documentation via Git
BSD 3-Clause "New" or "Revised" License
528 stars 47 forks source link

Custom version ordering #124

Closed leonardehrenfried closed 1 year ago

leonardehrenfried commented 1 year ago

Over the years our open source project has accumulated a few idiosyncratic ways of doing things. We recently moved from readthedocs to mike and want to keep our current URL structure but that leads to the ordering in versions.json to be not what we hoped.

Our versions are this:

Understandably, mike orders these versions like this:

This leads to them being rendered in the version selector like that:

image

Would you accept any patches that implement a custom version ordering? Or should I forget that idea and implement a little GH Action that reorders the file after the commit?

jimporter commented 1 year ago

The development version of mike 2.0 uses a (hopefully) smarter version-sorting scheme: versions starting with numbers are sorted as usual, but versions that don't start with numbers are now treated as "development versions", and go at the top of the list (in reverse-alphabetical order, since the dropdown sorts from last to first). That should go most of the way to solving your issue here.

That said, if you have a version named latest, and titled 2.2.0, I'd recommend reversing that: deploy your latest docs to 2.2.0 as the primary version, and add an alias of latest to it: that will let you point links to your-docs.com/latest/ as usual, but keep the sorting the way you want. (It also makes it easier for people to perma-link to the 2.2.0 docs if they want.)

You might also benefit from specifying the versions of your pages as [major].[minor], rather than [major].[minor].[patch]. This is just my preference of course, but I never saw much benefit to keeping docs around for old patch releases: if you have [major].[minor], perma-links always point to the latest patch release, which I think is usually the right thing to do (assuming you follow semver).

Of course, the changes in mike 2.0 might not be sufficient for how you want things to look. I don't think I'd want to add extra support in mike itself for customizing the sort order, but since the versions.json file is designed to have a stable and unchanging schema, it shouldn't be too hard to add a post-processing step that manipulates the file however you like. You could also handle the sorting in Javascript when actually displaying the dropdown, though I imagine this would require delving into the Material theme's internals (at least, it looks like you're using Material).

leonardehrenfried commented 1 year ago

The problem is the leading v in the version so I think all of them would be considered development version, isn't it?

I agree wholeheartedly with your point of not keeping the patch versions around. However, our project has over 10 years of history and in an effort to be thorough those ended up in the URLs and nobody had the stomach to change all of the links.

I will try the latest version and see what happens. If it doesn't do what we want then I will write a little script order them how we would like to see it.

Thanks very much for your help.

jimporter commented 1 year ago

If you set up aliases, you shouldn't need to worry about invalidating old links. You could have, say, 2.0.0 just be an alias that redirects to 2.0.

Maybe there's an argument for version specifiers like v1.2.3 to be treated the same as 1.2.3, but that's an extra layer of complexity, and so it's more room for things to break...

jimporter commented 1 year ago

Ok, as of 8440141, v-prefixed versions should be treated as regular, non-development versions. (You can't mix them with regular 1.2.3-style versions, but I don't know that anyone would want to anyway.) I also added a bit of documentation about how versions are sorted.

With that fixed, I think that's all that mike can really do to help with this, so more-esoteric scenarios will probably require a bit of post-processing. (It would be an interesting experiment to see if you could write a new MkDocs plugin that performs this post-processing in a clean way, but I'm not sure I have time to try that out myself.)

leonardehrenfried commented 1 year ago

Wow, thank you! I will try it out asap!

squidfunk commented 1 year ago

Since mike is a plugin, could'n it just allow users to implement their own sorting function? We do the same over at Material for MkDocs, e.g. for slugifying tags or comparing tags for sorting. That would give authors 100% control.

You could also handle the sorting in Javascript when actually displaying the dropdown, though I imagine this would require delving into the Material theme's internals (at least, it looks like you're using Material).

Sorting the versions.json beforehand is by far easier than hooking into the JavaScript 😅 Especially for non-FE users.

jimporter commented 1 year ago

Since mike is a plugin, could'n it just allow users to implement their own sorting function?

It could, but I'd prefer to keep options to a minimum if I can help it. My goal is to release mike v2.0 and then call the project "done", aside from the occasional bugfix or compatibility update. I mainly wrote mike to solve this for my personal projects, and it already does considerably more than I need.

In this case, a user could post-process the versions.json file using a separate script in the (hopefully) rare occasion where the default sort order is wrong. That wouldn't require messing with JS; just a bit of work to read versions.json, modify it, and generate a new commit. (Doing it through JS is fine too though; it'd be an option for users who maintain their own theme.)

squidfunk commented 1 year ago

My goal is to release mike v2.0 and then call the project "done", aside from the occasional bugfix or compatibility update.

Ah yeah, been there, thought that 😅 I was corrected. I guess that's what Open Source is all about. I need to say: many thanks for maintaining mike over the last years by the way, it's a really good and lean versioning implementation! With that said, offering users ways to customize has often been, at least for me, a good escape hatch for further feature requests.

jimporter commented 1 year ago

It's something I might think about further in the future, but my initial goal with mike was for it to be a set of commands that users add their own automation on top of. Increasingly (especially with 2.0), I've moved more of that into the configuration for the plugin, so that it becomes easier to manage without writing wrapper scripts.

For a little bit of backstory: I myself never interact with mike directly; I use wrappers on top to automatically manage documentation versions so that I only ever have to run make doc-deploy (or some rough equivalent depending on build system). To use Git's terminology, for me, mike is plumbing that I add my own porcelain to. However, based on the issues people file, I think most people expect mike to be porcelain too.

(And thanks for the kind words! Obviously, I like mike, but I'm glad others have gotten value out of it too!)