Skip to content

Commit b2b3bb7

Browse files
committed
Allow v1,v2 etc. style version names while still supporting full semver in queries
Fixes #14414
1 parent 192e3c4 commit b2b3bb7

4 files changed

Lines changed: 97 additions & 7 deletions

File tree

common/version/version.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ type Version struct {
3737
// HugoVersionSuffix is the suffix used in the Hugo version string.
3838
// It will be blank for release versions.
3939
Suffix string
40+
41+
// Set when parsed from a string,
42+
source string
4043
}
4144

4245
var (
@@ -51,6 +54,10 @@ func (v Version) IsAlphaBetaOrRC() bool {
5154
return strings.Contains(s, "alpha.") || strings.Contains(s, "beta.") || strings.Contains(s, "rc.")
5255
}
5356

57+
func (v Version) IsZero() bool {
58+
return v.Major == 0 && v.Minor == 0 && v.PatchLevel == 0 && v.Suffix == ""
59+
}
60+
5461
func (v Version) String() string {
5562
return version(v.Major, v.Minor, v.PatchLevel, v.Suffix)
5663
}
@@ -109,6 +116,7 @@ func ParseVersion(s string) (Version, error) {
109116
vv.Suffix = suffix
110117
}
111118
vv.Major, vv.Minor, vv.PatchLevel = parseVersion(s)
119+
vv.source = s
112120

113121
return vv, nil
114122
}
@@ -176,6 +184,10 @@ func CompareVersions(v1 Version, v2 any) int {
176184
case int64:
177185
c = compareFloatWithVersion(float64(d), v1)
178186
case Version:
187+
if v1.IsZero() && d.IsZero() {
188+
// Fall back to source comparison.
189+
return strings.Compare(v1.source, d.source)
190+
}
179191
if d.Major == v1.Major && d.Minor == v1.Minor && d.PatchLevel == v1.PatchLevel {
180192
return strings.Compare(v1.Suffix, d.Suffix)
181193
}
@@ -200,11 +212,13 @@ func CompareVersions(v1 Version, v2 any) int {
200212
return -1
201213
}
202214

203-
v, err := ParseVersion(s)
204-
if err != nil {
205-
return -1
215+
v2v, _ := ParseVersion(s)
216+
if v1.IsZero() && v2v.IsZero() {
217+
// Fall back to source comparison.
218+
return strings.Compare(v1.source, v2v.source)
206219
}
207-
return v1.Compare(v)
220+
221+
return v1.Compare(v2v)
208222

209223
}
210224

common/version/version_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ func TestHugoVersion(t *testing.T) {
5050
func TestCompareVersions(t *testing.T) {
5151
c := qt.New(t)
5252

53+
parseIgnoreErr := func(s string) Version {
54+
v, _ := ParseVersion(s)
55+
return v
56+
}
57+
5358
c.Assert(CompareVersions(MustParseVersion("0.20.0"), 0.20), qt.Equals, 0)
5459
c.Assert(CompareVersions(MustParseVersion("0.20.0"), float32(0.20)), qt.Equals, 0)
5560
c.Assert(CompareVersions(MustParseVersion("0.20.0"), float64(0.20)), qt.Equals, 0)
@@ -69,6 +74,15 @@ func TestCompareVersions(t *testing.T) {
6974
c.Assert(CompareVersions(MustParseVersion("0.22.0-DEV"), "0.22"), qt.Equals, 1)
7075
c.Assert(CompareVersions(MustParseVersion("0.22.1-DEV"), "0.22"), qt.Equals, -1)
7176
c.Assert(CompareVersions(MustParseVersion("0.22.1-DEV"), "0.22.1-DEV"), qt.Equals, 0)
77+
78+
c.Assert(CompareVersions(parseIgnoreErr("foobar"), "v1.0.0"), qt.Equals, 1)
79+
c.Assert(CompareVersions(parseIgnoreErr("v1.0.0"), "foobar"), qt.Equals, -1)
80+
c.Assert(CompareVersions(parseIgnoreErr("foobar"), "foobar"), qt.Equals, 0)
81+
c.Assert(CompareVersions(parseIgnoreErr("foobar"), parseIgnoreErr("foobar")), qt.Equals, 0)
82+
c.Assert(CompareVersions(parseIgnoreErr("a"), "b"), qt.Equals, -1)
83+
c.Assert(CompareVersions(parseIgnoreErr("a"), parseIgnoreErr("b")), qt.Equals, -1)
84+
c.Assert(CompareVersions(parseIgnoreErr("b"), "a"), qt.Equals, 1)
85+
c.Assert(CompareVersions(parseIgnoreErr("b"), parseIgnoreErr("a")), qt.Equals, 1)
7286
}
7387

7488
func TestParseHugoVersion(t *testing.T) {

hugolib/sitesmatrix/sitematrix_integration_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,3 +1590,50 @@ Title: {{ .Title }}|
15901590
b.AssertFileContent("public/v1.0.0/p1/index.html", "Title: P1 v1|")
15911591
b.AssertFileContent("public/v2.0.0/p1/index.html", "Title: P1 v1|")
15921592
}
1593+
1594+
func TestSitesMatrixFileMountThemeIssue14414(t *testing.T) {
1595+
t.Parallel()
1596+
1597+
files := `
1598+
-- hugo.toml --
1599+
1600+
disableKinds = ["taxonomy", "term", "rss", "sitemap"]
1601+
defaultContentVersion = "v1"
1602+
defaultContentVersionInSubDir = true
1603+
1604+
[versions]
1605+
[versions."v1"]
1606+
[versions."v2"]
1607+
1608+
[module]
1609+
[[module.mounts]]
1610+
source = 'content'
1611+
target = 'content'
1612+
[module.mounts.sites.matrix]
1613+
versions = '> v2.0.0'
1614+
[[module.imports]]
1615+
ignoreConfig = true
1616+
path = 'mytheme'
1617+
[[module.imports.mounts]]
1618+
source = 'content'
1619+
target = 'content'
1620+
[module.imports.mounts.sites.matrix]
1621+
versions = '<= v2.0.0'
1622+
1623+
-- themes/mytheme/content/p1.md --
1624+
---
1625+
title: "P1 from theme"
1626+
---
1627+
-- content/p1.md --
1628+
---
1629+
title: "P1 from site"
1630+
---
1631+
-- layouts/all.html --
1632+
Title: {{ .Title }}|Version: {{ .Site.Version.Name }}|
1633+
1634+
`
1635+
1636+
b := hugolib.Test(t, files)
1637+
1638+
b.AssertFileContent("public/v1/p1/index.html", "Title: P1 from theme|Version: v1|")
1639+
}

hugolib/versions/versions.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ type VersionInternal struct {
6464
// Name of the version.
6565
// This is the key from the config.
6666
Name string
67+
68+
// Parsed version of Name.
69+
parsedVersion version.Version
70+
6771
// Whether this version is the default version.
6872
// This will be by default rendered in the root.
6973
// There can only be one default version.
@@ -104,6 +108,15 @@ func (r VersionsInternal) ResolveIndex(name string) int {
104108
return i
105109
}
106110
}
111+
// Compare against parsed versions as well.
112+
v, err := version.ParseVersion(name)
113+
if err == nil {
114+
for i, version := range r.Sorted {
115+
if version.parsedVersion.Compare(v) == 0 {
116+
return i
117+
}
118+
}
119+
}
107120
return -1
108121
}
109122

@@ -161,15 +174,17 @@ func (r *VersionsInternal) init(defaultContentVersion string) error {
161174
defaultSeen = true
162175
}
163176

164-
r.Sorted = append(r.Sorted, VersionInternal{Name: k, Default: isDefault, VersionConfig: v})
177+
// Ignore error, this may not be a semver version.
178+
parsedVersion, _ := version.ParseVersion(k)
179+
180+
r.Sorted = append(r.Sorted, VersionInternal{Name: k, parsedVersion: parsedVersion, Default: isDefault, VersionConfig: v})
165181
}
166182

167183
// Sort by weight if set, then semver descending.
168184
sort.SliceStable(r.Sorted, func(i, j int) bool {
169185
ri, rj := r.Sorted[i], r.Sorted[j]
170186
if ri.Weight == rj.Weight {
171-
v1, v2 := version.MustParseVersion(ri.Name), version.MustParseVersion(rj.Name)
172-
return v1.Compare(v2) < 0
187+
return ri.parsedVersion.Compare(rj.parsedVersion) < 0
173188
}
174189
if rj.Weight == 0 {
175190
return true

0 commit comments

Comments
 (0)