Commit 38dc7950 authored by Bryan C. Mills's avatar Bryan C. Mills Committed by Russ Cox

cmd/go: allow unversioned paths to -dropreplace flag

We can add unversioned paths via -replace;
-dropreplace must be able to drop them.

Fixes #26417.

Change-Id: Ic05e9ae2ad80c008e11b195695cbb9d0fc8dbc0a
Reviewed-on: https://go-review.googlesource.com/126155
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarRuss Cox <rsc@golang.org>
parent 52cc9e37
......@@ -63,12 +63,13 @@ The -exclude=path@version and -dropexclude=path@version flags
add and drop an exclusion for the given module path and version.
Note that -exclude=path@version is a no-op if that exclusion already exists.
The -replace=old@v=new@w and -dropreplace=old@v flags
The -replace=old[@v]=new[@w] and -dropreplace=old[@v] flags
add and drop a replacement of the given module path and version pair.
If the @v in old@v is omitted, the replacement applies to all versions
with the old module path. If the @v in new@v is omitted, the
new path should be a directory on the local system, not a module path.
Note that -replace overrides any existing replacements for old@v.
with the old module path. If the @w in new@w is omitted, the
new path should be a directory on the local system containing
source for a module, not a module path.
Note that -replace overrides any existing replacements for old[@v].
These editing flags (-require, -droprequire, -exclude, -dropexclude,
-replace, and -dropreplace) may be repeated.
......@@ -362,6 +363,25 @@ func parsePath(flag, arg string) (path string) {
return path
}
// parsePathVersionOptional parses path[@version], using adj to
// describe any errors.
func parsePathVersionOptional(adj, arg string, allowDirPath bool) (path, version string, err error) {
if i := strings.Index(arg, "@"); i < 0 {
path = arg
} else {
path, version = strings.TrimSpace(arg[:i]), strings.TrimSpace(arg[i+1:])
}
if err := module.CheckPath(path); err != nil {
if !allowDirPath || !modfile.IsDirectoryPath(path) {
return path, version, fmt.Errorf("invalid %s path: %v", adj, err)
}
}
if path != arg && modfile.MustQuote(version) {
return path, version, fmt.Errorf("invalid %s version: %q", adj, version)
}
return path, version, nil
}
// flagRequire implements the -require flag.
func flagRequire(arg string) {
path, version := parsePathVersion("require", arg)
......@@ -406,39 +426,23 @@ func flagDropExclude(arg string) {
func flagReplace(arg string) {
var i int
if i = strings.Index(arg, "="); i < 0 {
base.Fatalf("go mod: -replace=%s: need old@v=new[@v] (missing =)", arg)
base.Fatalf("go mod: -replace=%s: need old[@v]=new[@w] (missing =)", arg)
}
old, new := strings.TrimSpace(arg[:i]), strings.TrimSpace(arg[i+1:])
if strings.HasPrefix(new, ">") {
base.Fatalf("go mod: -replace=%s: separator between old and new is =, not =>", arg)
}
var oldPath, oldVersion string
if i = strings.Index(old, "@"); i < 0 {
oldPath = old
} else {
oldPath, oldVersion = strings.TrimSpace(old[:i]), strings.TrimSpace(old[i+1:])
}
if err := module.CheckPath(oldPath); err != nil {
base.Fatalf("go mod: -replace=%s: invalid old path: %v", arg, err)
}
if oldPath != old && modfile.MustQuote(oldVersion) {
base.Fatalf("go mod: -replace=%s: invalid old version %q", arg, oldVersion)
}
var newPath, newVersion string
if i = strings.Index(new, "@"); i >= 0 {
newPath, newVersion = strings.TrimSpace(new[:i]), strings.TrimSpace(new[i+1:])
if err := module.CheckPath(newPath); err != nil {
base.Fatalf("go mod: -replace=%s: invalid new path: %v", arg, err)
oldPath, oldVersion, err := parsePathVersionOptional("old", old, false)
if err != nil {
base.Fatalf("go mod: -replace=%s: %v", arg, err)
}
if modfile.MustQuote(newVersion) {
base.Fatalf("go mod: -replace=%s: invalid new version %q", arg, newVersion)
newPath, newVersion, err := parsePathVersionOptional("new", new, true)
if err != nil {
base.Fatalf("go mod: -replace=%s: %v", arg, err)
}
} else {
if !modfile.IsDirectoryPath(new) {
if newPath == new && !modfile.IsDirectoryPath(new) {
base.Fatalf("go mod: -replace=%s: unversioned new path must be local directory", arg)
}
newPath = new
}
modEdits = append(modEdits, func(f *modfile.File) {
if err := f.AddReplace(oldPath, oldVersion, newPath, newVersion); err != nil {
......@@ -449,7 +453,10 @@ func flagReplace(arg string) {
// flagDropReplace implements the -dropreplace flag.
func flagDropReplace(arg string) {
path, version := parsePathVersion("dropreplace", arg)
path, version, err := parsePathVersionOptional("old", arg, true)
if err != nil {
base.Fatalf("go mod: -dropreplace=%s: %v", arg, err)
}
modEdits = append(modEdits, func(f *modfile.File) {
if err := f.DropReplace(path, version); err != nil {
base.Fatalf("go mod: -dropreplace=%s: %v", arg, err)
......
......@@ -30,6 +30,8 @@ go mod -replace=x.1@v1.3.0=y.1/v2@v2.3.5 -replace=x.1@v1.4.0=y.1/v2@v2.3.5
cmp go.mod $WORK/go.mod.edit3
go mod -replace=x.1=y.1/v2@v2.3.6
cmp go.mod $WORK/go.mod.edit4
go mod -dropreplace=x.1
cmp go.mod $WORK/go.mod.edit5
# go mod -packages
go mod -packages
......@@ -117,6 +119,12 @@ exclude x.1 v1.2.0
replace x.1 => y.1/v2 v2.3.6
require x.3 v1.99.0
-- $WORK/go.mod.edit5 --
module x.x/y/z
exclude x.1 v1.2.0
require x.3 v1.99.0
-- $WORK/go.mod.packages --
x.x/y/z
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment