modules: Ignore non-require blocks in go.mod rewrite

The Go 1.24 tool directive uses single-token entries inside a
tool ( ... ) block. The previous splitter treated any tab-indented
line as a require entry, causing an index out of range panic when
running hugo mod tidy on a module with a tool block.

Track the require block state explicitly so other blocks (tool,
replace, exclude, retract) are left untouched.

Fixes #14783
This commit is contained in:
Bjørn Erik Pedersen
2026-04-20 17:47:12 +02:00
parent 7574e35b40
commit 4169c1f70f
3 changed files with 38 additions and 3 deletions
+16 -2
View File
@@ -1045,18 +1045,32 @@ func (modules goModules) GetMain() *goModule {
func getModlineSplitter(isGoMod bool) func(line string) []string {
if isGoMod {
var inRequireBlock bool
return func(line string) []string {
if strings.HasPrefix(line, "require (") {
inRequireBlock = true
return nil
}
if !strings.HasPrefix(line, "require") && !strings.HasPrefix(line, "\t") {
if inRequireBlock {
if strings.HasPrefix(line, ")") {
inRequireBlock = false
return nil
}
if !strings.HasPrefix(line, "\t") {
return nil
}
} else if !strings.HasPrefix(line, "require ") {
return nil
}
line = strings.TrimPrefix(line, "require")
line = strings.TrimSpace(line)
line = strings.TrimSuffix(line, "// indirect")
return strings.Fields(line)
parts := strings.Fields(line)
if len(parts) < 2 {
return nil
}
return parts
}
}
+14 -1
View File
@@ -210,14 +210,27 @@ func TestGetModlineSplitter(t *testing.T) {
gomodSplitter := getModlineSplitter(true)
c.Assert(gomodSplitter("require ("), qt.IsNil)
c.Assert(gomodSplitter("\tgithub.com/BurntSushi/toml v0.3.1"), qt.DeepEquals, []string{"github.com/BurntSushi/toml", "v0.3.1"})
c.Assert(gomodSplitter("\tgithub.com/cpuguy83/go-md2man v1.0.8 // indirect"), qt.DeepEquals, []string{"github.com/cpuguy83/go-md2man", "v1.0.8"})
c.Assert(gomodSplitter("require ("), qt.IsNil)
gosumSplitter := getModlineSplitter(false)
c.Assert(gosumSplitter("github.com/BurntSushi/toml v0.3.1"), qt.DeepEquals, []string{"github.com/BurntSushi/toml", "v0.3.1"})
}
// Issue 14783
func TestGetModlineSplitterIgnoresToolBlockIssue14783(t *testing.T) {
c := qt.New(t)
gomodSplitter := getModlineSplitter(true)
c.Assert(gomodSplitter("tool ("), qt.IsNil)
c.Assert(gomodSplitter("\tgithub.com/gohugoio/hugo"), qt.IsNil)
c.Assert(gomodSplitter(")"), qt.IsNil)
c.Assert(gomodSplitter("require ("), qt.IsNil)
c.Assert(gomodSplitter("\tgithub.com/foo/bar v1.2.3"), qt.DeepEquals, []string{"github.com/foo/bar", "v1.2.3"})
}
func TestClientConfigToEnv(t *testing.T) {
c := qt.New(t)
+8
View File
@@ -11,9 +11,17 @@ go 1.19
require github.com/bep/empty-hugo-module v1.0.0
tool (
github.com/gohugoio/hugo
)
module github.com/gohugoio/testmod
-- golden/go.mod.cleaned --
go 1.19
tool (
github.com/gohugoio/hugo
)
module github.com/gohugoio/testmod