feat(goctl): go work multi-module support (#1800)

* feat(goctl): go work multi-module support

Resolve: #1793

* chore: print log when getting project ctx fails
master
Fyn 3 years ago committed by GitHub
parent 92b450eb11
commit e62870e268
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -12,6 +12,9 @@ import (
"github.com/zeromicro/go-zero/tools/goctl/vars"
)
// RunFunc defines a function type of Run function
type RunFunc func(string, string, ...*bytes.Buffer) (string, error)
// Run provides the execution of shell scripts in golang,
// which can support macOS, Windows, and Linux operating systems.
// Other operating systems are currently not supported

@ -2,6 +2,7 @@ package ctx
import (
"errors"
"fmt"
"path/filepath"
"github.com/zeromicro/go-zero/tools/goctl/rpc/execx"
@ -31,6 +32,7 @@ func Prepare(workDir string) (*ProjectContext, error) {
if err == nil {
return ctx, nil
}
fmt.Printf("get project context from workdir[%s] failed: %s\n", workDir, err)
name := filepath.Base(workDir)
_, err = execx.Run("go mod init "+name, workDir)

@ -1,11 +1,14 @@
package ctx
import (
"encoding/json"
"errors"
"fmt"
"io"
"os"
"path/filepath"
"strings"
"github.com/zeromicro/go-zero/core/jsonx"
"github.com/zeromicro/go-zero/tools/goctl/rpc/execx"
"github.com/zeromicro/go-zero/tools/goctl/util/pathx"
)
@ -36,16 +39,11 @@ func projectFromGoMod(workDir string) (*ProjectContext, error) {
return nil, err
}
data, err := execx.Run("go list -json -m", workDir)
m, err := getRealModule(workDir, execx.Run)
if err != nil {
return nil, err
}
var m Module
err = jsonx.Unmarshal([]byte(data), &m)
if err != nil {
return nil, err
}
var ret ProjectContext
ret.WorkDir = workDir
ret.Name = filepath.Base(m.Dir)
@ -58,3 +56,34 @@ func projectFromGoMod(workDir string) (*ProjectContext, error) {
ret.Path = m.Path
return &ret, nil
}
func getRealModule(workDir string, execRun execx.RunFunc) (*Module, error) {
data, err := execRun("go list -json -m", workDir)
if err != nil {
return nil, err
}
modules, err := decodePackages(strings.NewReader(data))
if err != nil {
return nil, err
}
for _, m := range modules {
if strings.HasPrefix(workDir, m.Dir) {
return &m, nil
}
}
return nil, errors.New("no matched module")
}
func decodePackages(rc io.Reader) ([]Module, error) {
var modules []Module
decoder := json.NewDecoder(rc)
for decoder.More() {
var m Module
if err := decoder.Decode(&m); err != nil {
return nil, fmt.Errorf("invalid module: %v", err)
}
modules = append(modules, m)
}
return modules, nil
}

@ -1,9 +1,11 @@
package ctx
import (
"bytes"
"go/build"
"os"
"path/filepath"
"reflect"
"testing"
"github.com/stretchr/testify/assert"
@ -36,3 +38,75 @@ func TestProjectFromGoMod(t *testing.T) {
assert.Equal(t, projectName, ctx.Path)
assert.Equal(t, dir, ctx.Dir)
}
func Test_getRealModule(t *testing.T) {
type args struct {
workDir string
execRun execx.RunFunc
}
tests := []struct {
name string
args args
want *Module
wantErr bool
}{
{
name: "single module",
args: args{
workDir: "/home/foo",
execRun: func(arg, dir string, in ...*bytes.Buffer) (string, error) {
return `{
"Path":"foo",
"Dir":"/home/foo",
"GoMod":"/home/foo/go.mod",
"GoVersion":"go1.16"}`, nil
},
},
want: &Module{
Path: "foo",
Dir: "/home/foo",
GoMod: "/home/foo/go.mod",
GoVersion: "go1.16",
},
},
{
name: "go work multiple modules",
args: args{
workDir: "/home/bar",
execRun: func(arg, dir string, in ...*bytes.Buffer) (string, error) {
return `
{
"Path":"foo",
"Dir":"/home/foo",
"GoMod":"/home/foo/go.mod",
"GoVersion":"go1.18"
}
{
"Path":"bar",
"Dir":"/home/bar",
"GoMod":"/home/bar/go.mod",
"GoVersion":"go1.18"
}`, nil
},
},
want: &Module{
Path: "bar",
Dir: "/home/bar",
GoMod: "/home/bar/go.mod",
GoVersion: "go1.18",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := getRealModule(tt.args.workDir, tt.args.execRun)
if (err != nil) != tt.wantErr {
t.Errorf("getRealModule() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("getRealModule() = %v, want %v", got, tt.want)
}
})
}
}

@ -4,7 +4,6 @@ import (
"errors"
"os"
"github.com/zeromicro/go-zero/core/jsonx"
"github.com/zeromicro/go-zero/tools/goctl/rpc/execx"
)
@ -17,16 +16,10 @@ func IsGoMod(workDir string) (bool, error) {
return false, err
}
data, err := execx.Run("go list -json -m", workDir)
if err != nil {
data, err := execx.Run("go list -m -f '{{.GoMod}}'", workDir)
if err != nil || len(data) == 0 {
return false, nil
}
var m Module
err = jsonx.Unmarshal([]byte(data), &m)
if err != nil {
return false, err
}
return len(m.GoMod) > 0, nil
return true, nil
}

Loading…
Cancel
Save