mirror of
https://github.com/gohugoio/hugo.git
synced 2026-08-24 07:18:54 +00:00
Allow v1,v2 etc. style version names while still supporting full semver in queries
Fixes #14414
This commit is contained in:
committed by
GitHub
parent
ee91c707ee
commit
ac2c3fb20f
@@ -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 (
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -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) {
|
||||
|
||||
@@ -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|")
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user