mirror of
https://github.com/zeromicro/go-zero.git
synced 2025-02-02 16:28:39 +08:00
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
This commit is contained in:
parent
92b450eb11
commit
e62870e268
@ -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…
Reference in New Issue
Block a user