github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/libs/cli/helper.go (about)

     1  package cli
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"os"
     8  	"path/filepath"
     9  	"runtime"
    10  
    11  	"github.com/spf13/cobra"
    12  	"github.com/spf13/viper"
    13  )
    14  
    15  // RunWithArgs executes the given command with the specified command line args
    16  // and environmental variables set. It returns any error returned from cmd.Execute()
    17  //
    18  // This is only used in testing.
    19  func RunWithArgs(ctx context.Context, cmd *cobra.Command, args []string, env map[string]string) error {
    20  	oargs := os.Args
    21  	oenv := map[string]string{}
    22  	// defer returns the environment back to normal
    23  	defer func() {
    24  		os.Args = oargs
    25  		for k, v := range oenv {
    26  			os.Setenv(k, v)
    27  		}
    28  	}()
    29  
    30  	// set the args and env how we want them
    31  	os.Args = args
    32  	for k, v := range env {
    33  		// backup old value if there, to restore at end
    34  		oenv[k] = os.Getenv(k)
    35  		err := os.Setenv(k, v)
    36  		if err != nil {
    37  			return err
    38  		}
    39  	}
    40  
    41  	// and finally run the command
    42  	return RunWithTrace(ctx, cmd)
    43  }
    44  
    45  func RunWithTrace(ctx context.Context, cmd *cobra.Command) error {
    46  	cmd.SilenceUsage = true
    47  	cmd.SilenceErrors = true
    48  
    49  	if err := cmd.ExecuteContext(ctx); err != nil {
    50  		if viper.GetBool(TraceFlag) {
    51  			const size = 64 << 10
    52  			buf := make([]byte, size)
    53  			buf = buf[:runtime.Stack(buf, false)]
    54  			fmt.Fprintf(os.Stderr, "ERROR: %v\n%s\n", err, buf)
    55  		} else {
    56  			fmt.Fprintf(os.Stderr, "ERROR: %v\n", err)
    57  		}
    58  
    59  		return err
    60  	}
    61  	return nil
    62  }
    63  
    64  // WriteConfigVals writes a toml file with the given values.
    65  // It returns an error if writing was impossible.
    66  func WriteConfigVals(dir string, vals map[string]string) error {
    67  	data := ""
    68  	for k, v := range vals {
    69  		data += fmt.Sprintf("%s = \"%s\"\n", k, v)
    70  	}
    71  	cfile := filepath.Join(dir, "config.toml")
    72  	return ioutil.WriteFile(cfile, []byte(data), 0600)
    73  }
    74  
    75  // NewCompletionCmd returns a cobra.Command that generates bash and zsh
    76  // completion scripts for the given root command. If hidden is true, the
    77  // command will not show up in the root command's list of available commands.
    78  func NewCompletionCmd(rootCmd *cobra.Command, hidden bool) *cobra.Command {
    79  	flagZsh := "zsh"
    80  	cmd := &cobra.Command{
    81  		Use:   "completion",
    82  		Short: "Generate shell completion scripts",
    83  		Long: fmt.Sprintf(`Generate Bash and Zsh completion scripts and print them to STDOUT.
    84  
    85  Once saved to file, a completion script can be loaded in the shell's
    86  current session as shown:
    87  
    88     $ . <(%s completion)
    89  
    90  To configure your bash shell to load completions for each session add to
    91  your $HOME/.bashrc or $HOME/.profile the following instruction:
    92  
    93     . <(%s completion)
    94  `, rootCmd.Use, rootCmd.Use),
    95  		RunE: func(cmd *cobra.Command, _ []string) error {
    96  			zsh, err := cmd.Flags().GetBool(flagZsh)
    97  			if err != nil {
    98  				return err
    99  			}
   100  			if zsh {
   101  				return rootCmd.GenZshCompletion(cmd.OutOrStdout())
   102  			}
   103  			return rootCmd.GenBashCompletion(cmd.OutOrStdout())
   104  		},
   105  		Hidden: hidden,
   106  		Args:   cobra.NoArgs,
   107  	}
   108  
   109  	cmd.Flags().Bool(flagZsh, false, "Generate Zsh completion script")
   110  
   111  	return cmd
   112  }