Sort strings based on semver?

I’m working on a system for auto-inferring which versions of documentation exist based on which folders exist in the content/docs folder. Thus, if there is a content/docs/1.0 folder and a content/docs/1.1 folder, then I can infer that 1.0 and 1.1 are the available versions and that 1.1 is the “latest” version. Like this:

<!-- Sort versions in descending order -->
{{ $versions := sort (readDir "content/docs") "Name" "desc" }}
<!-- The "latest" version is the first version in the array -->
{{ $latest := (index $versions 0).Name }}

The issue is that that system breaks down if I add version 1.1.1, which is technically “below” version 1.1 when using an ordinary sort function.

Have any of you come up with a way of maintaining proper sorting based on semver?

1 Like

Does this help? It converts an “x.y.z” version to a float. And then you can sort based on that float string?

{{/* .36      -> 0.36
     .36.1    -> 0.361
     0.37-DEV -> 0.3699 */}}
{{- $ver_major_minor := (float (replaceRE "([0-9]+\\.[0-9]+).*" "${1}" .)) -}}
{{- $ver_micro_str := (replaceRE "[0-9]+\\.[0-9]+(.*)" "${1}" . | replaceRE "-DEV" "-0.01") -}}
{{- $ver_micro := (div (float (or $ver_micro_str "0")) 100.00) -}}
{{- $ver_float := (add $ver_major_minor $ver_micro) -}}
<!-- "Return" value -->
{{- $ver_float -}}

Source

2 Likes

Wow, that’s amazing! Such a creative approach. I’m going to give this a try and get back to you. A+++