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.

84 lines
2.1 KiB

  1. package cli
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io"
  6. "io/ioutil"
  7. "os"
  8. "path/filepath"
  9. )
  10. // WriteDemoConfig writes a toml file with the given values.
  11. // It returns the RootDir the config.toml file is stored in,
  12. // or an error if writing was impossible
  13. func WriteDemoConfig(vals map[string]string) (string, error) {
  14. cdir, err := ioutil.TempDir("", "test-cli")
  15. if err != nil {
  16. return "", err
  17. }
  18. data := ""
  19. for k, v := range vals {
  20. data = data + fmt.Sprintf("%s = \"%s\"\n", k, v)
  21. }
  22. cfile := filepath.Join(cdir, "config.toml")
  23. err = ioutil.WriteFile(cfile, []byte(data), 0666)
  24. return cdir, err
  25. }
  26. // RunWithArgs executes the given command with the specified command line args
  27. // and environmental variables set. It returns any error returned from cmd.Execute()
  28. func RunWithArgs(cmd Executable, args []string, env map[string]string) error {
  29. oargs := os.Args
  30. oenv := map[string]string{}
  31. // defer returns the environment back to normal
  32. defer func() {
  33. os.Args = oargs
  34. for k, v := range oenv {
  35. os.Setenv(k, v)
  36. }
  37. }()
  38. // set the args and env how we want them
  39. os.Args = args
  40. for k, v := range env {
  41. // backup old value if there, to restore at end
  42. oenv[k] = os.Getenv(k)
  43. err := os.Setenv(k, v)
  44. if err != nil {
  45. return err
  46. }
  47. }
  48. // and finally run the command
  49. return cmd.Execute()
  50. }
  51. // RunCaptureWithArgs executes the given command with the specified command line args
  52. // and environmental variables set. It returns whatever was writen to
  53. // stdout along with any error returned from cmd.Execute()
  54. func RunCaptureWithArgs(cmd Executable, args []string, env map[string]string) (output string, err error) {
  55. old := os.Stdout // keep backup of the real stdout
  56. r, w, _ := os.Pipe()
  57. os.Stdout = w
  58. defer func() {
  59. os.Stdout = old // restoring the real stdout
  60. }()
  61. outC := make(chan string)
  62. // copy the output in a separate goroutine so printing can't block indefinitely
  63. go func() {
  64. var buf bytes.Buffer
  65. // io.Copy will end when we call w.Close() below
  66. io.Copy(&buf, r)
  67. outC <- buf.String()
  68. }()
  69. // now run the command
  70. err = RunWithArgs(cmd, args, env)
  71. // and grab the stdout to return
  72. w.Close()
  73. output = <-outC
  74. return output, err
  75. }