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(&params.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  }