// 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 (
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)
}
vv.Suffix = suffix
}
vv.Major, vv.Minor, vv.PatchLevel = parseVersion(s)
+ vv.source = s
return vv, nil
}
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)
}
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)
}
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)
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) {
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|")
+}
// 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.
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
}
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