github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/cmd/cli/commands/generate/controller/generator.go (about) 1 // This file is part of the Smart Home 2 // Program complex distribution https://github.com/e154/smart-home 3 // Copyright (C) 2016-2023, Filippov Alex 4 // 5 // This library is free software: you can redistribute it and/or 6 // modify it under the terms of the GNU Lesser General Public 7 // License as published by the Free Software Foundation; either 8 // version 3 of the License, or (at your option) any later version. 9 // 10 // This library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 // Library General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public 16 // License along with this library. If not, see 17 // <https://www.gnu.org/licenses/>. 18 19 package controller 20 21 import ( 22 "os" 23 "path" 24 "strings" 25 "text/template" 26 27 "github.com/e154/smart-home/common/logger" 28 29 "github.com/e154/smart-home/cmd/cli/commands/generate" 30 "github.com/e154/smart-home/common" 31 "github.com/spf13/cobra" 32 ) 33 34 var ( 35 log = logger.MustGetLogger("controller") 36 ) 37 38 var controllerTpl = `//CODE GENERATED AUTOMATICALLY 39 40 package {{.Package}} 41 42 import ( 43 "context" 44 "net/http" 45 46 "google.golang.org/grpc/codes" 47 "google.golang.org/grpc/status" 48 "google.golang.org/protobuf/types/known/emptypb" 49 50 "{{.Dir}}/api/stub/api" 51 ) 52 53 // {{.Name}} ... 54 type Controller{{.Name}} struct { 55 *ControllerCommon 56 } 57 58 func NewController{{.Name}}(common *ControllerCommon) Controller{{.Name}} { 59 return Controller{{.Name}}{ 60 ControllerCommon: common, 61 } 62 } 63 64 // AddEntity{{.Name}} ... 65 func (c Controller{{.Name}}) AddEntity{{.Name}}(_ context.Context, req *api.New{{.Name}}Request) (*api.{{.Name}}, error) { 66 67 image, errs, err := c.endpoint.{{.EndpointName}}.AddEntity(c.dto.{{.Name}}.FromNew{{.Name}}Request(req)) 68 if len(errs) > 0 { 69 return nil, c.prepareErrors(errs) 70 } 71 72 if err != nil { 73 return nil, status.Error(codes.Internal, err.Error()) 74 } 75 76 return c.dto.{{.Name}}.To{{.Name}}(image), nil 77 } 78 79 // Get{{.Name}} ... 80 func (c Controller{{.Name}}) Get{{.Name}}ById(_ context.Context, req *api.Get{{.Name}}Request) (*api.{{.Name}}, error) { 81 82 image, err := c.endpoint.{{.EndpointName}}.GetById(int64(req.Id)) 83 if err != nil { 84 if err.Error() == "record not found" { 85 return nil, status.Error(codes.NotFound, err.Error()) 86 } 87 return nil, status.Error(codes.Internal, err.Error()) 88 } 89 90 return c.dto.{{.Name}}.To{{.Name}}(image), nil 91 } 92 93 // UpdateEntity{{.Name}}ById ... 94 func (c Controller{{.Name}}) UpdateEntity{{.Name}}ById(_ context.Context, req *api.UpdateEntity{{.Name}}Request) (*api.{{.Name}}, error) { 95 96 image, errs, err := c.endpoint.{{.EndpointName}}.UpdateEntity(c.dto.{{.Name}}.FromUpdate{{.Name}}Request(req)) 97 if len(errs) > 0 { 98 return nil, c.prepareErrors(errs) 99 } 100 101 if err != nil { 102 if err.Error() == "record not found" { 103 return nil, status.Error(codes.NotFound, err.Error()) 104 } 105 return nil, status.Error(codes.Internal, err.Error()) 106 } 107 108 return c.dto.{{.Name}}.To{{.Name}}(image), nil 109 } 110 111 // Get{{.Name}}List ... 112 func (c Controller{{.Name}}) Get{{.Name}}List(_ context.Context, req *api.PaginationRequest) (*api.Get{{.Name}}ListResult, error) { 113 114 pagination := c.Pagination(req.Page, req.Limit, req.Sort) 115 items, total, err := c.endpoint.{{.EndpointName}}.List(ctx, pagination) 116 if err != nil { 117 return nil, c.error(ctx, nil, err) 118 } 119 120 return c.dto.{{.EndpointName}}.GetTaskList(items, uint64(total), pagination), nil 121 } 122 123 // Delete{{.Name}}ById ... 124 func (c Controller{{.Name}}) Delete{{.Name}}ById(_ context.Context, req *api.Delete{{.Name}}Request) (*emptypb.Empty, error) { 125 126 if err := c.endpoint.{{.EndpointName}}.Delete(int64(req.Id)); err != nil { 127 if err.Error() == "record not found" { 128 return nil, status.Error(codes.NotFound, err.Error()) 129 } 130 return nil, status.Error(codes.Internal, err.Error()) 131 } 132 133 return &emptypb.Empty{}, nil 134 } 135 136 ` 137 138 var ( 139 controllerCmd = &cobra.Command{ 140 Use: "c", 141 Short: "controller generator", 142 Long: "$ cli g c [-endpoint=endpointName] [controllerName]", 143 } 144 endpointName string 145 packageName = "controllers" 146 ) 147 148 func init() { 149 generate.Generate.AddCommand(controllerCmd) 150 controllerCmd.Flags().StringVarP(&endpointName, "endpoint", "e", "EndpointName", "EndpointName") 151 controllerCmd.Run = func(cmd *cobra.Command, args []string) { 152 153 if len(args) == 0 { 154 log.Error("Wrong number of arguments. Run: cli help generate") 155 return 156 } 157 158 currpath, _ := os.Getwd() 159 160 g := Generator{} 161 g.Generate(args[0], currpath) 162 } 163 } 164 165 // Generator ... 166 type Generator struct{} 167 168 // Generate ... 169 func (e Generator) Generate(controllerName, currpath string) { 170 171 log.Infof("Using '%s' as controller name", controllerName) 172 log.Infof("Using '%s' as package name", packageName) 173 174 fp := path.Join(currpath, "api", "controllers") 175 176 e.addController(fp, controllerName) 177 } 178 179 func (e Generator) addController(fp, controllerName string) { 180 181 if _, err := os.Stat(fp); os.IsNotExist(err) { 182 // Create the controller's directory 183 if err := os.MkdirAll(fp, 0777); err != nil { 184 log.Errorf("Could not create controllers directory: %s", err.Error()) 185 return 186 } 187 } 188 189 fpath := path.Join(fp, strings.ToLower(controllerName)+".go") 190 f, err := os.OpenFile(fpath, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0666) 191 if err != nil { 192 log.Errorf("Could not create controller file: %s", err.Error()) 193 return 194 } 195 defer f.Close() 196 197 templateData := struct { 198 Package string 199 Name string 200 List string 201 EndpointName string 202 Dir string 203 }{ 204 Dir: common.Dir(), 205 Package: packageName, 206 Name: controllerName, 207 EndpointName: endpointName, 208 } 209 t := template.Must(template.New("controller").Parse(controllerTpl)) 210 211 if t.Execute(f, templateData) != nil { 212 log.Error(err.Error()) 213 } 214 215 common.FormatSourceCode(fpath) 216 }