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 }