hugo icon indicating copy to clipboard operation
hugo copied to clipboard

Extend sort function to support semantic version numbers

Open alexlafreniere opened this issue 3 years ago • 6 comments

We use Hugo to manage our documentation site. On this site, we provide documentation for various versions of software packages that are released according to semantic versioning rules. We list versions of the packages in descending order according to their version number for easy navigation. Today, Hugo has no direct support for sorting by semver, so we settle for sorting by the date the version was released. This is less than desirable in the situation where we are actively maintaining more than one major or minor version at a time, resulting in seemingly unsorted lists of versions for our users.

On a stale PR attempting to implement sorting of semver numbers, @jmooring suggested extending the sort function to support this functionality. Implementing sorting in this way would avoid breaking existing sites and allow sorting any resource by any front matter field according to semver conventions:

{{ range (sort .Pages "Params.version" "semVerAsc" ) }}
{{ range (sort .Pages "Params.version" "semVerDesc" ) }}

I'm unfamiliar with the Hugo codebase, but would be more than happy to perform the implementation once the design proposal is finalized and accepted by the Hugo maintainers. My initial survey of the source suggests most changes would center around tpl/collections/sort.go, but a nudge in the right direction from more experienced contributors would be appreciated.

alexlafreniere avatar Jan 17 '22 18:01 alexlafreniere

The high-level desire is to specify a sort method as well as a sort direction. Whether those are specified together in a single string, in separate args, or in a map is an implementation detail.

In addition to semver sorting, at some point we might want to add a natural sort.

jmooring avatar Jan 17 '22 19:01 jmooring

@alexlafreniere, what do you expect to happen when the input contains an invalid semver string?

I'll throw out a proposal for discussion:

The existing function signature for sort is:

sort SEQUENCE [FIELD [DIRECTION]]

We could add a new optional field for the sort method:

sort SEQUENCE [FIELD [DIRECTION [METHOD]]]
  • Method would be semver in this case.
  • If no method is supplied, the default sort method is used.
  • This could be extended easily to support additional methods such as natural.
  • This new field would maintain backward compatibility so as not to break any existing sites.

Example usage:

{{ sort .Pages "Params.version" "asc" "semver" }}
{{ sort .Pages "Params.version" "desc" "semver" }}

moorereason avatar Jan 17 '22 22:01 moorereason

semver strings are strictly defined. I'd be okay with throwing an error when an invalid string is encountered.

alexlafreniere avatar Jan 17 '22 22:01 alexlafreniere

Also need to come up with a name for current sort method, which seems to sort numeric things numerically, and alpha things alphabetically. Maybe the method is simply default with an explanation in the docs.

Test data
{{ $m := slice
  (dict "name" "Buddy" "age_int" 3 "age_string" "a3")
  (dict "name" "Duke" "age_int" 21 "age_string" "a21")
  (dict "name" "Rover" "age_int" 2 "age_string" "a2")
  (dict "name" "Spot" "age_int" 1 "age_string" "a1")
}}

{{ $mSorted := sort $m "age_int" }}
<pre>{{ jsonify (dict "indent" "  ") $mSorted }}</pre>

{{ $mSorted := sort $m "age_string" }}
<pre>{{ jsonify (dict "indent" "  ") $mSorted }}</pre>

jmooring avatar Jan 17 '22 22:01 jmooring

Just to document the workaround we went with for Graphviz, padding out our major version numbers to two digits (or, more generally, the length of the longest major version in use) did the trick. "10.0.1" will sort before "9.0.0", but it sorts after "09.0.0".

ferdnyc avatar Jun 29 '24 10:06 ferdnyc

(If it's not the major version but some other version component that gets into double digits, you'd want to pad those out as well / instead. Just like with the major versions, "1.10.1" comes before "1.9.1", but should sort after "1.09.1".)

ferdnyc avatar Jun 29 '24 10:06 ferdnyc