github.com/sapplications/sb@v0.0.0-20240116135441-1a13cafe3497/cmd/public.go (about) 1 // Copyright 2022 Vitalii Noha vitalii.noga@gmail.com. All rights reserved. 2 3 // Package cmd represents Command Line Interface. 4 package cmd 5 6 import ( 7 "errors" 8 "fmt" 9 "os" 10 "strings" 11 12 "github.com/sapplications/dl" 13 "github.com/sapplications/sb" 14 "github.com/spf13/cobra" 15 ) 16 17 // SmartBuilder includes all available commands and handles them. 18 type SmartBuilder struct { 19 cobra.Command 20 } 21 22 // Creator describes methods for creating an application by generating smart application unit (.sa file). 23 type Creator interface { 24 Create(string) error 25 } 26 27 // Generator describes methods for generating smart builder unit (.sb) using smart application unit. 28 type Generator interface { 29 Generate(string) error 30 } 31 32 // Coder describes methods for generating code to build the application. 33 type Coder interface { 34 Generate(string) error 35 } 36 37 // Builder describes methods for building an application using the generated items. 38 type Builder interface { 39 Build(string) error 40 } 41 42 // Cleaner describes methods for removing generated/compiled files. 43 type Cleaner interface { 44 Clean(string) error 45 } 46 47 // Runner describes methods for running the application. 48 type Runner interface { 49 Run(string) error 50 } 51 52 // AppsPrinter describes methods for displaying all available applications. 53 type AppsPrinter interface { 54 Apps() ([]string, error) 55 } 56 57 // VersionPrinter describes methods for displaying a version of the application. 58 type VersionPrinter interface { 59 Version() string 60 } 61 62 // ModManager describes methods for managing application items and dependencies. 63 type ModManager interface { 64 AddItem(module, item string) error 65 AddDependency(item, dependency, resolver string, update bool) error 66 DeleteItem(item string) error 67 DeleteDependency(item, dependency string) error 68 ReadAll(kind string) (ModReader, error) 69 } 70 71 // ModReader describes methods for getting module attributes. 72 type ModReader interface { 73 Items() map[string][][]string 74 Dependency(string, string) string 75 } 76 77 // ModFormatter describes methods for formatting module attributes and returns it as a string. 78 type ModFormatter interface { 79 Item(string, [][]string) string 80 String(module ModReader) string 81 } 82 83 const ( 84 // application 85 AppsItemName string = "apps" 86 DefaultModuleName string = "apps" 87 // error messages 88 ErrorMessageF string = "Error: %v\n" 89 AppNameMissing string = "application name is required" 90 SubcmdMissing string = "subcommand is required" 91 ItemMissing string = "item name is required" 92 ModOrDepMissing string = "module name or dependency name is missing" 93 ResolverMissing string = "resolver is required" 94 DependencyMissing string = "\"--dep\" parameter is required" 95 ItemDoesNotExistF string = "\"%s\" item does not exist" 96 DependencyDoesNotExistF string = "\"%s\" dependency item does not exist" 97 UnknownSubcmdF string = "unknown \"%s\" subcommand" 98 ) 99 100 func CmdCreate(c *sb.SmartCreator) func(cmd *cobra.Command, args []string) error { 101 if c == nil { 102 return nil 103 } else { 104 return func(cmd *cobra.Command, args []string) error { 105 if len(args) > 0 { 106 return c.Create(args[0]) 107 } else { 108 return fmt.Errorf(AppNameMissing) 109 } 110 } 111 } 112 } 113 114 func CmdGen(c *sb.SmartGenerator) func(cmd *cobra.Command, args []string) error { 115 if c == nil { 116 return nil 117 } else { 118 return func(cmd *cobra.Command, args []string) error { 119 if len(args) > 0 { 120 return c.Generate(args[0]) 121 } else { 122 return c.Generate("") 123 } 124 } 125 } 126 } 127 128 func CmdCode(c *sb.SmartBuilder) func(cmd *cobra.Command, args []string) error { 129 if c == nil { 130 return nil 131 } else { 132 return func(cmd *cobra.Command, args []string) error { 133 if len(args) > 0 { 134 return c.Generate(args[0]) 135 } else { 136 return c.Generate("") 137 } 138 } 139 } 140 } 141 142 func CmdBuild(c *sb.SmartBuilder) func(cmd *cobra.Command, args []string) error { 143 if c == nil { 144 return nil 145 } else { 146 return func(cmd *cobra.Command, args []string) error { 147 if len(args) > 0 { 148 return c.Build(args[0]) 149 } else { 150 return c.Build("") 151 } 152 } 153 } 154 } 155 156 func CmdClean(c *sb.SmartBuilder) func(cmd *cobra.Command, args []string) error { 157 if c == nil { 158 return nil 159 } else { 160 return func(cmd *cobra.Command, args []string) error { 161 if len(args) > 0 { 162 return c.Clean(args[0]) 163 } else { 164 return c.Clean("") 165 } 166 } 167 } 168 } 169 170 func CmdRun(c *sb.SmartBuilder) func(cmd *cobra.Command, args []string) error { 171 if c == nil { 172 return nil 173 } else { 174 return func(cmd *cobra.Command, args []string) error { 175 if len(args) > 0 { 176 return c.Run(args[0]) 177 } else { 178 return c.Run("") 179 } 180 } 181 } 182 } 183 184 func CmdList(c *sb.ModHelper) func(cmd *cobra.Command, args []string) error { 185 if c == nil { 186 return nil 187 } else { 188 return func(cmd *cobra.Command, args []string) error { 189 apps, err := c.Apps() 190 if err != nil { 191 return err 192 } 193 for _, app := range apps { 194 fmt.Println(app) 195 } 196 return nil 197 } 198 } 199 } 200 201 func CmdVersion(c *sb.SmartBuilder) func(cmd *cobra.Command, args []string) { 202 if c == nil { 203 return nil 204 } else { 205 return func(cmd *cobra.Command, args []string) { 206 fmt.Println(c.Version()) 207 } 208 } 209 } 210 211 func CmdManageMod(c *sb.SmartBuilder, f *dl.Formatter) func(cmd *cobra.Command, args []string) error { 212 if c == nil || f == nil { 213 return nil 214 } else { 215 // depFlags.mod = v.Command.Flags().StringP("mod", "m", "", "module name") 216 // depFlags.item = v.Command.Flags().StringP("name", "n", "", "item name") 217 // depFlags.dep = v.Command.Flags().StringP("dep", "d", "", "dependency name") 218 // depFlags.resolver = v.Command.Flags().StringP("resolver", "r", "", "resolver") 219 // depFlags.all = v.Command.Flags().BoolP("all", "a", false, "print module") 220 return func(cmd *cobra.Command, args []string) error { 221 if len(args) == 0 { 222 return errors.New(SubcmdMissing) 223 } 224 defer handleError() 225 var subCmd = args[0] 226 var modStr = strings.Trim(*depFlags.mod, "\t \n") 227 var itemStr = strings.Trim(*depFlags.item, "\t \n") 228 var depStr = strings.Trim(*depFlags.dep, "\t \n") 229 var resolverStr = strings.Trim(*depFlags.resolver, "\t \n") 230 // handle subcommands 231 switch subCmd { 232 case subCmds.del: 233 // if modStr == "" { 234 // // return errors.New(ModuleMissing) 235 // } 236 // if itemStr == "" { 237 // return errors.New(ItemMissing) 238 // } 239 // if depStr == "" { 240 // return v.Manager.DeleteItem(modStr, itemStr) 241 // } else { 242 // return v.Manager.DeleteDependency(modStr, itemStr, depStr) 243 // } 244 case subCmds.edit: 245 if modStr == "" { 246 // return errors.New(ModuleMissing) 247 } 248 if itemStr == "" { 249 return errors.New(ItemMissing) 250 } 251 if depStr == "" { 252 return errors.New(DependencyMissing) 253 } 254 if resolverStr == "" { 255 return errors.New(ResolverMissing) 256 } 257 return c.AddDependency(itemStr, depStr, resolverStr, true) 258 case subCmds.list: 259 if depStr != "" && itemStr == "" { 260 return errors.New(ItemMissing) 261 } 262 mod, err := c.ReadAll("sb") 263 if err != nil { 264 return err 265 } else if *depFlags.all { 266 fmt.Println(f.String(mod)) 267 } else if itemStr != "" { 268 var item = mod.Items()[itemStr] 269 if item == nil { 270 return fmt.Errorf(ItemDoesNotExistF, itemStr) 271 } else { 272 if depStr == "" { 273 fmt.Print(f.Item(itemStr, item)) 274 } else { 275 found := false 276 for _, row := range item { 277 if row[0] == depStr { 278 found = true 279 break 280 } 281 } 282 if found { 283 fmt.Print(mod.Dependency(itemStr, depStr)) 284 } else { 285 return fmt.Errorf(DependencyDoesNotExistF, depStr) 286 } 287 } 288 } 289 } 290 default: 291 return fmt.Errorf(UnknownSubcmdF, args[0]) 292 } 293 return nil 294 } 295 } 296 } 297 298 func CmdInitMod(c *sb.SmartBuilder) func(cmd *cobra.Command, args []string) error { 299 if c == nil { 300 return nil 301 } else { 302 return func(cmd *cobra.Command, args []string) error { 303 defer handleError() 304 return c.AddItem(DefaultModuleName, AppsItemName) 305 } 306 } 307 } 308 309 func CmdAddToMod(c *sb.SmartBuilder) func(cmd *cobra.Command, args []string) error { 310 if c == nil { 311 return nil 312 } else { 313 return func(cmd *cobra.Command, args []string) error { 314 defer handleError() 315 if len(args) < 1 { 316 return errors.New(ItemMissing) 317 } else if len(args) < 2 { 318 return errors.New(ModOrDepMissing) 319 } else if len(args) == 2 { 320 return c.AddItem(args[1], args[0]) 321 } else if len(args) > 2 { 322 return c.AddDependency(args[0], args[1], args[2], false) 323 } else { 324 return nil 325 } 326 } 327 } 328 } 329 330 func CmdDelFromMod(c *sb.SmartBuilder) func(cmd *cobra.Command, args []string) error { 331 if c == nil { 332 return nil 333 } else { 334 return func(cmd *cobra.Command, args []string) error { 335 defer handleError() 336 if len(args) < 1 { 337 return errors.New(ItemMissing) 338 } else if len(args) == 1 { 339 return c.DeleteItem(args[0]) 340 } else if len(args) == 2 { 341 return c.DeleteDependency(args[1], args[0]) 342 } else { 343 return nil 344 } 345 } 346 } 347 } 348 349 func OSStdout() *os.File { 350 return os.Stdout 351 }