From e75bb92ef0ef1dd15f4f65fbf753404e87614c07 Mon Sep 17 00:00:00 2001
From: Yanchen Chen <yanchen1610@gmail.com>
Date: Thu, 3 Apr 2025 00:11:07 +0800
Subject: [PATCH 1/4] cmd/go/internal/modload: don't infer a /v1 suffix module
 path

---
 src/cmd/go/internal/modload/init.go | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/src/cmd/go/internal/modload/init.go b/src/cmd/go/internal/modload/init.go
index 41b3b9df1ba20c..e274eec0cf76d7 100644
--- a/src/cmd/go/internal/modload/init.go
+++ b/src/cmd/go/internal/modload/init.go
@@ -1710,6 +1710,15 @@ func findModulePath(dir string) (string, error) {
 				badPathErr = err
 				break
 			}
+			// Ensure the inferred path is valid.
+			if _, _, ok := module.SplitPathVersion(path); !ok {
+				if strings.HasPrefix(path, "gopkg.in/") {
+					badPathErr = errors.New("module paths beginning with gopkg.in/ must always have a major version suffix in the form of .vN")
+				} else {
+					badPathErr = errors.New("major version suffixes must be in the form of /vN and are only allowed for v2 or later")
+				}
+				break
+			}
 			return path, nil
 		}
 	}
@@ -1725,6 +1734,7 @@ func findModulePath(dir string) (string, error) {
 Example usage:
 	'go mod init example.com/m' to initialize a v0 or v1 module
 	'go mod init example.com/m/v2' to initialize a v2 module
+	'go mod init gopkg.in/m.v1' to initialize a gopkg.in module
 
 Run 'go help mod init' for more information.
 `

From 5f0c4511af8ebbcda559688ff92b60b5b4da1cbe Mon Sep 17 00:00:00 2001
From: Yanchen Chen <yanchen1610@gmail.com>
Date: Thu, 3 Apr 2025 20:37:58 +0800
Subject: [PATCH 2/4] cmd/go/internal/modload: remove example for gopkg.in
 module initialization

---
 src/cmd/go/internal/modload/init.go | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/cmd/go/internal/modload/init.go b/src/cmd/go/internal/modload/init.go
index e274eec0cf76d7..feee871fc44145 100644
--- a/src/cmd/go/internal/modload/init.go
+++ b/src/cmd/go/internal/modload/init.go
@@ -1734,7 +1734,6 @@ func findModulePath(dir string) (string, error) {
 Example usage:
 	'go mod init example.com/m' to initialize a v0 or v1 module
 	'go mod init example.com/m/v2' to initialize a v2 module
-	'go mod init gopkg.in/m.v1' to initialize a gopkg.in module
 
 Run 'go help mod init' for more information.
 `

From 9946437fd13e3a142d0339b1e4e28c2f2460ec47 Mon Sep 17 00:00:00 2001
From: Yanchen Chen <yanchen1610@gmail.com>
Date: Fri, 4 Apr 2025 00:01:35 +0800
Subject: [PATCH 3/4] cmd/go/testdata: add tests for 'go mod init' in v0 and v1
 directories

---
 src/cmd/go/testdata/script/mod_init_empty.txt | 23 +++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/src/cmd/go/testdata/script/mod_init_empty.txt b/src/cmd/go/testdata/script/mod_init_empty.txt
index d197a79a67180c..beb41c81c859cb 100644
--- a/src/cmd/go/testdata/script/mod_init_empty.txt
+++ b/src/cmd/go/testdata/script/mod_init_empty.txt
@@ -8,6 +8,22 @@ stdout '^example.com$'
 go list
 stdout '^example.com$'
 
+# Reset $GOPATH
+env GOPATH=$WORK/gopath
+
+# 'go mod init' should not create a go.mod file in v0 or v1 directory.
+cd $GOPATH/src/example.com/m/v0
+! go mod init
+stderr '(?s)^go: cannot determine module path for source directory(.*)example.com/m/v0 \(bad module path inferred from directory in GOPATH: major version suffixes must be in the form of /vN and are only allowed for v2 or later\)(.*)Example usage:(.*)''go mod init example.com/m'' to initialize a v0 or v1 module(.*)''go mod init example.com/m/v2'' to initialize a v2 module(.*)Run ''go help mod init'' for more information.$'
+
+cd $GOPATH/src/example.com/m/v1
+! go mod init
+stderr '(?s)^go: cannot determine module path for source directory(.*)example.com/m/v1 \(bad module path inferred from directory in GOPATH: major version suffixes must be in the form of /vN and are only allowed for v2 or later\)(.*)Example usage:(.*)''go mod init example.com/m'' to initialize a v0 or v1 module(.*)''go mod init example.com/m/v2'' to initialize a v2 module(.*)Run ''go help mod init'' for more information.$'
+
+cd $GOPATH/src/example.com/m/v2
+go mod init
+stderr '^go: creating new go.mod: module example.com/m/v2$'
+
 -- go.mod --
 module example.com
 
@@ -19,3 +35,10 @@ func main() {}
 
 -- $WORK/invalid-gopath
 This is a text file, not a directory.
+
+-- example.com/m/v0/main.go --
+package main
+-- example.com/m/v1/main.go --
+package main
+-- example.com/m/v2/main.go --
+package main

From 612ed5e27be4dd2285e862ac0b410f26ebd644b6 Mon Sep 17 00:00:00 2001
From: Yanchen Chen <yanchen1610@gmail.com>
Date: Mon, 7 Apr 2025 08:56:35 +0800
Subject: [PATCH 4/4] cmd/go/testdata: make matches shorter and add gopkg.in
 module test case

---
 src/cmd/go/testdata/script/mod_init_empty.txt | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/src/cmd/go/testdata/script/mod_init_empty.txt b/src/cmd/go/testdata/script/mod_init_empty.txt
index beb41c81c859cb..2ae22271f03b0f 100644
--- a/src/cmd/go/testdata/script/mod_init_empty.txt
+++ b/src/cmd/go/testdata/script/mod_init_empty.txt
@@ -14,16 +14,20 @@ env GOPATH=$WORK/gopath
 # 'go mod init' should not create a go.mod file in v0 or v1 directory.
 cd $GOPATH/src/example.com/m/v0
 ! go mod init
-stderr '(?s)^go: cannot determine module path for source directory(.*)example.com/m/v0 \(bad module path inferred from directory in GOPATH: major version suffixes must be in the form of /vN and are only allowed for v2 or later\)(.*)Example usage:(.*)''go mod init example.com/m'' to initialize a v0 or v1 module(.*)''go mod init example.com/m/v2'' to initialize a v2 module(.*)Run ''go help mod init'' for more information.$'
+stderr '(?s)^go: cannot determine module path for source directory (.*v0) \(bad module path inferred from directory in GOPATH: major version suffixes must be in the form of /vN and are only allowed for v2 or later\)(.*)'
 
 cd $GOPATH/src/example.com/m/v1
 ! go mod init
-stderr '(?s)^go: cannot determine module path for source directory(.*)example.com/m/v1 \(bad module path inferred from directory in GOPATH: major version suffixes must be in the form of /vN and are only allowed for v2 or later\)(.*)Example usage:(.*)''go mod init example.com/m'' to initialize a v0 or v1 module(.*)''go mod init example.com/m/v2'' to initialize a v2 module(.*)Run ''go help mod init'' for more information.$'
+stderr '(?s)^go: cannot determine module path for source directory (.*v1) \(bad module path inferred from directory in GOPATH: major version suffixes must be in the form of /vN and are only allowed for v2 or later\)(.*)'
 
 cd $GOPATH/src/example.com/m/v2
 go mod init
 stderr '^go: creating new go.mod: module example.com/m/v2$'
 
+cd $GOPATH/src/gopkg.in/m
+! go mod init
+stderr '(?s)^go: cannot determine module path for source directory (.*m) \(bad module path inferred from directory in GOPATH: module paths beginning with gopkg.in/ must always have a major version suffix in the form of .vN\)(.*)'
+
 -- go.mod --
 module example.com
 
@@ -42,3 +46,5 @@ package main
 package main
 -- example.com/m/v2/main.go --
 package main
+-- gopkg.in/m/main.go --
+package main