Skip to content

Commit

Permalink
Test the 'go list -m -json all' parsing logic
Browse files Browse the repository at this point in the history
  • Loading branch information
simnalamburt committed Aug 30, 2021
1 parent 4ecef2c commit fb888ae
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 37 deletions.
84 changes: 47 additions & 37 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,10 +185,7 @@ func runDev(ctx context.Context, args []string) error {

// make sure the module being developed is replaced
// so that the local copy is used
replacements := []xcaddy.Replace{
xcaddy.NewReplace(currentModule, moduleDir),
}

//
// replace directives only apply to the top-level/main go.mod,
// and since this tool is a carry-through for the user's actual
// go.mod, we need to transfer their replace directives through
Expand All @@ -199,39 +196,9 @@ func runDev(ctx context.Context, args []string) error {
if err != nil {
return fmt.Errorf("exec %v: %v: %s", cmd.Args, err, string(out))
}
decoder := json.NewDecoder(bytes.NewReader(out))
for {
var mod map[string]interface{}
if err := decoder.Decode(&mod); err == io.EOF {
break
} else if err != nil {
return fmt.Errorf("json parse error: %v", err)
}
rep, ok := mod["Replace"].(map[string]interface{})
if !ok {
continue
}

srcPath := mod["Path"].(string)
srcVersion := mod["Version"].(string)
src := srcPath + "@" + srcVersion

// 1. Target is module, version is required in this case
// 2A. Target is absolute path
// 2B. Target is relative path, proper handling is required in this case
dstPath := rep["Path"].(string)
dstVersion, isTargetModule := rep["Version"].(string)
var dst string
if isTargetModule {
dst = dstPath + "@" + dstVersion
} else if filepath.IsAbs(dstPath) {
dst = dstPath
} else {
dst = filepath.Join(moduleDir, dstPath)
log.Printf("[INFO] Resolved relative replacement %s to %s", dstPath, dst)
}

replacements = append(replacements, xcaddy.NewReplace(src, dst))
replacements, err := parseGoListJson(currentModule, moduleDir, out)
if err != nil {
return fmt.Errorf("json parse error: %v", err)
}

// reconcile remaining path segments; for example if a module foo/a
Expand Down Expand Up @@ -297,6 +264,49 @@ func runDev(ctx context.Context, args []string) error {
return cmd.Wait()
}

func parseGoListJson(currentModule, moduleDir string, out []byte) ([]xcaddy.Replace, error) {
replacements := []xcaddy.Replace{
xcaddy.NewReplace(currentModule, moduleDir),
}

decoder := json.NewDecoder(bytes.NewReader(out))
for {
var mod map[string]interface{}
if err := decoder.Decode(&mod); err == io.EOF {
break
} else if err != nil {
return nil, err
}
rep, ok := mod["Replace"].(map[string]interface{})
if !ok {
continue
}

srcPath := mod["Path"].(string)
srcVersion := mod["Version"].(string)
src := srcPath + "@" + srcVersion

// 1. Target is module, version is required in this case
// 2A. Target is absolute path
// 2B. Target is relative path, proper handling is required in this case
dstPath := rep["Path"].(string)
dstVersion, isTargetModule := rep["Version"].(string)
var dst string
if isTargetModule {
dst = dstPath + "@" + dstVersion
} else if filepath.IsAbs(dstPath) {
dst = dstPath
} else {
dst = filepath.Join(moduleDir, dstPath)
log.Printf("[INFO] Resolved relative replacement %s to %s", dstPath, dst)
}

replacements = append(replacements, xcaddy.NewReplace(src, dst))
}

return replacements, nil
}

func normalizeImportPath(currentModule, cwd, moduleDir string) string {
return path.Join(currentModule, filepath.ToSlash(strings.TrimPrefix(cwd, moduleDir)))
}
Expand Down
80 changes: 80 additions & 0 deletions cmd/main_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,90 @@
package xcaddycmd

import (
"reflect"
"runtime"
"testing"

"github.com/caddyserver/xcaddy"
)

func TestParseGoListJson(t *testing.T) {
replacements, err := parseGoListJson("module", "/home/work/module", []byte(`
{
"Path": "github.com/simnalamburt/module",
"Main": true,
"Dir": "/home/work/module",
"GoMod": "/home/work/module/go.mod",
"GoVersion": "1.17"
}
{
"Path": "replacetest1",
"Version": "v1.2.3",
"Replace": {
"Path": "golang.org/x/example",
"Version": "v0.0.0-20210811190340-787a929d5a0d",
"Time": "2021-08-11T19:03:40Z",
"GoMod": "/home/simnalamburt/.go/pkg/mod/cache/download/golang.org/x/example/@v/v0.0.0-20210811190340-787a929d5a0d.mod",
"GoVersion": "1.15"
},
"GoMod": "/home/simnalamburt/.go/pkg/mod/cache/download/golang.org/x/example/@v/v0.0.0-20210811190340-787a929d5a0d.mod",
"GoVersion": "1.15"
}
{
"Path": "replacetest2",
"Version": "v0.0.1",
"Replace": {
"Path": "golang.org/x/example",
"Version": "v0.0.0-20210407023211-09c3a5e06b5d",
"Time": "2021-04-07T02:32:11Z",
"GoMod": "/home/simnalamburt/.go/pkg/mod/cache/download/golang.org/x/example/@v/v0.0.0-20210407023211-09c3a5e06b5d.mod",
"GoVersion": "1.15"
},
"GoMod": "/home/simnalamburt/.go/pkg/mod/cache/download/golang.org/x/example/@v/v0.0.0-20210407023211-09c3a5e06b5d.mod",
"GoVersion": "1.15"
}
{
"Path": "replacetest3",
"Version": "v1.2.3",
"Replace": {
"Path": "./fork1",
"Dir": "/home/work/module/fork1",
"GoMod": "/home/work/module/fork1/go.mod",
"GoVersion": "1.17"
},
"Dir": "/home/work/module/fork1",
"GoMod": "/home/work/module/fork1/go.mod",
"GoVersion": "1.17"
}
{
"Path": "replacetest4",
"Version": "v0.0.1",
"Replace": {
"Path": "/srv/fork2",
"Dir": "/home/work/module/fork2",
"GoMod": "/home/work/module/fork2/go.mod",
"GoVersion": "1.17"
},
"Dir": "/home/work/module/fork2",
"GoMod": "/home/work/module/fork2/go.mod",
"GoVersion": "1.17"
}
`))
if err != nil {
t.Errorf("Error occured during JSON parsing")
}
expected := []xcaddy.Replace{
xcaddy.NewReplace("module", "/home/work/module"),
xcaddy.NewReplace("replacetest1@v1.2.3", "golang.org/x/example@v0.0.0-20210811190340-787a929d5a0d"),
xcaddy.NewReplace("replacetest2@v0.0.1", "golang.org/x/example@v0.0.0-20210407023211-09c3a5e06b5d"),
xcaddy.NewReplace("replacetest3@v1.2.3", "/home/work/module/fork1"),
xcaddy.NewReplace("replacetest4@v0.0.1", "/srv/fork2"),
}
if !reflect.DeepEqual(replacements, expected) {
t.Errorf("Expected replacements '%v' but got '%v'", expected, replacements)
}
}

func TestSplitWith(t *testing.T) {
for i, tc := range []struct {
input string
Expand Down

0 comments on commit fb888ae

Please sign in to comment.