Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions common/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ type Version struct {
// HugoVersionSuffix is the suffix used in the Hugo version string.
// It will be blank for release versions.
Suffix string

// Set when parsed from a string,
source string
}

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

func (v Version) IsZero() bool {
return v.Major == 0 && v.Minor == 0 && v.PatchLevel == 0 && v.Suffix == ""
}

func (v Version) String() string {
return version(v.Major, v.Minor, v.PatchLevel, v.Suffix)
}
Expand Down Expand Up @@ -109,6 +116,7 @@ func ParseVersion(s string) (Version, error) {
vv.Suffix = suffix
}
vv.Major, vv.Minor, vv.PatchLevel = parseVersion(s)
vv.source = s

return vv, nil
}
Expand Down Expand Up @@ -176,6 +184,10 @@ func CompareVersions(v1 Version, v2 any) int {
case int64:
c = compareFloatWithVersion(float64(d), v1)
case Version:
if v1.IsZero() && d.IsZero() {
// Fall back to source comparison.
return strings.Compare(v1.source, d.source)
}
if d.Major == v1.Major && d.Minor == v1.Minor && d.PatchLevel == v1.PatchLevel {
return strings.Compare(v1.Suffix, d.Suffix)
}
Expand All @@ -200,11 +212,13 @@ func CompareVersions(v1 Version, v2 any) int {
return -1
}

v, err := ParseVersion(s)
if err != nil {
return -1
v2v, _ := ParseVersion(s)
if v1.IsZero() && v2v.IsZero() {
// Fall back to source comparison.
return strings.Compare(v1.source, v2v.source)
}
return v1.Compare(v)

return v1.Compare(v2v)

}

Expand Down
14 changes: 14 additions & 0 deletions common/version/version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ func TestHugoVersion(t *testing.T) {
func TestCompareVersions(t *testing.T) {
c := qt.New(t)

parseIgnoreErr := func(s string) Version {
v, _ := ParseVersion(s)
return v
}

c.Assert(CompareVersions(MustParseVersion("0.20.0"), 0.20), qt.Equals, 0)
c.Assert(CompareVersions(MustParseVersion("0.20.0"), float32(0.20)), qt.Equals, 0)
c.Assert(CompareVersions(MustParseVersion("0.20.0"), float64(0.20)), qt.Equals, 0)
Expand All @@ -69,6 +74,15 @@ func TestCompareVersions(t *testing.T) {
c.Assert(CompareVersions(MustParseVersion("0.22.0-DEV"), "0.22"), qt.Equals, 1)
c.Assert(CompareVersions(MustParseVersion("0.22.1-DEV"), "0.22"), qt.Equals, -1)
c.Assert(CompareVersions(MustParseVersion("0.22.1-DEV"), "0.22.1-DEV"), qt.Equals, 0)

c.Assert(CompareVersions(parseIgnoreErr("foobar"), "v1.0.0"), qt.Equals, 1)
c.Assert(CompareVersions(parseIgnoreErr("v1.0.0"), "foobar"), qt.Equals, -1)
c.Assert(CompareVersions(parseIgnoreErr("foobar"), "foobar"), qt.Equals, 0)
c.Assert(CompareVersions(parseIgnoreErr("foobar"), parseIgnoreErr("foobar")), qt.Equals, 0)
c.Assert(CompareVersions(parseIgnoreErr("a"), "b"), qt.Equals, -1)
c.Assert(CompareVersions(parseIgnoreErr("a"), parseIgnoreErr("b")), qt.Equals, -1)
c.Assert(CompareVersions(parseIgnoreErr("b"), "a"), qt.Equals, 1)
c.Assert(CompareVersions(parseIgnoreErr("b"), parseIgnoreErr("a")), qt.Equals, 1)
}

func TestParseHugoVersion(t *testing.T) {
Expand Down
47 changes: 47 additions & 0 deletions hugolib/sitesmatrix/sitematrix_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1590,3 +1590,50 @@ Title: {{ .Title }}|
b.AssertFileContent("public/v1.0.0/p1/index.html", "Title: P1 v1|")
b.AssertFileContent("public/v2.0.0/p1/index.html", "Title: P1 v1|")
}

func TestSitesMatrixFileMountThemeIssue14414(t *testing.T) {
t.Parallel()

files := `
-- hugo.toml --

disableKinds = ["taxonomy", "term", "rss", "sitemap"]
defaultContentVersion = "v1"
defaultContentVersionInSubDir = true

[versions]
[versions."v1"]
[versions."v2"]

[module]
[[module.mounts]]
source = 'content'
target = 'content'
[module.mounts.sites.matrix]
versions = '> v2.0.0'
[[module.imports]]
ignoreConfig = true
path = 'mytheme'
[[module.imports.mounts]]
source = 'content'
target = 'content'
[module.imports.mounts.sites.matrix]
versions = '<= v2.0.0'

-- themes/mytheme/content/p1.md --
---
title: "P1 from theme"
---
-- content/p1.md --
---
title: "P1 from site"
---
-- layouts/all.html --
Title: {{ .Title }}|Version: {{ .Site.Version.Name }}|

`

b := hugolib.Test(t, files)

b.AssertFileContent("public/v1/p1/index.html", "Title: P1 from theme|Version: v1|")
}
21 changes: 18 additions & 3 deletions hugolib/versions/versions.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ type VersionInternal struct {
// Name of the version.
// This is the key from the config.
Name string

// Parsed version of Name.
parsedVersion version.Version

// Whether this version is the default version.
// This will be by default rendered in the root.
// There can only be one default version.
Expand Down Expand Up @@ -104,6 +108,15 @@ func (r VersionsInternal) ResolveIndex(name string) int {
return i
}
}
// Compare against parsed versions as well.
v, err := version.ParseVersion(name)
if err == nil {
for i, version := range r.Sorted {
if version.parsedVersion.Compare(v) == 0 {
return i
}
}
}
return -1
}

Expand Down Expand Up @@ -161,15 +174,17 @@ func (r *VersionsInternal) init(defaultContentVersion string) error {
defaultSeen = true
}

r.Sorted = append(r.Sorted, VersionInternal{Name: k, Default: isDefault, VersionConfig: v})
// Ignore error, this may not be a semver version.
parsedVersion, _ := version.ParseVersion(k)

r.Sorted = append(r.Sorted, VersionInternal{Name: k, parsedVersion: parsedVersion, Default: isDefault, VersionConfig: v})
}

// Sort by weight if set, then semver descending.
sort.SliceStable(r.Sorted, func(i, j int) bool {
ri, rj := r.Sorted[i], r.Sorted[j]
if ri.Weight == rj.Weight {
v1, v2 := version.MustParseVersion(ri.Name), version.MustParseVersion(rj.Name)
return v1.Compare(v2) < 0
return ri.parsedVersion.Compare(rj.parsedVersion) < 0
}
if rj.Weight == 0 {
return true
Expand Down