You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

60 lines
1.3 KiB

  1. package cli
  2. import (
  3. "context"
  4. "fmt"
  5. "os"
  6. "runtime"
  7. "github.com/spf13/cobra"
  8. "github.com/spf13/viper"
  9. )
  10. // RunWithArgs executes the given command with the specified command line args
  11. // and environmental variables set. It returns any error returned from cmd.Execute()
  12. //
  13. // This is only used in testing.
  14. func RunWithArgs(ctx context.Context, cmd *cobra.Command, args []string, env map[string]string) error {
  15. oargs := os.Args
  16. oenv := map[string]string{}
  17. // defer returns the environment back to normal
  18. defer func() {
  19. os.Args = oargs
  20. for k, v := range oenv {
  21. os.Setenv(k, v)
  22. }
  23. }()
  24. // set the args and env how we want them
  25. os.Args = args
  26. for k, v := range env {
  27. // backup old value if there, to restore at end
  28. oenv[k] = os.Getenv(k)
  29. err := os.Setenv(k, v)
  30. if err != nil {
  31. return err
  32. }
  33. }
  34. // and finally run the command
  35. return RunWithTrace(ctx, cmd)
  36. }
  37. func RunWithTrace(ctx context.Context, cmd *cobra.Command) error {
  38. cmd.SilenceUsage = true
  39. cmd.SilenceErrors = true
  40. if err := cmd.ExecuteContext(ctx); err != nil {
  41. if viper.GetBool(TraceFlag) {
  42. const size = 64 << 10
  43. buf := make([]byte, size)
  44. buf = buf[:runtime.Stack(buf, false)]
  45. fmt.Fprintf(os.Stderr, "ERROR: %v\n%s\n", err, buf)
  46. } else {
  47. fmt.Fprintf(os.Stderr, "ERROR: %v\n", err)
  48. }
  49. return err
  50. }
  51. return nil
  52. }