diff --git a/cmd/hz/app/app.go b/cmd/hz/app/app.go index bf2b620bb..a37da5d51 100644 --- a/cmd/hz/app/app.go +++ b/cmd/hz/app/app.go @@ -36,6 +36,10 @@ import ( // global args. MUST fork it when use var globalArgs = config.NewArgument() +func GetGlobalArgs() *config.Argument { + return globalArgs +} + func New(c *cli.Context) error { args, err := globalArgs.Parse(c, meta.CmdNew) if err != nil { diff --git a/cmd/hz/config/argument.go b/cmd/hz/config/argument.go index 2f5f5f7f4..bb8ca75f1 100644 --- a/cmd/hz/config/argument.go +++ b/cmd/hz/config/argument.go @@ -18,10 +18,11 @@ package config import ( "fmt" - "os" "path/filepath" "strings" + "github.com/cloudwego/thriftgo/utils/dir_utils" + "github.com/cloudwego/hertz/cmd/hz/meta" "github.com/cloudwego/hertz/cmd/hz/util" "github.com/cloudwego/hertz/cmd/hz/util/logs" @@ -149,16 +150,25 @@ func (arg *Argument) UpdateByManifest(m *meta.Manifest) { // checkPath sets the project path and verifies that the model、handler、router and client path is compliant func (arg *Argument) checkPath() error { - dir, err := os.Getwd() + dir, err := dir_utils.Getwd() if err != nil { return fmt.Errorf("get current path failed: %s", err) } + + if !filepath.IsAbs(dir) { + dir, err = filepath.Abs(dir) + if err != nil { + return fmt.Errorf("get abs path failed: %s", err) + } + } + arg.Cwd = dir if arg.OutDir == "" { arg.OutDir = dir } + if !filepath.IsAbs(arg.OutDir) { - ap := filepath.Join(arg.Cwd, arg.OutDir) + ap, _ := filepath.Abs(arg.OutDir) arg.OutDir = ap } if arg.ModelDir != "" && filepath.IsAbs(arg.ModelDir) { diff --git a/cmd/hz/config/cmd.go b/cmd/hz/config/cmd.go index fc83c57c5..522b1c36c 100644 --- a/cmd/hz/config/cmd.go +++ b/cmd/hz/config/cmd.go @@ -87,6 +87,22 @@ func link(src, dst string) error { return nil } +// BuildSdkPluginCmd build cmd for hz plugin sdk +func BuildSdkPluginCmd(args *Argument) (*exec.Cmd, error) { + exe, err := os.Executable() + if err != nil { + return nil, fmt.Errorf("failed to detect current executable, err: %v", err) + } + + argPacks, err := args.Pack() + if err != nil { + return nil, err + } + kas := strings.Join(argPacks, ",") + return wrapCmd(args, "", exe, kas) +} + +// BuildPluginCmd build cmd for hz plugin cmd func BuildPluginCmd(args *Argument) (*exec.Cmd, error) { exe, err := os.Executable() if err != nil { @@ -103,10 +119,12 @@ func BuildPluginCmd(args *Argument) (*exec.Cmd, error) { if err != nil { return nil, err } - cmd := &exec.Cmd{ - Path: path, - } + return wrapCmd(args, path, exe, kas) +} + +func wrapCmd(args *Argument, path, exe, kas string) (*exec.Cmd, error) { + cmd := &exec.Cmd{Path: path} if args.IdlType == meta.IdlThrift { // thriftgo os.Setenv(meta.EnvPluginMode, meta.ThriftPluginName) @@ -144,9 +162,9 @@ func BuildPluginCmd(args *Argument) (*exec.Cmd, error) { cmd.Args = append(cmd.Args, "-I", filepath.Dir(inc)) } cmd.Args = append(cmd.Args, - "--plugin=protoc-gen-hertz="+exe, - "--hertz_out="+args.OutDir, - "--hertz_opt="+kas, + "--plugin=protoc-gen-rgo="+exe, + "--rgo_out="+args.OutDir, + "--rgo_opt="+kas, ) for _, p := range args.ProtobufPlugins { pluginParams := strings.Split(p, ":") diff --git a/cmd/hz/go.mod b/cmd/hz/go.mod index 712c5a28d..c70d87118 100644 --- a/cmd/hz/go.mod +++ b/cmd/hz/go.mod @@ -4,7 +4,7 @@ go 1.16 require ( github.com/Masterminds/sprig/v3 v3.2.3 - github.com/cloudwego/thriftgo v0.1.7 + github.com/cloudwego/thriftgo v0.3.19 github.com/hashicorp/go-version v1.5.0 github.com/jhump/protoreflect v1.12.0 github.com/urfave/cli/v2 v2.23.0 diff --git a/cmd/hz/go.sum b/cmd/hz/go.sum index de5c00d51..e854c2e9e 100644 --- a/cmd/hz/go.sum +++ b/cmd/hz/go.sum @@ -7,18 +7,18 @@ github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7Y github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= -github.com/apache/thrift v0.13.0 h1:5hryIiq9gtn+MiLVn0wP37kb/uTeRZgN08WoCsAhIhI= -github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudwego/thriftgo v0.1.7 h1:mTGRv6Dtwfp0hTPZXuIHwm3vtGOuZVTrWarI0xVzUYg= -github.com/cloudwego/thriftgo v0.1.7/go.mod h1:LzeafuLSiHA9JTiWC8TIMIq64iadeObgRUhmVG1OC/w= +github.com/cloudwego/thriftgo v0.3.19 h1:G5W8sLFXjuip8Kwl+bv+am48WFiyCJIydN6AiYlwsoo= +github.com/cloudwego/thriftgo v0.3.19/go.mod h1:AdLEJJVGW/ZJYvkkYAZf5SaJH+pA3OyC801WSwqcBwI= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= @@ -135,8 +135,9 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -175,6 +176,7 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -182,6 +184,7 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/cmd/hz/meta/const.go b/cmd/hz/meta/const.go index a696be8e7..396e0dd33 100644 --- a/cmd/hz/meta/const.go +++ b/cmd/hz/meta/const.go @@ -55,7 +55,7 @@ const ( // hz Plugins const ( - ProtocPluginName = "protoc-gen-hertz" + ProtocPluginName = "protoc-gen-rgo" ThriftPluginName = "thrift-gen-hertz" ) diff --git a/cmd/hz/protobuf/plugin.go b/cmd/hz/protobuf/plugin.go index abb7616c4..c70dcc221 100644 --- a/cmd/hz/protobuf/plugin.go +++ b/cmd/hz/protobuf/plugin.go @@ -330,7 +330,7 @@ func (plugin *Plugin) fixModelPathAndPackage(pkg string) (impt, path string) { } path = util.ImportToPath(impt, "") // bugfix: impt may have "/" suffix - //impt = plugin.Package + "/" + impt + // impt = plugin.Package + "/" + impt impt = filepath.Join(plugin.Package, impt) if util.IsWindows() { impt = util.PathToImport(impt, "") diff --git a/cmd/hz/sdk/hertz_sdk.go b/cmd/hz/sdk/hertz_sdk.go new file mode 100644 index 000000000..ac48e90c3 --- /dev/null +++ b/cmd/hz/sdk/hertz_sdk.go @@ -0,0 +1,196 @@ +// Copyright 2025 CloudWeGo Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package sdk + +import ( + "flag" + "fmt" + "os/exec" + "path/filepath" + "strings" + + "github.com/cloudwego/hertz/cmd/hz/meta" + "github.com/cloudwego/hertz/cmd/hz/util" + + "github.com/cloudwego/hertz/cmd/hz/app" + "github.com/cloudwego/hertz/cmd/hz/config" + "github.com/cloudwego/hertz/cmd/hz/thrift" + "github.com/cloudwego/thriftgo/plugin" + "github.com/cloudwego/thriftgo/sdk" + "github.com/urfave/cli/v2" +) + +// RunHertzTool Run hz SDK +func RunHertzTool(wd, cmdType string, plugins []plugin.SDKPlugin, hertzArgs ...string) error { + hertzPlugin, args, err := GetHertzSDKPlugin(wd, cmdType, hertzArgs) + if err != nil { + return err + } + s := []plugin.SDKPlugin{hertzPlugin} + s = append(s, plugins...) + + manifest := new(meta.Manifest) + switch cmdType { + case meta.CmdNew: + exist, err := util.PathExist(filepath.Join(args.OutDir, meta.ManifestFile)) + if err != nil { + return err + } + + if exist && !args.ForceNew { + return fmt.Errorf("the current is already a hertz project, if you want to regenerate it you can specify \"-force\"") + } + + err = app.GenerateLayout(args) + if err != nil { + return err + } + case meta.CmdUpdate: + err = manifest.InitAndValidate(args.OutDir) + if err != nil { + return err + } + // update argument by ".hz", can automatically get "handler_dir"/"model_dir"/"router_dir" + args.UpdateByManifest(manifest) + } + + err = sdk.RunThriftgoAsSDK(wd, s, hertzPlugin.GetThriftgoParameters()...) + if err != nil { + if !strings.Contains(err.Error(), meta.TheUseOptionMessage) { + return err + } + } + + switch cmdType { + case meta.CmdNew: + args.InitManifest(manifest) + err = manifest.Persist(args.OutDir) + if err != nil { + return fmt.Errorf("persist manifest failed: %v", err) + } + case meta.CmdUpdate: + args.UpdateManifest(manifest) + err = manifest.Persist(args.OutDir) + if err != nil { + return cli.Exit(fmt.Errorf("persist manifest failed: %v", err), meta.PersistError) + } + } + + return nil +} + +type HertzSDKPlugin struct { + HertzParams []string + ThriftgoParams []string + Pwd string + Args *config.Argument +} + +func (k *HertzSDKPlugin) Invoke(req *plugin.Request) (res *plugin.Response) { + r := thrift.Plugin{} + return r.HandleRequest(k.Args, req) +} + +func (k *HertzSDKPlugin) GetName() string { + return "hz" +} + +func (k *HertzSDKPlugin) GetPluginParameters() []string { + return k.HertzParams +} + +func (k *HertzSDKPlugin) GetThriftgoParameters() []string { + return k.ThriftgoParams +} + +func findCommon(client *cli.App, cmdType string) *cli.Command { + for _, cmd := range client.Commands { + if cmd.Name == cmdType { + return cmd + } + } + return nil +} + +func GetHertzSDKPlugin(pwd, cmdType string, rawHertzArgs []string) (*HertzSDKPlugin, *config.Argument, error) { + client := app.Init() + + c := findCommon(client, cmdType) + if c == nil { + return nil, nil, fmt.Errorf("command not found: %s", cmdType) + } + + flagSet := flag.NewFlagSet(cmdType+"-parse", flag.ContinueOnError) + + for _, f := range c.Flags { + if err := f.Apply(flagSet); err != nil { + return nil, nil, err + } + } + + if err := flagSet.Parse(rawHertzArgs); err != nil { + return nil, nil, err + } + + ctx := cli.NewContext(client, flagSet, nil) + + args, err := app.GetGlobalArgs().Parse(ctx, cmdType) + if err != nil { + return nil, nil, err + } + + cmd, err := config.BuildSdkPluginCmd(args) + if err != nil { + return nil, nil, err + } + + hertzPlugin := &HertzSDKPlugin{} + + hertzPlugin.ThriftgoParams, hertzPlugin.HertzParams, err = ParseHertzCmd(cmd) + hertzPlugin.Args = args + + if err != nil { + return nil, nil, err + } + hertzPlugin.Pwd = pwd + + return hertzPlugin, args, nil +} + +func ParseHertzCmd(cmd *exec.Cmd) (thriftgoParams, hertzParams []string, err error) { + cmdArgs := cmd.Args + // thriftgo -r -o kitex_gen -g go:xxx -p kitex=xxxx -p otherplugin xxx.thrift + // ignore first argument, and remove -p kitex=xxxx + + thriftgoParams = []string{} + hertzParams = []string{} + if len(cmdArgs) < 1 { + return nil, nil, fmt.Errorf("cmd args too short: %s", cmdArgs) + } + + for i := 1; i < len(cmdArgs); i++ { + arg := cmdArgs[i] + if arg == "-p" && i+1 < len(cmdArgs) { + pluginArgs := cmdArgs[i+1] + if strings.HasPrefix(pluginArgs, "hertz") { + hertzParams = strings.Split(pluginArgs, ",") + i++ + continue + } + } + thriftgoParams = append(thriftgoParams, arg) + } + return thriftgoParams, hertzParams, nil +} diff --git a/cmd/hz/thrift/plugin.go b/cmd/hz/thrift/plugin.go index 0e773df30..5640811e1 100644 --- a/cmd/hz/thrift/plugin.go +++ b/cmd/hz/thrift/plugin.go @@ -44,37 +44,13 @@ type Plugin struct { rmTags []string } -func (plugin *Plugin) Run() int { +func (plugin *Plugin) HandleRequest(args *config.Argument, req *thriftgo_plugin.Request) *thriftgo_plugin.Response { plugin.setLogger() - args := &config.Argument{} - defer func() { - if args == nil { - return - } - if args.Verbose { - verboseLog := plugin.recvVerboseLogger() - if len(verboseLog) != 0 { - fmt.Fprintf(os.Stderr, verboseLog) - } - } else { - warning := plugin.recvWarningLogger() - if len(warning) != 0 { - fmt.Fprintf(os.Stderr, warning) - } - } - }() - - err := plugin.handleRequest() - if err != nil { - logs.Errorf("handle request failed: %s", err.Error()) - return meta.PluginError - } - - args, err = plugin.parseArgs() - if err != nil { - logs.Errorf("parse args failed: %s", err.Error()) - return meta.PluginError - } + plugin.req = req + // init thriftgo utils + thriftgoUtil = golang.NewCodeUtils(backend.DummyLogFunc()) + thriftgoUtil.HandleOptions(req.GeneratorParameters) + plugin.args = args plugin.rmTags = args.RmTags if args.CmdType == meta.CmdModel { // check tag options for model mode @@ -82,20 +58,15 @@ func (plugin *Plugin) Run() int { res, err := plugin.GetResponse(nil, args.OutDir) if err != nil { logs.Errorf("get response failed: %s", err.Error()) - return meta.PluginError - } - plugin.response(res) - if err != nil { - logs.Errorf("response failed: %s", err.Error()) - return meta.PluginError + return thriftgo_plugin.BuildErrorResponse(err.Error()) } - return 0 + return res } - err = plugin.initNameStyle() + err := plugin.initNameStyle() if err != nil { logs.Errorf("init naming style failed: %s", err.Error()) - return meta.PluginError + return thriftgo_plugin.BuildErrorResponse(err.Error()) } options := CheckTagOption(plugin.args) @@ -103,34 +74,34 @@ func (plugin *Plugin) Run() int { pkgInfo, err := plugin.getPackageInfo() if err != nil { logs.Errorf("get http package info failed: %s", err.Error()) - return meta.PluginError + return thriftgo_plugin.BuildErrorResponse(err.Error()) } customPackageTemplate := args.CustomizePackage pkg, err := args.GetGoPackage() if err != nil { logs.Errorf("get go package failed: %s", err.Error()) - return meta.PluginError + return thriftgo_plugin.BuildErrorResponse(err.Error()) } handlerDir, err := args.GetHandlerDir() if err != nil { logs.Errorf("get handler dir failed: %s", err.Error()) - return meta.PluginError + return thriftgo_plugin.BuildErrorResponse(err.Error()) } routerDir, err := args.GetRouterDir() if err != nil { logs.Errorf("get router dir failed: %s", err.Error()) - return meta.PluginError + return thriftgo_plugin.BuildErrorResponse(err.Error()) } modelDir, err := args.GetModelDir() if err != nil { logs.Errorf("get model dir failed: %s", err.Error()) - return meta.PluginError + return thriftgo_plugin.BuildErrorResponse(err.Error()) } clientDir, err := args.GetClientDir() if err != nil { logs.Errorf("get client dir failed: %s", err.Error()) - return meta.PluginError + return thriftgo_plugin.BuildErrorResponse(err.Error()) } sg := generator.HttpPackageGenerator{ ConfigPath: customPackageTemplate, @@ -163,32 +134,71 @@ func (plugin *Plugin) Run() int { err = sg.Generate(pkgInfo) if err != nil { logs.Errorf("generate package failed: %s", err.Error()) - return meta.PluginError + return thriftgo_plugin.BuildErrorResponse(err.Error()) } if len(args.Use) != 0 { err = sg.Persist() if err != nil { logs.Errorf("persist file failed within '-use' option: %s", err.Error()) - return meta.PluginError + return thriftgo_plugin.BuildErrorResponse(err.Error()) } res := thriftgo_plugin.BuildErrorResponse(errors.New(meta.TheUseOptionMessage).Error()) - err = plugin.response(res) - if err != nil { - logs.Errorf("response failed: %s", err.Error()) - return meta.PluginError - } - return 0 + return res } files, err := sg.GetFormatAndExcludedFiles() if err != nil { logs.Errorf("format file failed: %s", err.Error()) - return meta.PluginError + return thriftgo_plugin.BuildErrorResponse(err.Error()) } + res, err := plugin.GetResponse(files, sg.OutputDir) if err != nil { logs.Errorf("get response failed: %s", err.Error()) + return thriftgo_plugin.BuildErrorResponse(err.Error()) + } + + return res +} + +func (plugin *Plugin) Run() int { + plugin.setLogger() + args := &config.Argument{} + defer func() { + if args == nil { + return + } + if args.Verbose { + verboseLog := plugin.recvVerboseLogger() + if len(verboseLog) != 0 { + fmt.Fprintf(os.Stderr, verboseLog) + } + } else { + warning := plugin.recvWarningLogger() + if len(warning) != 0 { + fmt.Fprintf(os.Stderr, warning) + } + } + }() + + data, err := ioutil.ReadAll(os.Stdin) + if err != nil { + logs.Errorf("read request failed: %s", err.Error()) + return meta.PluginError + } + req, err := thriftgo_plugin.UnmarshalRequest(data) + if err != nil { + logs.Errorf("unmarshal request failed: %s", err.Error()) + return meta.PluginError + } + + args, err = plugin.parseArgs(req) + if err != nil { + logs.Errorf("parse args failed: %s", err.Error()) return meta.PluginError } + + res := plugin.HandleRequest(args, req) + err = plugin.response(res) if err != nil { logs.Errorf("response failed: %s", err.Error()) @@ -220,29 +230,12 @@ func (plugin *Plugin) recvVerboseLogger() string { return verboseLog } -func (plugin *Plugin) handleRequest() error { - data, err := ioutil.ReadAll(os.Stdin) - if err != nil { - return fmt.Errorf("read request failed: %s", err.Error()) - } - req, err := thriftgo_plugin.UnmarshalRequest(data) - if err != nil { - return fmt.Errorf("unmarshal request failed: %s", err.Error()) - } - plugin.req = req - // init thriftgo utils - thriftgoUtil = golang.NewCodeUtils(backend.DummyLogFunc()) - thriftgoUtil.HandleOptions(req.GeneratorParameters) - - return nil -} - -func (plugin *Plugin) parseArgs() (*config.Argument, error) { - if plugin.req == nil { +func (plugin *Plugin) parseArgs(req *thriftgo_plugin.Request) (*config.Argument, error) { + if req == nil { return nil, fmt.Errorf("request is nil") } args := new(config.Argument) - err := args.Unpack(plugin.req.PluginParameters) + err := args.Unpack(req.PluginParameters) if err != nil { logs.Errorf("unpack args failed: %s", err.Error()) } diff --git a/cmd/hz/thrift/plugin_test.go b/cmd/hz/thrift/plugin_test.go index 1cd4d8b67..e0e573d81 100644 --- a/cmd/hz/thrift/plugin_test.go +++ b/cmd/hz/thrift/plugin_test.go @@ -41,7 +41,7 @@ func TestRun(t *testing.T) { plu.req = req - _, err = plu.parseArgs() + _, err = plu.parseArgs(req) if err != nil { t.Fatal(err) } diff --git a/internal/tagexpr/spec_func.go b/internal/tagexpr/spec_func.go index 8e6291da8..78be29a97 100644 --- a/internal/tagexpr/spec_func.go +++ b/internal/tagexpr/spec_func.go @@ -59,7 +59,7 @@ func RegFunc(funcName string, fn func(...interface{}) interface{}, force ...bool return nil } -func (p *Expr) parseFuncSign(funcName string, expr *string) (boolOpposite *bool, signOpposite *bool, args []ExprNode, found bool) { +func (p *Expr) parseFuncSign(funcName string, expr *string) (boolOpposite, signOpposite *bool, args []ExprNode, found bool) { prefix := funcName + "(" length := len(funcName) last, boolOpposite, signOpposite := getBoolAndSignOpposite(expr) diff --git a/internal/tagexpr/spec_operand.go b/internal/tagexpr/spec_operand.go index b14b05515..e94ea0056 100644 --- a/internal/tagexpr/spec_operand.go +++ b/internal/tagexpr/spec_operand.go @@ -212,7 +212,7 @@ func readVariableExprNode(expr *string) ExprNode { } } -func getBoolAndSignOpposite(expr *string) (last string, boolOpposite *bool, signOpposite *bool) { +func getBoolAndSignOpposite(expr *string) (last string, boolOpposite, signOpposite *bool) { last, boolOpposite = getOpposite(expr, "!") last = strings.TrimLeft(last, "+") last, signOpposite = getOpposite(&last, "-") @@ -305,7 +305,7 @@ func toFloat64(i interface{}, tryParse bool) (float64, bool) { return v, ok } -func realValue(v interface{}, boolOpposite *bool, signOpposite *bool) interface{} { +func realValue(v interface{}, boolOpposite, signOpposite *bool) interface{} { if boolOpposite != nil { bol := FakeBool(v) if *boolOpposite { diff --git a/internal/tagexpr/spec_selector.go b/internal/tagexpr/spec_selector.go index 7e00990b1..bc4860d5f 100644 --- a/internal/tagexpr/spec_selector.go +++ b/internal/tagexpr/spec_selector.go @@ -59,7 +59,7 @@ func (p *Expr) readSelectorExprNode(expr *string) ExprNode { var selectorRegexp = regexp.MustCompile(`^([\!\+\-]*)(\([ \t]*[A-Za-z_]+[A-Za-z0-9_\.]*[ \t]*\))?(\$)([\)\[\],\+\-\*\/%><\|&!=\^ \t\\]|$)`) -func findSelector(expr *string) (field string, name string, subSelector []string, boolOpposite, signOpposite *bool, found bool) { +func findSelector(expr *string) (field, name string, subSelector []string, boolOpposite, signOpposite *bool, found bool) { raw := *expr a := selectorRegexp.FindAllStringSubmatch(raw, -1) if len(a) != 1 { diff --git a/internal/tagexpr/tagexpr.go b/internal/tagexpr/tagexpr.go index 9b14576e3..fbbc2fed9 100644 --- a/internal/tagexpr/tagexpr.go +++ b/internal/tagexpr/tagexpr.go @@ -517,7 +517,7 @@ func (s *structVM) mergeSubStructVM(field *fieldVM, sub *structVM) { } } -func (s *structVM) newChildField(parent *fieldVM, child *fieldVM, toBind bool) *fieldVM { +func (s *structVM) newChildField(parent, child *fieldVM, toBind bool) *fieldVM { f := &fieldVM{ structField: child.structField, exprs: make(map[string]*Expr, len(child.exprs)),