Comparing Hugo versions

I have to make sure some features are not used if Hugo Version is below whatever. (page resources)

I used {{ if ge .Hugo.Version 0.34 }} and it worked fine until I upgraded to 0.36.1 and the .Hugo.Version value ceased to be a simple float.

Any body, knowing golang would know how to efficiently compare those two values? I tried to use float on .Hugo.Version but it throws:
unable to cast "0.36.1" of type string to float64

Thanks a ton!

May be instead of directly using .Hugo.Version, first truncate off the last micro version bit using replaceRE and then use that instead?

Damn! That’d be perfect. Let me reduce my self-confidence to shreds while I’m looking for the right regex.

That having software versions represented by floats (Hugo 0.36.1 …?) is a bad idea was illustrated plenty this week when Go 1.10 was released and Travis started to build Hugo and lots of other projects with Go 1.1…

We have some internal and flexible helpers in this area that we could put in a template func fairly easy if someone could describe the use case in a GH issue.

We have a CompareVersion func which answers greater than, equal or less than.

Here’s some debug code :sunglasses:

{{ printf "Version string: %s<br />" .Hugo.Version | safeHTML }}
{{ $ver_float := (float (replaceRE "([0-9]+\\.[0-9]+).*" "${1}" .Hugo.Version)) }}
{{ printf "Version float: %f<br />" $ver_float | safeHTML }}
{{ printf "Version ≥ 0.36?: %#v<br />" (ge $ver_float 0.36) | safeHTML }}
{{ printf "Version ≥ 0.37?: %#v<br />" (ge $ver_float 0.37) | safeHTML }}
{{ printf "Version ≥ 0.38?: %#v<br />" (ge $ver_float 0.38) | safeHTML }}

For the DEV version that I am on, it gives:

image

1 Like

Here you go https://github.com/gohugoio/hugo/issues/4443

Thanks!

Thanks for that temporary solution! Works like a charm.

1 Like

I am probably just wasting my time here with one more iteration, but it was cool to come up with this :smile:

{{ printf "Version string: %s<br />" .Hugo.Version | safeHTML }}
{{ $major_minor_ver_float := (float (replaceRE "([0-9]+\\.[0-9]+).*" "${1}" .Hugo.Version)) }}
{{ $micro_ver := (replaceRE "[0-9]+\\.[0-9]+(.*)" "${1}" .Hugo.Version | replaceRE "-DEV" "-0.01") }}
{{ $micro_ver_float := (div (float (or $micro_ver "0")) 100.00) }}
{{ printf "Micro Version: %s<br />" $micro_ver | safeHTML }}
{{ printf "Micro Version float: %f<br />" $micro_ver_float | safeHTML }}

{{ $ver_float := (add $major_minor_ver_float $micro_ver_float) }}
{{ printf "Version float: %f<br />" $ver_float | safeHTML }}
{{ printf "Version ≥ 0.36?: %#v<br />" (ge $ver_float 0.36) | safeHTML }}
{{ printf "Version ≥ 0.37?: %#v<br />" (ge $ver_float 0.37) | safeHTML }}
{{ printf "Version ≥ 0.38?: %#v<br />" (ge $ver_float 0.38) | safeHTML }}

image

1 Like

You’re not wasting your time if you’re having fun :slight_smile:

Beside we’ll still need your workaround before the version including issue#4443 is super widely adopted…

Update

See the updated, better alternative of this in my later comment:


Old Version

Alright, one last for the day… the usage is a bit verbose, but the solution is generic… I guess, as close as we can get to a template function.

Partial version_ge.html

{{ $ver_current := (index . 0) }}
{{ $ver_ref := (index . 1) }}

{{ $ver_current_major_minor := (float (replaceRE "([0-9]+\\.[0-9]+).*" "${1}" $ver_current)) }}
{{ $ver_current_micro_str := (replaceRE "[0-9]+\\.[0-9]+(.*)" "${1}" $ver_current | replaceRE "-DEV" "-0.01") }}
{{ $ver_current_micro := (div (float (or $ver_current_micro_str "0")) 100.00) }}
{{ $ver_current_float := (add $ver_current_major_minor $ver_current_micro) }}

{{ $ver_ref_major_minor := (float (replaceRE "([0-9]+\\.[0-9]+).*" "${1}" $ver_ref)) }}
{{ $ver_ref_micro_str := (replaceRE "[0-9]+\\.[0-9]+(.*)" "${1}" $ver_ref | replaceRE "-DEV" "-0.01") }}
{{ $ver_ref_micro := (div (float (or $ver_ref_micro_str "0")) 100.00) }}
{{ $ver_ref_float := (add $ver_ref_major_minor $ver_ref_micro) }}

<!-- "Return" value -->
{{ ge $ver_current_float $ver_ref_float }}

Tests

{{ if (findRE "true" (partial "version_ge.html" (slice "0.35-DEV" "0.36"))) }}
    {{ printf "0.35-DEV ≥ 0.36<br />" | safeHTML }}
{{ else }}
    {{ printf "0.35-DEV < 0.36<br />" | safeHTML }}
{{ end }}
{{ if (findRE "true" (partial "version_ge.html" (slice "0.35" "0.36"))) }}
    {{ printf "0.35 ≥ 0.36<br />" | safeHTML }}
{{ else }}
    {{ printf "0.35 < 0.36<br />" | safeHTML }}
{{ end }}
{{ if (findRE "true" (partial "version_ge.html" (slice "0.35.1" "0.36"))) }}
    {{ printf "0.35.1 ≥ 0.36<br />" | safeHTML }}
{{ else }}
    {{ printf "0.35.1 < 0.36<br />" | safeHTML }}
{{ end }}
{{ if (findRE "true" (partial "version_ge.html" (slice "0.36-DEV" "0.36"))) }}
    {{ printf "0.36-DEV ≥ 0.36<br />" | safeHTML }}
{{ else }}
    {{ printf "0.36-DEV < 0.36<br />" | safeHTML }}
{{ end }}
{{ if (findRE "true" (partial "version_ge.html" (slice "0.36" "0.36"))) }}
    {{ printf "0.36 ≥ 0.36<br />" | safeHTML }}
{{ else }}
    {{ printf "0.36 < 0.36<br />" | safeHTML }}
{{ end }}
{{ if (findRE "true" (partial "version_ge.html" (slice "0.36.0" "0.36"))) }}
    {{ printf "0.36.0 ≥ 0.36<br />" | safeHTML }}
{{ else }}
    {{ printf "0.36.0 < 0.36<br />" | safeHTML }}
{{ end }}
{{ if (findRE "true" (partial "version_ge.html" (slice "0.36.1" "0.36"))) }}
    {{ printf "0.36.1 ≥ 0.36<br />" | safeHTML }}
{{ else }}
    {{ printf "0.36.1 < 0.36<br />" | safeHTML }}
{{ end }}

image


Example Use

An actual use case could be:

{{ if (findRE "true" (partial "version_ge.html" (slice .Hugo.Version "0.35"))) }}
    {{ printf "Headless bundles available!<br />" | safeHTML }}
{{ else }}
    {{ printf "Headless bundles *not* available!<br />" | safeHTML }}
{{ end }}

OR

{{ if (findRE "false" (partial "version_ge.html" (slice .Hugo.Version "0.35"))) }}
    {{ printf "Headless bundles *not* available!<br />" | safeHTML }}
{{ else }}
    {{ printf "Headless bundles available!<br />" | safeHTML }}
{{ end }}

If you really want to understand versioning, this series is a fantastic read:

https://research.swtch.com/vgo

Russ Cox adds real simplicity and clarity to a subject that has been really muddy.

1 Like

And here’s the final-final iteration… much lighter than the earlier version, and it will also be easy to replace it with the inbuilt ge, le comparisons in future.

Partial version_str2float.html

{{- $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

Example Use

{{ if (ge (partial "version_str2float.html" .Hugo.Version) 0.36) }}
    {{ printf "curr >= 0.36<br />" | safeHTML }}
{{ else }}
    {{ printf "curr < 0.36<br />" | safeHTML }}
{{ end }}

Future

In future, once version 0.37 is old enough, simply remove the partial wrapper.

So (partial "version_str2float.html" .Hugo.Version) becomes just .Hugo.Version, and things will “just work”.

Here’s a live example :sunglasses:

2 Likes