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  }