Skip to content

Commit

Permalink
Support replacing module with different version
Browse files Browse the repository at this point in the history
  • Loading branch information
harry-hov committed Feb 28, 2023
1 parent 3291945 commit 4f4b82e
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 40 deletions.
12 changes: 12 additions & 0 deletions pkgs/gnolang/gnomod/gnomod.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,18 @@ func GnoToGoMod(f File) (*File, error) {
})
}

// Since we already fetched and replaced replacement modules
// with `/pkg/gnomod/...` path.
// Ignore leftovers.
var repl []*modfile.Replace
for _, r := range f.Replace {
if !modfile.IsDirectoryPath(r.New.Path) {
continue
}
repl = append(repl, r)
}
f.Replace = repl

return &f, nil
}

Expand Down
40 changes: 0 additions & 40 deletions pkgs/gnolang/gnomod/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package gnomod

import (
"fmt"
"path/filepath"
"reflect"
"strings"

Expand Down Expand Up @@ -143,42 +142,3 @@ func (f *File) add(errs *modfile.ErrorList, block *modfile.LineBlock, line *modf
f.Replace = append(f.Replace, replace)
}
}

func parseReplace(filename string, line *modfile.Line, verb string, args []string) (*modfile.Replace, *modfile.Error) {
wrapError := func(err error) *modfile.Error {
return &modfile.Error{
Filename: filename,
Pos: line.Start,
Err: err,
}
}
errorf := func(format string, args ...interface{}) *modfile.Error {
return wrapError(fmt.Errorf(format, args...))
}

if len(args) != 3 || args[1] != "=>" {
return nil, errorf("usage: %s module/path => ../local/directory", verb)
}
s, err := parseString(&args[0])
if err != nil {
return nil, errorf("invalid quoted string: %v", err)
}

ns, err := parseString(&args[2])
if err != nil {
return nil, errorf("invalid quoted string: %v", err)
}

if !modfile.IsDirectoryPath(ns) {
return nil, errorf("replacement module 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)")
}

return &modfile.Replace{
Old: module.Version{Path: s, Version: "v0.0.0"},
New: module.Version{Path: ns},
Syntax: line,
}, nil
}
87 changes: 87 additions & 0 deletions pkgs/gnolang/gnomod/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"errors"
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"unicode"
Expand Down Expand Up @@ -661,6 +662,14 @@ func ModulePath(mod []byte) string {
return "" // missing module path
}

func modulePathMajor(path string) (string, error) {
_, major, ok := module.SplitPathVersion(path)
if !ok {
return "", fmt.Errorf("invalid module path")
}
return major, nil
}

func parseString(s *string) (string, error) {
t := *s
if strings.HasPrefix(t, `"`) {
Expand Down Expand Up @@ -706,3 +715,81 @@ func parseVersion(verb string, path string, s *string) (string, error) {
*s = cv
return *s, nil
}

func parseReplace(filename string, line *modfile.Line, verb string, args []string) (*modfile.Replace, *modfile.Error) {
wrapModPathError := func(modPath string, err error) *modfile.Error {
return &modfile.Error{
Filename: filename,
Pos: line.Start,
ModPath: modPath,
Verb: verb,
Err: err,
}
}
wrapError := func(err error) *modfile.Error {
return &modfile.Error{
Filename: filename,
Pos: line.Start,
Err: err,
}
}
errorf := func(format string, args ...interface{}) *modfile.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])
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 !modfile.IsDirectoryPath(ns) {
if strings.Contains(ns, "@") {
return nil, errorf("replacement module must match format 'path version', not 'path@version'")
}
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])
if err != nil {
return nil, wrapError(err)
}
if modfile.IsDirectoryPath(ns) {
return nil, errorf("replacement module directory path %q cannot have version", ns)
}
}
return &modfile.Replace{
Old: module.Version{Path: s, Version: v},
New: module.Version{Path: ns, Version: nv},
Syntax: line,
}, nil
}

0 comments on commit 4f4b82e

Please sign in to comment.