[go: nahoru, domu]

Skip to content

Commit

Permalink
feat(tool): implement kitex tool as sdk (#1356)
Browse files Browse the repository at this point in the history
  • Loading branch information
HeyJavaBean committed Jun 26, 2024
1 parent f7570e2 commit d42ee6b
Show file tree
Hide file tree
Showing 15 changed files with 300 additions and 141 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ require (
github.com/cloudwego/localsession v0.0.2
github.com/cloudwego/netpoll v0.6.2
github.com/cloudwego/runtimex v0.1.0
github.com/cloudwego/thriftgo v0.3.6
github.com/cloudwego/thriftgo v0.3.14-0.20240625094426-efe48e84f538
github.com/golang/mock v1.6.0
github.com/google/pprof v0.0.0-20220608213341-c488b8fa1db3
github.com/jhump/protoreflect v1.8.2
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,21 @@ github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
github.com/cloudwego/localsession v0.0.2 h1:N9/IDtCPj1fCL9bCTP+DbXx3f40YjVYWcwkJG0YhQkY=
github.com/cloudwego/localsession v0.0.2/go.mod h1:kiJxmvAcy4PLgKtEnPS5AXed3xCiXcs7Z+KBHP72Wv8=
github.com/cloudwego/netpoll v0.6.1 h1:Cjftvi6bmumsOijmuUFy6HqAUXMxAT3fKK96wsrm3XA=
github.com/cloudwego/netpoll v0.6.1/go.mod h1:kaqvfZ70qd4T2WtIIpCOi5Cxyob8viEpzLhCrTrz3HM=
github.com/cloudwego/netpoll v0.6.2 h1:+KdILv5ATJU+222wNNXpHapYaBeRvvL8qhJyhcxRxrQ=
github.com/cloudwego/netpoll v0.6.2/go.mod h1:kaqvfZ70qd4T2WtIIpCOi5Cxyob8viEpzLhCrTrz3HM=
github.com/cloudwego/runtimex v0.1.0 h1:HG+WxWoj5/CDChDZ7D99ROwvSMkuNXAqt6hnhTTZDiI=
github.com/cloudwego/runtimex v0.1.0/go.mod h1:23vL/HGV0W8nSCHbe084AgEBdDV4rvXenEUMnUNvUd8=
github.com/cloudwego/thriftgo v0.3.6 h1:gHHW8Ag3cAEQ/awP4emTJiRPr5yQjbANhcsmV8/Epbw=
github.com/cloudwego/thriftgo v0.3.6/go.mod h1:29ukiySoAMd0vXMYIduAY9dph/7dmChvOS11YLotFb8=
github.com/cloudwego/thriftgo v0.3.14-0.20240625094426-efe48e84f538 h1:erd7sP8sG2j+hMjISTNtdF60oPUL/76EPS+XsbYYdYo=
github.com/cloudwego/thriftgo v0.3.14-0.20240625094426-efe48e84f538/go.mod h1:R4a+4aVDI0V9YCTfpNgmvbkq/9ThKgF7Om8Z0I36698=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI=
github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
Expand Down
144 changes: 70 additions & 74 deletions tool/cmd/kitex/args/args.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ type ExtraFlag struct {

// check may perform any value checking for flags added by apply above.
// When an error occur, check should directly terminate the program by
// os.Exit with exit code 1 for internal error and 2 for invalid arguments.
Check func(*Arguments)
Check func(*Arguments) error
}

// Arguments .
Expand Down Expand Up @@ -152,44 +151,49 @@ Examples:
Flags:
`, a.Version, os.Args[0], cmdExample)
f.PrintDefaults()
os.Exit(1)
}
return f
}

// ParseArgs parses command line arguments.
func (a *Arguments) ParseArgs(version string) {
func (a *Arguments) ParseArgs(version, curpath string, kitexArgs []string) (err error) {
f := a.buildFlags(version)
if err := f.Parse(os.Args[1:]); err != nil {
log.Warn(os.Stderr, err)
os.Exit(2)
if err = f.Parse(kitexArgs); err != nil {
return err
}

log.Verbose = a.Verbose

for _, e := range a.extends {
e.Check(a)
err = e.Check(a)
if err != nil {
return err
}
}

a.checkIDL(f.Args())
a.checkServiceName()
err = a.checkIDL(f.Args())
if err != nil {
return err
}
err = a.checkServiceName()
if err != nil {
return err
}
// todo finish protobuf
if a.IDLType != "thrift" {
a.GenPath = generator.KitexGenPath
}
a.checkPath()
return a.checkPath(curpath)
}

func (a *Arguments) checkIDL(files []string) {
func (a *Arguments) checkIDL(files []string) error {
if len(files) == 0 {
log.Warn("No IDL file found; Please make your IDL file the last parameter, for example: " +
"\"kitex -service demo idl.thrift\".")
os.Exit(2)
return fmt.Errorf("no IDL file found; Please make your IDL file the last parameter, for example: " +
"\"kitex -service demo idl.thrift\"")
}
if len(files) != 1 {
log.Warn("Require exactly 1 IDL file; Please make your IDL file the last parameter, for example: " +
"\"kitex -service demo idl.thrift\".")
os.Exit(2)
return fmt.Errorf("require exactly 1 IDL file; Please make your IDL file the last parameter, for example: " +
"\"kitex -service demo idl.thrift\"")
}
a.IDL = files[0]

Expand All @@ -199,60 +203,53 @@ func (a *Arguments) checkIDL(files []string) {
if typ, ok := a.guessIDLType(); ok {
a.IDLType = typ
} else {
log.Warnf("Can not guess an IDL type from %q (unknown suffix), please specify with the '-type' flag.", a.IDL)
os.Exit(2)
return fmt.Errorf("can not guess an IDL type from %q (unknown suffix), please specify with the '-type' flag", a.IDL)
}
default:
log.Warn("Unsupported IDL type:", a.IDLType)
os.Exit(2)
return fmt.Errorf("unsupported IDL type: %s", a.IDLType)
}
return nil
}

func (a *Arguments) checkServiceName() {
func (a *Arguments) checkServiceName() error {
if a.ServiceName == "" && a.TemplateDir == "" {
if a.Use != "" {
log.Warn("-use must be used with -service or -template-dir")
os.Exit(2)
return fmt.Errorf("-use must be used with -service or -template-dir")
}
}
if a.ServiceName != "" && a.TemplateDir != "" {
log.Warn("-template-dir and -service cannot be specified at the same time")
os.Exit(2)
return fmt.Errorf("-template-dir and -service cannot be specified at the same time")
}
if a.ServiceName != "" {
a.GenerateMain = true
}
return nil
}

func (a *Arguments) checkPath() {
func (a *Arguments) checkPath(curpath string) error {
pathToGo, err := exec.LookPath("go")
if err != nil {
log.Warn(err)
os.Exit(1)
return err
}

gosrc := util.JoinPath(util.GetGOPATH(), "src")
gosrc, err = filepath.Abs(gosrc)
gopath, err := util.GetGOPATH()
if err != nil {
log.Warn("Get GOPATH/src path failed:", err.Error())
os.Exit(1)
return err
}
curpath, err := filepath.Abs(".")
gosrc := util.JoinPath(gopath, "src")
gosrc, err = filepath.Abs(gosrc)
if err != nil {
log.Warn("Get current path failed:", err.Error())
os.Exit(1)
return fmt.Errorf("get GOPATH/src path failed: %s", err.Error())
}

if strings.HasPrefix(curpath, gosrc) {
if a.PackagePrefix, err = filepath.Rel(gosrc, curpath); err != nil {
log.Warn("Get GOPATH/src relpath failed:", err.Error())
os.Exit(1)
return fmt.Errorf("get GOPATH/src relpath failed: %s", err.Error())
}
a.PackagePrefix = util.JoinPath(a.PackagePrefix, a.GenPath)
} else {
if a.ModuleName == "" {
log.Warn("Outside of $GOPATH. Please specify a module name with the '-module' flag.")
os.Exit(1)
return fmt.Errorf("outside of $GOPATH. Please specify a module name with the '-module' flag")
}
}

Expand All @@ -261,19 +258,16 @@ func (a *Arguments) checkPath() {
if ok {
// go.mod exists
if module != a.ModuleName {
log.Warnf("The module name given by the '-module' option ('%s') is not consist with the name defined in go.mod ('%s' from %s)\n",
return fmt.Errorf("the module name given by the '-module' option ('%s') is not consist with the name defined in go.mod ('%s' from %s)",
a.ModuleName, module, path)
os.Exit(1)
}
if a.PackagePrefix, err = filepath.Rel(path, curpath); err != nil {
log.Warn("Get package prefix failed:", err.Error())
os.Exit(1)
return fmt.Errorf("get package prefix failed: %s", err.Error())
}
a.PackagePrefix = util.JoinPath(a.ModuleName, a.PackagePrefix, a.GenPath)
} else {
if err = initGoMod(pathToGo, a.ModuleName); err != nil {
log.Warn("Init go mod failed:", err.Error())
os.Exit(1)
return fmt.Errorf("init go mod failed: %s", err.Error())
}
a.PackagePrefix = util.JoinPath(a.ModuleName, a.GenPath)
}
Expand All @@ -283,14 +277,14 @@ func (a *Arguments) checkPath() {
a.PackagePrefix = a.Use
}
a.OutputPath = curpath
return nil
}

// BuildCmd builds an exec.Cmd.
func (a *Arguments) BuildCmd(out io.Writer) *exec.Cmd {
func (a *Arguments) BuildCmd(out io.Writer) (*exec.Cmd, error) {
exe, err := os.Executable()
if err != nil {
log.Warn("Failed to detect current executable:", err.Error())
os.Exit(1)
return nil, fmt.Errorf("failed to detect current executable: %s", err.Error())
}

for i, inc := range a.Includes {
Expand All @@ -300,9 +294,7 @@ func (a *Arguments) BuildCmd(out io.Writer) *exec.Cmd {
if errMsg == "" {
errMsg = gitErr.Error()
}
log.Warn("failed to pull IDL from git:", errMsg)
log.Warn("You can execute 'rm -rf ~/.kitex' to clean the git cache and try again.")
os.Exit(1)
return nil, fmt.Errorf("failed to pull IDL from git:%s\nYou can execute 'rm -rf ~/.kitex' to clean the git cache and try again", errMsg)
}
a.Includes[i] = localGitPath
}
Expand All @@ -316,7 +308,9 @@ func (a *Arguments) BuildCmd(out io.Writer) *exec.Cmd {
Stderr: io.MultiWriter(out, os.Stderr),
}

ValidateCMD(cmd.Path, a.IDLType)
if err != nil {
return nil, err
}

if a.IDLType == "thrift" {
os.Setenv(EnvPluginMode, thriftgo.PluginName)
Expand All @@ -325,7 +319,10 @@ func (a *Arguments) BuildCmd(out io.Writer) *exec.Cmd {
cmd.Args = append(cmd.Args, "-i", inc)
}
if thriftgo.IsHessian2(a.Config) {
thriftgo.Hessian2PreHook(&a.Config)
err = thriftgo.Hessian2PreHook(&a.Config)
if err != nil {
return nil, err
}
}
a.ThriftOptions = append(a.ThriftOptions, "package_prefix="+a.PackagePrefix)
gas := "go:" + strings.Join(a.ThriftOptions, ",")
Expand Down Expand Up @@ -374,8 +371,7 @@ func (a *Arguments) BuildCmd(out io.Writer) *exec.Cmd {
for _, p := range a.ProtobufPlugins {
pluginParams := strings.Split(p, ":")
if len(pluginParams) != 3 {
log.Warnf("Failed to get the correct protoc plugin parameters for %. Please specify the protoc plugin in the form of \"plugin_name:options:out_dir\"", p)
os.Exit(1)
return nil, fmt.Errorf("failed to get the correct protoc plugin parameters for %s. Please specify the protoc plugin in the form of \"plugin_name:options:out_dir\"", p)
}
// pluginParams[0] -> plugin name, pluginParams[1] -> plugin options, pluginParams[2] -> out_dir
cmd.Args = append(cmd.Args,
Expand All @@ -387,11 +383,11 @@ func (a *Arguments) BuildCmd(out io.Writer) *exec.Cmd {
cmd.Args = append(cmd.Args, a.IDL)
}
log.Info(strings.ReplaceAll(strings.Join(cmd.Args, " "), kas, fmt.Sprintf("%q", kas)))
return cmd
return cmd, nil
}

// ValidateCMD check if the path exists and if the version is satisfied
func ValidateCMD(path, idlType string) {
func ValidateCMD(path, idlType string) error {
// check if the path exists
if _, err := os.Stat(path); err != nil {
tool := "thriftgo"
Expand All @@ -402,15 +398,13 @@ func ValidateCMD(path, idlType string) {
if idlType == "thrift" {
_, err = runCommand("go install github.com/cloudwego/thriftgo@latest")
if err != nil {
log.Warnf("[ERROR] %s is also unavailable, please install %s first.\n", path, tool)
log.Warn("Refer to https://github.com/cloudwego/thriftgo, or simple run:\n")
log.Warn(" go install -v github.com/cloudwego/thriftgo@latest\n")
os.Exit(1)
return fmt.Errorf("[ERROR] %s is also unavailable, please install %s first.\n"+
"Refer to https://github.com/cloudwego/thriftgo, or simple run:\n"+
" go install -v github.com/cloudwego/thriftgo@latest", path, tool)
}
} else {
log.Warnf("[ERROR] %s is also unavailable, please install %s first.\n", path, tool)
log.Warn("Refer to https://github.com/protocolbuffers/protobuf\n")
os.Exit(1)
return fmt.Errorf("[ERROR] %s is also unavailable, please install %s first.\n"+
"Refer to https://github.com/protocolbuffers/protobuf", path, tool)
}
}

Expand All @@ -420,24 +414,22 @@ func ValidateCMD(path, idlType string) {
cmd := exec.Command(path, "-version")
out, err := cmd.CombinedOutput()
if err != nil {
log.Warnf("Failed to get thriftgo version: %s\n", err.Error())
os.Exit(1)
return fmt.Errorf("failed to get thriftgo version: %s", err.Error())
}
if !strings.HasPrefix(string(out), "thriftgo ") {
log.Warnf("thriftgo -version returns '%s', please reinstall thriftgo first.\n", string(out))
os.Exit(1)
return fmt.Errorf("thriftgo -version returns '%s', please reinstall thriftgo first", string(out))
}
version := strings.Replace(strings.TrimSuffix(string(out), "\n"), "thriftgo ", "", 1)
if !versionSatisfied(version, requiredThriftGoVersion) {
_, err = runCommand("go install github.com/cloudwego/thriftgo@latest")
if err != nil {
log.Warnf("[ERROR] thriftgo version(%s) not satisfied, please install version >= %s\n",
return fmt.Errorf("[ERROR] thriftgo version(%s) not satisfied, please install version >= %s",
version, requiredThriftGoVersion)
os.Exit(1)
}
}
return
return nil
}
return nil
}

var versionSuffixPattern = regexp.MustCompile(`-.*$`)
Expand Down Expand Up @@ -495,7 +487,11 @@ func LookupTool(idlType, compilerPath string) string {
path, err := exec.LookPath(tool)
if err != nil {
// log.Warnf("Failed to find %q from $PATH: %s.\nTry $GOPATH/bin/%s instead\n", path, err.Error(), tool)
path = util.JoinPath(util.GetGOPATH(), "bin", tool)
gopath, er := util.GetGOPATH()
if er != nil {
return ""
}
path = util.JoinPath(gopath, "bin", tool)
}
return path
}
Expand Down
1 change: 1 addition & 0 deletions tool/cmd/kitex/args/version_requirements.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@

package args

// todo thriftgo sdk 功能 v0.3.13 发布打 tag
var requiredThriftGoVersion = "v0.3.6"
Loading

0 comments on commit d42ee6b

Please sign in to comment.