modules: Add support for direct version module imports in hugo.toml

Fixes #13964
This commit is contained in:
Bjørn Erik Pedersen
2025-09-05 08:00:39 +02:00
parent d8774d7fc3
commit 747cf4ad65
12 changed files with 562 additions and 84 deletions
+47 -6
View File
@@ -17,6 +17,7 @@
package modules
import (
"net/url"
"time"
"github.com/gohugoio/hugo/config"
@@ -54,6 +55,10 @@ type Module interface {
// or the path below your /theme folder, e.g. "mytheme".
Path() string
// For direct dependencies, this will be Path + "@" + VersionQuery.
// For managed dependencies, this will be the same as Path.
PathVersionQuery(escapeQuery bool) string
// Replaced by this module.
Replace() Module
@@ -63,6 +68,12 @@ type Module interface {
// The module version.
Version() string
// The version query requested in the import.
VersionQuery() string
// The expected cryptographic hash of the module.
Sum() string
// Time version was created.
Time() time.Time
@@ -73,12 +84,13 @@ type Module interface {
type Modules []Module
type moduleAdapter struct {
path string
dir string
version string
vendor bool
projectMod bool
owner Module
path string
dir string
version string
versionQuery string
vendor bool
projectMod bool
owner Module
mounts []Mount
@@ -129,6 +141,23 @@ func (m *moduleAdapter) Path() string {
return m.gomod.Path
}
func (m *moduleAdapter) PathVersionQuery(escapeQuery bool) string {
// We added version as a config option in Hugo v0.150.0, so
// to make this backward compatible, we only add the version
// if it was explicitly requested.
pathBase := m.Path()
if m.versionQuery == "" || !m.IsGoMod() {
return pathBase
}
q := m.versionQuery
if escapeQuery {
q = url.QueryEscape(q)
}
return pathBase + "@" + q
}
func (m *moduleAdapter) Replace() Module {
if m.IsGoMod() && !m.Vendor() && m.gomod.Replace != nil {
return &moduleAdapter{
@@ -150,6 +179,18 @@ func (m *moduleAdapter) Version() string {
return m.gomod.Version
}
func (m *moduleAdapter) VersionQuery() string {
return m.versionQuery
}
func (m *moduleAdapter) Sum() string {
if !m.IsGoMod() {
return ""
}
return m.gomod.Sum
}
func (m *moduleAdapter) Time() time.Time {
if !m.IsGoMod() || m.gomod.Time == nil {
return time.Time{}