github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/cmd/vpm/main.go (about) 1 /* 2 * Copyright (c) 2023-present unTill Pro, Ltd. 3 * @author Alisher Nurmanov 4 */ 5 6 package main 7 8 import ( 9 _ "embed" 10 "fmt" 11 "os" 12 "strconv" 13 "strings" 14 15 "github.com/spf13/cobra" 16 "github.com/spf13/pflag" 17 "github.com/voedger/voedger/pkg/goutils/cobrau" 18 ) 19 20 //go:embed version 21 var version string 22 23 func main() { 24 if err := execRootCmd(os.Args, version); err != nil { 25 fmt.Println(err) 26 os.Exit(1) 27 } 28 } 29 30 func execRootCmd(args []string, ver string) error { 31 params := &vpmParams{} 32 rootCmd := cobrau.PrepareRootCmd( 33 "vpm", 34 "", 35 args, 36 ver, 37 newCompileCmd(params), 38 newBaselineCmd(params), 39 newCompatCmd(params), 40 newOrmCmd(params), 41 newInitCmd(params), 42 newTidyCmd(params), 43 newBuildCmd(params), 44 ) 45 rootCmd.InitDefaultHelpCmd() 46 rootCmd.InitDefaultCompletionCmd() 47 correctCommandTexts(rootCmd) 48 initGlobalFlags(rootCmd, params) 49 rootCmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error { 50 return prepareParams(cmd, params, args) 51 } 52 setNoArgs(rootCmd) 53 return cobrau.ExecCommandAndCatchInterrupt(rootCmd) 54 } 55 56 func setNoArgs(cmd *cobra.Command) { 57 if cmd.Args == nil { 58 cmd.Args = exactArgs(0) 59 } 60 for _, subCmd := range cmd.Commands() { 61 setNoArgs(subCmd) 62 } 63 } 64 65 // correctCommandTexts makes first letter of command and its flags descriptions small 66 // works recursively for all subcommands 67 func correctCommandTexts(cmd *cobra.Command) { 68 correctCommandFlagTexts(cmd) 69 for _, c := range cmd.Commands() { 70 c.Short = makeFirstLetterSmall(c.Short) 71 correctCommandTexts(c) 72 } 73 } 74 75 func correctCommandFlagTexts(cmd *cobra.Command) { 76 correctFlagSetTexts(cmd.Flags()) 77 correctFlagSetTexts(cmd.PersistentFlags()) 78 } 79 80 func correctFlagSetTexts(fs *pflag.FlagSet) { 81 fs.VisitAll(func(f *pflag.Flag) { 82 f.Usage = makeFirstLetterSmall(f.Usage) 83 }) 84 } 85 86 func makeFirstLetterSmall(s string) string { 87 if len(s) == 0 { 88 return s 89 } 90 return strings.ToLower(s[0:1]) + s[1:] 91 } 92 93 func initGlobalFlags(cmd *cobra.Command, params *vpmParams) { 94 cmd.SilenceErrors = true 95 cmd.PersistentFlags().StringVarP(¶ms.Dir, "change-dir", "C", "", "change to dir before running the command. Any files named on the command line are interpreted after changing directories") 96 } 97 98 func exactArgs(n int) cobra.PositionalArgs { 99 return func(cmd *cobra.Command, args []string) error { 100 runHelpFuncInstead := func(cmd *cobra.Command, args []string) error { 101 if err := cmd.Help(); err != nil { 102 return err 103 } 104 return nil 105 } 106 switch { 107 case len(args) == 1 && args[0] == "help": 108 cmd.RunE = runHelpFuncInstead 109 return nil 110 case len(args) != n: 111 strCountOfArgs := strconv.Itoa(n) 112 if n == 0 { 113 strCountOfArgs = "no" 114 } 115 return fmt.Errorf("'%s' accepts %s arg(s). Run '%s help'", cmd.CommandPath(), strCountOfArgs, cmd.CommandPath()) 116 } 117 return nil 118 } 119 }