diff --git a/cmd/gf/internal/cmd/genctrl/genctrl.go b/cmd/gf/internal/cmd/genctrl/genctrl.go index 37c97a206..5f76a4fe2 100644 --- a/cmd/gf/internal/cmd/genctrl/genctrl.go +++ b/cmd/gf/internal/cmd/genctrl/genctrl.go @@ -34,6 +34,7 @@ gf gen ctrl CGenCtrlBriefSdkStdVersion = `use standard version prefix for generated sdk request path` CGenCtrlBriefSdkNoV1 = `do not add version suffix for interface module name if version is v1` CGenCtrlBriefClear = `auto delete generated and unimplemented controller go files if api definitions are missing` + CGenCtrlControllerMerge = `generate all controller files into one go file by name of api definition source go file` ) const ( @@ -58,6 +59,7 @@ func init() { `CGenCtrlBriefSdkStdVersion`: CGenCtrlBriefSdkStdVersion, `CGenCtrlBriefSdkNoV1`: CGenCtrlBriefSdkNoV1, `CGenCtrlBriefClear`: CGenCtrlBriefClear, + `CGenCtrlControllerMerge`: CGenCtrlControllerMerge, }) } @@ -72,6 +74,7 @@ type ( SdkStdVersion bool `short:"v" name:"sdkStdVersion" brief:"{CGenCtrlBriefSdkStdVersion}" orphan:"true"` SdkNoV1 bool `short:"n" name:"sdkNoV1" brief:"{CGenCtrlBriefSdkNoV1}" orphan:"true"` Clear bool `short:"c" name:"clear" brief:"{CGenCtrlBriefClear}" orphan:"true"` + Merge bool `short:"m" name:"merge" brief:"{CGenCtrlControllerMerge}" orphan:"true"` } CGenCtrlOutput struct{} ) @@ -79,7 +82,7 @@ type ( func (c CGenCtrl) Ctrl(ctx context.Context, in CGenCtrlInput) (out *CGenCtrlOutput, err error) { if in.WatchFile != "" { err = c.generateByWatchFile( - in.WatchFile, in.SdkPath, in.SdkStdVersion, in.SdkNoV1, in.Clear, + in.WatchFile, in.SdkPath, in.SdkStdVersion, in.SdkNoV1, in.Clear, in.Merge, ) mlog.Print(`done!`) return @@ -104,7 +107,7 @@ func (c CGenCtrl) Ctrl(ctx context.Context, in CGenCtrlInput) (out *CGenCtrlOutp ) err = c.generateByModule( apiModuleFolderPath, dstModuleFolderPath, in.SdkPath, - in.SdkStdVersion, in.SdkNoV1, in.Clear, + in.SdkStdVersion, in.SdkNoV1, in.Clear, in.Merge, ) if err != nil { return nil, err @@ -115,7 +118,7 @@ func (c CGenCtrl) Ctrl(ctx context.Context, in CGenCtrlInput) (out *CGenCtrlOutp return } -func (c CGenCtrl) generateByWatchFile(watchFile, sdkPath string, sdkStdVersion, sdkNoV1, clear bool) (err error) { +func (c CGenCtrl) generateByWatchFile(watchFile, sdkPath string, sdkStdVersion, sdkNoV1, clear, merge bool) (err error) { // File lock to avoid multiple processes. var ( flockFilePath = gfile.Temp("gf.cli.gen.service.lock") @@ -154,14 +157,14 @@ func (c CGenCtrl) generateByWatchFile(watchFile, sdkPath string, sdkStdVersion, dstModuleFolderPath = gfile.Join(projectRootPath, "internal", "controller", module) ) return c.generateByModule( - apiModuleFolderPath, dstModuleFolderPath, sdkPath, sdkStdVersion, sdkNoV1, clear, + apiModuleFolderPath, dstModuleFolderPath, sdkPath, sdkStdVersion, sdkNoV1, clear, merge, ) } // parseApiModule parses certain api and generate associated go files by certain module, not all api modules. func (c CGenCtrl) generateByModule( apiModuleFolderPath, dstModuleFolderPath, sdkPath string, - sdkStdVersion, sdkNoV1, clear bool, + sdkStdVersion, sdkNoV1, clear, merge bool, ) (err error) { // parse src and dst folder go files. apiItemsInSrc, err := c.getApiItemsInSrc(apiModuleFolderPath) @@ -194,7 +197,7 @@ func (c CGenCtrl) generateByModule( toBeImplementedApiItems = append(toBeImplementedApiItems, item) } if len(toBeImplementedApiItems) > 0 { - err = newControllerGenerator().Generate(dstModuleFolderPath, toBeImplementedApiItems) + err = newControllerGenerator().Generate(dstModuleFolderPath, toBeImplementedApiItems, merge) if err != nil { return } diff --git a/cmd/gf/internal/cmd/genctrl/genctrl_api_item.go b/cmd/gf/internal/cmd/genctrl/genctrl_api_item.go index 997c38a5f..b495e2624 100644 --- a/cmd/gf/internal/cmd/genctrl/genctrl_api_item.go +++ b/cmd/gf/internal/cmd/genctrl/genctrl_api_item.go @@ -10,6 +10,7 @@ import "github.com/gogf/gf/v2/text/gstr" type apiItem struct { Import string `eg:"demo.com/api/user/v1"` + FileName string `eg:"user"` Module string `eg:"user"` Version string `eg:"v1"` MethodName string `eg:"GetList"` diff --git a/cmd/gf/internal/cmd/genctrl/genctrl_calculate.go b/cmd/gf/internal/cmd/genctrl/genctrl_calculate.go index 578fa7e98..40d0d1fd5 100644 --- a/cmd/gf/internal/cmd/genctrl/genctrl_calculate.go +++ b/cmd/gf/internal/cmd/genctrl/genctrl_calculate.go @@ -53,6 +53,7 @@ func (c CGenCtrl) getApiItemsInSrc(apiModuleFolderPath string) (items []apiItem, } item := apiItem{ Import: gstr.Trim(importPath, `"`), + FileName: gfile.Name(apiFileFolderPath), Module: gfile.Basename(apiModuleFolderPath), Version: gfile.Basename(apiVersionFolderPath), MethodName: methodName, diff --git a/cmd/gf/internal/cmd/genctrl/genctrl_generate_ctrl.go b/cmd/gf/internal/cmd/genctrl/genctrl_generate_ctrl.go index 00377059e..0c18f4e11 100644 --- a/cmd/gf/internal/cmd/genctrl/genctrl_generate_ctrl.go +++ b/cmd/gf/internal/cmd/genctrl/genctrl_generate_ctrl.go @@ -23,7 +23,7 @@ func newControllerGenerator() *controllerGenerator { return &controllerGenerator{} } -func (c *controllerGenerator) Generate(dstModuleFolderPath string, apiModuleApiItems []apiItem) (err error) { +func (c *controllerGenerator) Generate(dstModuleFolderPath string, apiModuleApiItems []apiItem, merge bool) (err error) { var ( doneApiItemSet = gset.NewStrSet() ) @@ -42,7 +42,7 @@ func (c *controllerGenerator) Generate(dstModuleFolderPath string, apiModuleApiI return } for _, subItem := range subItems { - if err = c.doGenerateCtrlItem(dstModuleFolderPath, subItem); err != nil { + if err = c.doGenerateCtrlItem(dstModuleFolderPath, subItem, merge); err != nil { return } doneApiItemSet.Add(subItem.String()) @@ -115,7 +115,7 @@ func (c *controllerGenerator) doGenerateCtrlNewByModuleAndVersion( return } -func (c *controllerGenerator) doGenerateCtrlItem(dstModuleFolderPath string, item apiItem) (err error) { +func (c *controllerGenerator) doGenerateCtrlItem(dstModuleFolderPath string, item apiItem, merge bool) (err error) { var ( methodNameSnake = gstr.CaseSnake(item.MethodName) ctrlName = fmt.Sprintf(`Controller%s`, gstr.UcFirst(item.Version)) @@ -123,15 +123,40 @@ func (c *controllerGenerator) doGenerateCtrlItem(dstModuleFolderPath string, ite `%s_%s_%s.go`, item.Module, item.Version, methodNameSnake, )) ) - content := gstr.ReplaceByMap(consts.TemplateGenCtrlControllerMethodFunc, g.MapStrStr{ - "{Module}": item.Module, - "{ImportPath}": item.Import, - "{CtrlName}": ctrlName, - "{Version}": item.Version, - "{MethodName}": item.MethodName, - }) - if err = gfile.PutContents(methodFilePath, gstr.TrimLeft(content)); err != nil { - return err + var content string + + if merge { + methodFilePath = gfile.Join(dstModuleFolderPath, fmt.Sprintf( + `%s_%s_%s.go`, item.Module, item.Version, item.FileName, + )) + + } + + if gfile.Exists(methodFilePath) { + content = gstr.ReplaceByMap(consts.TemplateGenCtrlControllerMethodFuncMerge, g.MapStrStr{ + "{Module}": item.Module, + "{CtrlName}": ctrlName, + "{Version}": item.Version, + "{MethodName}": item.MethodName, + }) + + if gstr.Contains(gfile.GetContents(methodFilePath), fmt.Sprintf(`func (c *%v) %v`, ctrlName, item.MethodName)) { + return + } + if err = gfile.PutContentsAppend(methodFilePath, gstr.TrimLeft(content)); err != nil { + return err + } + } else { + content = gstr.ReplaceByMap(consts.TemplateGenCtrlControllerMethodFunc, g.MapStrStr{ + "{Module}": item.Module, + "{ImportPath}": item.Import, + "{CtrlName}": ctrlName, + "{Version}": item.Version, + "{MethodName}": item.MethodName, + }) + if err = gfile.PutContents(methodFilePath, gstr.TrimLeft(content)); err != nil { + return err + } } mlog.Printf(`generated: %s`, methodFilePath) return diff --git a/cmd/gf/internal/consts/consts_gen_ctrl_template.go b/cmd/gf/internal/consts/consts_gen_ctrl_template.go index b2cfdc496..a51786dda 100644 --- a/cmd/gf/internal/consts/consts_gen_ctrl_template.go +++ b/cmd/gf/internal/consts/consts_gen_ctrl_template.go @@ -54,6 +54,13 @@ func (c *{CtrlName}) {MethodName}(ctx context.Context, req *{Version}.{MethodNam } ` +const TemplateGenCtrlControllerMethodFuncMerge = ` + +func (c *{CtrlName}) {MethodName}(ctx context.Context, req *{Version}.{MethodName}Req) (res *{Version}.{MethodName}Res, err error) { + return nil, gerror.NewCode(gcode.CodeNotImplemented) +} +` + const TemplateGenCtrlApiInterface = ` // ================================================================================= // Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.