From 2e62e52ae2ccf25b1391d73d0e4a363756580e28 Mon Sep 17 00:00:00 2001 From: luruichao <110596971+chaoranz758@users.noreply.github.com> Date: Tue, 10 Oct 2023 14:43:45 +0800 Subject: [PATCH] optimize: independent util package (#85) * independent util package * Update conf_tpl.yaml * format * format --- pkg/client/check.go | 4 +- pkg/client/kitex.go | 33 ++----- pkg/common/utils/env.go | 113 ++++++++++++++++++++++++ pkg/common/utils/file.go | 15 ++-- pkg/common/utils/hz.go | 3 +- pkg/server/check.go | 3 +- pkg/server/kitex.go | 40 +++------ pkg/server/server.go | 5 +- tpl/kitex/server/standard/conf_tpl.yaml | 19 ++-- 9 files changed, 162 insertions(+), 73 deletions(-) diff --git a/pkg/client/check.go b/pkg/client/check.go index f1058fe5..2309c85e 100644 --- a/pkg/client/check.go +++ b/pkg/client/check.go @@ -24,8 +24,8 @@ import ( "strings" "github.com/cloudwego/cwgo/config" + "github.com/cloudwego/cwgo/pkg/common/utils" "github.com/cloudwego/cwgo/pkg/consts" - "github.com/cloudwego/hertz/cmd/hz/util" ) func check(ca *config.ClientArgument) error { @@ -63,7 +63,7 @@ func check(ca *config.ClientArgument) error { ca.OutDir = ap } - gopath, err := util.GetGOPATH() + gopath, err := utils.GetGOPATH() if err != nil { return fmt.Errorf("get gopath failed: %s", err) } diff --git a/pkg/client/kitex.go b/pkg/client/kitex.go index b98bee92..a83b41d4 100644 --- a/pkg/client/kitex.go +++ b/pkg/client/kitex.go @@ -33,7 +33,6 @@ import ( kargs "github.com/cloudwego/kitex/tool/cmd/kitex/args" "github.com/cloudwego/kitex/tool/internal_pkg/generator" "github.com/cloudwego/kitex/tool/internal_pkg/log" - "github.com/cloudwego/kitex/tool/internal_pkg/util" ) func convertKitexArgs(sa *config.ClientArgument, kitexArgument *kargs.Arguments) (err error) { @@ -118,7 +117,7 @@ Flags: } func checkKitexArgs(a *kargs.Arguments) (err error) { - // check IDL` + // check IDL a.IDLType, err = utils.GetIdlType(a.IDL, consts.Protobuf) if err != nil { return err @@ -132,14 +131,15 @@ func checkKitexArgs(a *kargs.Arguments) (err error) { } } - // check path - pathToGo, err := exec.LookPath("go") + gopath, err := utils.GetGOPATH() if err != nil { - log.Warn(err) - os.Exit(1) + return fmt.Errorf("get gopath failed: %s", err) + } + if gopath == "" { + return fmt.Errorf("GOPATH is not set") } - gosrc := filepath.Join(util.GetGOPATH(), "src") + gosrc := filepath.Join(gopath, "src") gosrc, err = filepath.Abs(gosrc) if err != nil { log.Warn("Get GOPATH/src path failed:", err.Error()) @@ -165,7 +165,7 @@ func checkKitexArgs(a *kargs.Arguments) (err error) { } if a.ModuleName != "" { - module, path, ok := util.SearchGoMod(curpath) + module, path, ok := utils.SearchGoMod(curpath, true) if ok { // go.mod exists if module != a.ModuleName { @@ -179,7 +179,7 @@ func checkKitexArgs(a *kargs.Arguments) (err error) { } a.PackagePrefix = filepath.Join(a.ModuleName, a.PackagePrefix, generator.KitexGenPath) } else { - if err = initGoMod(pathToGo, a.ModuleName); err != nil { + if err = utils.InitGoMod(a.ModuleName); err != nil { log.Warn("Init go mod failed:", err.Error()) os.Exit(1) } @@ -207,18 +207,3 @@ func replaceThriftVersion(args *kargs.Arguments) { log.Warn("Adding apache/thrift@v0.13.0 to go.mod for generated code ..........", res) } } - -func initGoMod(pathToGo, module string) error { - if util.Exists("go.mod") { - return nil - } - - cmd := &exec.Cmd{ - Path: pathToGo, - Args: []string{"go", "mod", "init", module}, - Stdin: os.Stdin, - Stdout: os.Stdout, - Stderr: os.Stderr, - } - return cmd.Run() -} diff --git a/pkg/common/utils/env.go b/pkg/common/utils/env.go index 4d2f09f7..37eb6eaf 100644 --- a/pkg/common/utils/env.go +++ b/pkg/common/utils/env.go @@ -17,9 +17,122 @@ package utils import ( + "bytes" + "fmt" + "go/build" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "regexp" + "strings" + "github.com/cloudwego/cwgo/pkg/consts" ) +func GetGOPATH() (gopath string, err error) { + ps := filepath.SplitList(os.Getenv("GOPATH")) + if len(ps) > 0 { + gopath = ps[0] + } + if gopath == "" { + cmd := exec.Command("go", "env", "GOPATH") + var out bytes.Buffer + cmd.Stderr = &out + cmd.Stdout = &out + if err := cmd.Run(); err == nil { + gopath = strings.Trim(out.String(), " \t\n\r") + } + } + if gopath == "" { + ps := GetBuildGoPaths() + if len(ps) > 0 { + gopath = ps[0] + } + } + isExist, err := PathExist(gopath) + if !isExist { + return "", err + } + return strings.Replace(gopath, "/", string(os.PathSeparator), -1), nil +} + +// GetBuildGoPaths returns the list of Go path directories. +func GetBuildGoPaths() []string { + var all []string + for _, p := range filepath.SplitList(build.Default.GOPATH) { + if p == "" || p == build.Default.GOROOT { + continue + } + if strings.HasPrefix(p, "~") { + continue + } + all = append(all, p) + } + for k, v := range all { + if strings.HasSuffix(v, "/") || strings.HasSuffix(v, string(os.PathSeparator)) { + v = v[:len(v)-1] + } + all[k] = v + } + return all +} + +var goModReg = regexp.MustCompile(`^\s*module\s+(\S+)\s*`) + +// SearchGoMod searches go.mod from the given directory (which must be an absolute path) to +// the root directory. When the go.mod is found, its module name and path will be returned. +func SearchGoMod(cwd string, recurse bool) (moduleName, path string, found bool) { + for { + path = filepath.Join(cwd, "go.mod") + data, err := ioutil.ReadFile(path) + if err == nil { + for _, line := range strings.Split(string(data), "\n") { + m := goModReg.FindStringSubmatch(line) + if m != nil { + return m[1], cwd, true + } + } + return fmt.Sprintf("", path), path, true + } + + if !os.IsNotExist(err) { + return + } + if !recurse { + break + } + cwd = filepath.Dir(cwd) + // the root directory will return itself by using "filepath.Dir()"; to prevent dead loops, so jump out + if cwd == filepath.Dir(cwd) { + break + } + } + return +} + +func InitGoMod(module string) error { + isExist, err := PathExist("go.mod") + if err != nil { + return err + } + if isExist { + return nil + } + gg, err := exec.LookPath("go") + if err != nil { + return err + } + cmd := &exec.Cmd{ + Path: gg, + Args: []string{"go", "mod", "init", module}, + Stdin: os.Stdin, + Stdout: os.Stdout, + Stderr: os.Stderr, + } + return cmd.Run() +} + // IsWindows determines whether the current operating system is Windows func IsWindows() bool { return consts.SysType == consts.WindowsOS diff --git a/pkg/common/utils/file.go b/pkg/common/utils/file.go index cc4fc2bf..e8145b91 100644 --- a/pkg/common/utils/file.go +++ b/pkg/common/utils/file.go @@ -24,15 +24,20 @@ import ( "github.com/cloudwego/hertz/cmd/hz/meta" ) -// Exists is used to judge whether the path exists in file system. -func Exists(path string) bool { - _, err := os.Stat(path) +// PathExist is used to judge whether the path exists in file system. +func PathExist(path string) (bool, error) { + abPath, err := filepath.Abs(path) if err != nil { - return os.IsExist(err) + return false, err } - return true + _, err = os.Stat(abPath) + if err != nil { + return os.IsExist(err), nil + } + return true, nil } +// GetIdlType is used to return the idl type. func GetIdlType(path string, pbName ...string) (string, error) { ext := filepath.Ext(path) if ext == "" || ext[0] != '.' { diff --git a/pkg/common/utils/hz.go b/pkg/common/utils/hz.go index ca7c1f72..fb484c8e 100644 --- a/pkg/common/utils/hz.go +++ b/pkg/common/utils/hz.go @@ -31,5 +31,6 @@ func SetHzVerboseLog(v bool) { } func IsHzNew(outputDir string) bool { - return !Exists(path.Join(outputDir, ".hz")) + exist, _ := PathExist(path.Join(outputDir, ".hz")) + return !exist } diff --git a/pkg/server/check.go b/pkg/server/check.go index 6b42cd61..b56c3eee 100644 --- a/pkg/server/check.go +++ b/pkg/server/check.go @@ -26,7 +26,6 @@ import ( "github.com/cloudwego/cwgo/config" "github.com/cloudwego/cwgo/pkg/common/utils" "github.com/cloudwego/cwgo/pkg/consts" - "github.com/cloudwego/hertz/cmd/hz/util" ) func check(sa *config.ServerArgument) error { @@ -60,7 +59,7 @@ func check(sa *config.ServerArgument) error { sa.OutDir = ap } - gopath, err := util.GetGOPATH() + gopath, err := utils.GetGOPATH() if err != nil { return fmt.Errorf("get gopath failed: %s", err) } diff --git a/pkg/server/kitex.go b/pkg/server/kitex.go index 13b19659..c61339fe 100644 --- a/pkg/server/kitex.go +++ b/pkg/server/kitex.go @@ -41,7 +41,6 @@ import ( kargs "github.com/cloudwego/kitex/tool/cmd/kitex/args" "github.com/cloudwego/kitex/tool/internal_pkg/generator" "github.com/cloudwego/kitex/tool/internal_pkg/log" - "github.com/cloudwego/kitex/tool/internal_pkg/util" ) func convertKitexArgs(sa *config.ServerArgument, kitexArgument *kargs.Arguments) (err error) { @@ -126,7 +125,7 @@ Flags: } func checkKitexArgs(a *kargs.Arguments) (err error) { - // check IDL` + // check IDL a.IDLType, err = utils.GetIdlType(a.IDL, consts.Protobuf) if err != nil { return err @@ -140,14 +139,15 @@ func checkKitexArgs(a *kargs.Arguments) (err error) { } } - // check path - pathToGo, err := exec.LookPath("go") + gopath, err := utils.GetGOPATH() if err != nil { - log.Warn(err) - os.Exit(1) + return fmt.Errorf("get gopath failed: %s", err) + } + if gopath == "" { + return fmt.Errorf("GOPATH is not set") } - gosrc := filepath.Join(util.GetGOPATH(), "src") + gosrc := filepath.Join(gopath, "src") gosrc, err = filepath.Abs(gosrc) if err != nil { log.Warn("Get GOPATH/src path failed:", err.Error()) @@ -173,7 +173,7 @@ func checkKitexArgs(a *kargs.Arguments) (err error) { } if a.ModuleName != "" { - module, p, ok := util.SearchGoMod(curpath) + module, p, ok := utils.SearchGoMod(curpath, true) if ok { // go.mod exists if module != a.ModuleName { @@ -187,7 +187,7 @@ func checkKitexArgs(a *kargs.Arguments) (err error) { } a.PackagePrefix = filepath.Join(a.ModuleName, a.PackagePrefix, generator.KitexGenPath) } else { - if err = initGoMod(pathToGo, a.ModuleName); err != nil { + if err = utils.InitGoMod(a.ModuleName); err != nil { log.Warn("Init go mod failed:", err.Error()) os.Exit(1) } @@ -202,21 +202,6 @@ func checkKitexArgs(a *kargs.Arguments) (err error) { return nil } -func initGoMod(pathToGo, module string) error { - if util.Exists("go.mod") { - return nil - } - - cmd := &exec.Cmd{ - Path: pathToGo, - Args: []string{"go", "mod", "init", module}, - Stdin: os.Stdin, - Stdout: os.Stdout, - Stderr: os.Stderr, - } - return cmd.Run() -} - func replaceThriftVersion(args *kargs.Arguments) { if args.IDLType == "thrift" { cmd := "go mod edit -replace github.com/apache/thrift=github.com/apache/thrift@v0.13.0" @@ -341,9 +326,12 @@ var hertzEngine *route.Engine func init() { hertzEngine = initHertz() } - ` - if util.Exists("hex_trans_handler.go") { + exist, err := utils.PathExist("hex_trans_handler.go") + if err != nil { + return err + } + if exist { return nil } tmpl := template.Must(template.New("hex_trans_handler").Parse(tmplContent)) diff --git a/pkg/server/server.go b/pkg/server/server.go index d8d8d0cf..a5f9c1c1 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -30,7 +30,6 @@ import ( "github.com/cloudwego/hertz/cmd/hz/app" hzConfig "github.com/cloudwego/hertz/cmd/hz/config" "github.com/cloudwego/hertz/cmd/hz/meta" - "github.com/cloudwego/hertz/cmd/hz/util" kargs "github.com/cloudwego/kitex/tool/cmd/kitex/args" "github.com/cloudwego/kitex/tool/internal_pkg/log" "github.com/cloudwego/kitex/tool/internal_pkg/pluginmode/thriftgo" @@ -99,7 +98,7 @@ func Server(c *config.ServerArgument) error { if c.GoMod == "" { return fmt.Errorf("output directory %s is not under GOPATH/src. Please specify a module name with the '-module' flag", c.Cwd) } - module, path, ok := util.SearchGoMod(".", false) + module, path, ok := utils.SearchGoMod(".", false) if ok { // go.mod exists if module != c.GoMod { @@ -130,7 +129,7 @@ func Server(c *config.ServerArgument) error { return cli.Exit(err, meta.LoadError) } - module, path, ok := util.SearchGoMod(".", false) + module, path, ok := utils.SearchGoMod(".", false) if ok { // go.mod exists if c.GoMod != "" && module != c.GoMod { diff --git a/tpl/kitex/server/standard/conf_tpl.yaml b/tpl/kitex/server/standard/conf_tpl.yaml index 464fbd38..67231a9c 100644 --- a/tpl/kitex/server/standard/conf_tpl.yaml +++ b/tpl/kitex/server/standard/conf_tpl.yaml @@ -6,18 +6,17 @@ body: |- import ( "bytes" - "io/ioutil" - "os" + "io/ioutil" + "os" "os/exec" - "path/filepath" - "sync" - - "gopkg.in/validator.v2" - "gopkg.in/yaml.v2" + "path/filepath" + "sync" "github.com/bytedance/sonic" - "github.com/cloudwego/kitex/pkg/klog" - "github.com/kr/pretty" + "github.com/cloudwego/kitex/pkg/klog" + "github.com/kr/pretty" + "gopkg.in/validator.v2" + "gopkg.in/yaml.v2" ) var ( @@ -140,4 +139,4 @@ body: |- default: return klog.LevelInfo } - } \ No newline at end of file + }