in modfile/rule.go [462:537]
func parseReplace(filename string, line *Line, verb string, args []string, fix VersionFixer) (*Replace, *Error) {
wrapModPathError := func(modPath string, err error) *Error {
return &Error{
Filename: filename,
Pos: line.Start,
ModPath: modPath,
Verb: verb,
Err: err,
}
}
wrapError := func(err error) *Error {
return &Error{
Filename: filename,
Pos: line.Start,
Err: err,
}
}
errorf := func(format string, args ...interface{}) *Error {
return wrapError(fmt.Errorf(format, args...))
}
arrow := 2
if len(args) >= 2 && args[1] == "=>" {
arrow = 1
}
if len(args) < arrow+2 || len(args) > arrow+3 || args[arrow] != "=>" {
return nil, errorf("usage: %s module/path [v1.2.3] => other/module v1.4\n\t or %s module/path [v1.2.3] => ../local/directory", verb, verb)
}
s, err := parseString(&args[0])
if err != nil {
return nil, errorf("invalid quoted string: %v", err)
}
pathMajor, err := modulePathMajor(s)
if err != nil {
return nil, wrapModPathError(s, err)
}
var v string
if arrow == 2 {
v, err = parseVersion(verb, s, &args[1], fix)
if err != nil {
return nil, wrapError(err)
}
if err := module.CheckPathMajor(v, pathMajor); err != nil {
return nil, wrapModPathError(s, err)
}
}
ns, err := parseString(&args[arrow+1])
if err != nil {
return nil, errorf("invalid quoted string: %v", err)
}
nv := ""
if len(args) == arrow+2 {
if !IsDirectoryPath(ns) {
return nil, errorf("replacement module without version must be directory path (rooted or starting with ./ or ../)")
}
if filepath.Separator == '/' && strings.Contains(ns, `\`) {
return nil, errorf("replacement directory appears to be Windows path (on a non-windows system)")
}
}
if len(args) == arrow+3 {
nv, err = parseVersion(verb, ns, &args[arrow+2], fix)
if err != nil {
return nil, wrapError(err)
}
if IsDirectoryPath(ns) {
return nil, errorf("replacement module directory path %q cannot have version", ns)
}
}
return &Replace{
Old: module.Version{Path: s, Version: v},
New: module.Version{Path: ns, Version: nv},
Syntax: line,
}, nil
}