diff --git a/cmd/candi/cli_parser.go b/cmd/candi/cli_parser.go index 6fbab00..02c9acf 100644 --- a/cmd/candi/cli_parser.go +++ b/cmd/candi/cli_parser.go @@ -70,6 +70,19 @@ func parseInput(flagParam *flagParameter) (srvConfig serviceConfig) { goto stageReadInputModule } goto stageSelectServerHandler + + case AddUsecase: + stageAddUsecaseReadInputModule: + flagParam.moduleName = candihelper.ToDelimited(readInput("Please input existing module name to be added usecase(s):"), '-') + moduleDir := flagParam.getFullModuleChildDir() + if err := validateDir(moduleDir); err != nil { + fmt.Print(err.Error()) + goto stageAddUsecaseReadInputModule + } + + flagParam.serviceName = srvConfig.ServiceName + addUsecase(flagParam, readInput("Please input usecase name:")) + return } stageInputModules: diff --git a/cmd/candi/constant.go b/cmd/candi/constant.go index 5f507f0..5335e8e 100644 --- a/cmd/candi/constant.go +++ b/cmd/candi/constant.go @@ -8,6 +8,7 @@ const ( InitMonorepo = "initMonorepo" RunServiceMonorepo = "runServiceMonorepo" AddHandler = "addHandler" + AddUsecase = "addUsecase" RestHandler = "restHandler" GrpcHandler = "grpcHandler" diff --git a/cmd/candi/main.go b/cmd/candi/main.go index ba96115..c9bb0e5 100644 --- a/cmd/candi/main.go +++ b/cmd/candi/main.go @@ -81,7 +81,8 @@ func main() { "1) Init monorepo codebase\n" + "2) Init service\n" + "3) Add module(s) in service\n" + - "4) Add delivery handler(s) in module\033[0m\n>> ") + "4) Add delivery handler(s) in module\n" + + "5) Add usecase(s) in module\033[0m\n>> ") flagParam.scopeFlag = readInput() } @@ -108,7 +109,7 @@ func selectScope(flagParam flagParameter, scope string) { } monorepoGenerator(flagParam) return - case RunServiceMonorepo: // 5 + case RunServiceMonorepo: // 6 serviceRunner(flagParam.serviceName) return case InitService: diff --git a/cmd/candi/project_generator.go b/cmd/candi/project_generator.go index 5ceb865..fe9f42e 100644 --- a/cmd/candi/project_generator.go +++ b/cmd/candi/project_generator.go @@ -15,7 +15,7 @@ import ( ) func projectGenerator(flagParam flagParameter, scope string, srvConfig serviceConfig) { - if flagParam.addHandler { + if flagParam.addHandler || scope == AddUsecase { return } diff --git a/cmd/candi/project_generator_add_handler.go b/cmd/candi/project_generator_add_handler.go index b66be9c..858dfc4 100644 --- a/cmd/candi/project_generator_add_handler.go +++ b/cmd/candi/project_generator_add_handler.go @@ -171,7 +171,7 @@ func scopeAddHandler(flagParam *flagParameter, cfg serviceConfig, serverHandlers root := FileStructure{ Skip: true, Childs: []FileStructure{ apiStructure, internalServiceStructure, { - Source: modCfg.toJSONString(), FileName: "candi.json", + Source: cfg.toJSONString(), FileName: "candi.json", }, }, } diff --git a/cmd/candi/project_generator_add_usecase.go b/cmd/candi/project_generator_add_usecase.go new file mode 100644 index 0000000..91d475f --- /dev/null +++ b/cmd/candi/project_generator_add_usecase.go @@ -0,0 +1,33 @@ +package main + +import ( + "log" + "strings" + + "github.com/golangid/candi/candihelper" +) + +func addUsecase(flagParam *flagParameter, usecaseName string) { + targetDir := "" + if isWorkdirMonorepo() { + targetDir = flagParam.outputFlag + flagParam.serviceName + "/" + } + + fs := FileStructure{ + FromTemplate: true, + DataSource: map[string]any{"ModuleName": flagParam.moduleName, "UsecaseName": usecaseName}, + Source: templateNewUsecase, + FileName: candihelper.ToDelimited(usecaseName, '_') + ".go", + } + if err := fs.writeFile(targetDir + "internal/modules/" + flagParam.moduleName + "/usecase"); err != nil { + log.Fatal(err) + } + + fu := fileUpdate{ + filepath: targetDir + "internal/modules/" + flagParam.moduleName + "/usecase/usecase.go", + oldContent: `type ` + strings.Title(candihelper.ToCamelCase(flagParam.moduleName)) + `Usecase interface {`, + newContent: `type ` + strings.Title(candihelper.ToCamelCase(flagParam.moduleName)) + `Usecase interface { + ` + strings.Title(candihelper.ToCamelCase(usecaseName)) + `(ctx context.Context) (err error)`, + } + fu.readFileAndApply() +} diff --git a/cmd/candi/template_usecase.go b/cmd/candi/template_usecase.go index ed3b538..918d957 100644 --- a/cmd/candi/template_usecase.go +++ b/cmd/candi/template_usecase.go @@ -502,5 +502,21 @@ func TestNew{{upper (camel .ModuleName)}}Usecase(t *testing.T) { setFunc(nil) assert.NotNil(t, uc) } +` + + templateNewUsecase = `package usecase + +import ( + "context" + + "github.com/golangid/candi/tracer" +) + +func (uc *{{camel .ModuleName}}UsecaseImpl) {{upper (camel .UsecaseName)}}(ctx context.Context) (err error) { + trace, ctx := tracer.StartTraceWithContext(ctx, "{{upper (camel .ModuleName)}}Usecase:{{upper (camel .UsecaseName)}}") + defer trace.Finish() + + return +} ` ) diff --git a/cmd/candi/types.go b/cmd/candi/types.go index ff38c25..8889c5d 100644 --- a/cmd/candi/types.go +++ b/cmd/candi/types.go @@ -7,6 +7,7 @@ import ( "fmt" "log" "os" + "path/filepath" "strings" "text/template" "time" @@ -16,7 +17,7 @@ import ( var ( scopeMap = map[string]string{ - "1": InitMonorepo, "2": InitService, "3": AddModule, "4": AddHandler, + "1": InitMonorepo, "2": InitService, "3": AddModule, "4": AddHandler, "5": AddUsecase, } dependencyMap = map[string]string{ @@ -204,3 +205,22 @@ type FileStructure struct { SkipIfExist bool Childs []FileStructure } + +func (f *FileStructure) parseTemplate() (buff []byte) { + if f.FromTemplate { + if f.Source != "" { + buff = loadTemplate(f.Source, f.DataSource) + } else { + lastDir := filepath.Dir(f.TargetDir) + buff = defaultDataSource(lastDir[strings.LastIndex(lastDir, "/")+1:]) + } + } else { + buff = []byte(f.Source) + } + return +} + +func (f *FileStructure) writeFile(targetPath string) error { + fmt.Printf("creating %s...\n", targetPath+"/"+f.FileName) + return os.WriteFile(targetPath+"/"+f.FileName, f.parseTemplate(), 0644) +}