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.

93 lines
2.4 KiB

8 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  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
  52. // line args and environmental variables set. It returns string fields
  53. // representing output written to stdout and stderr, additionally any error
  54. // from cmd.Execute() is also returned
  55. func RunCaptureWithArgs(cmd Executable, args []string, env map[string]string) (stdout, stderr string, err error) {
  56. oldout, olderr := os.Stdout, os.Stderr // keep backup of the real stdout
  57. rOut, wOut, _ := os.Pipe()
  58. rErr, wErr, _ := os.Pipe()
  59. os.Stdout, os.Stderr = wOut, wErr
  60. defer func() {
  61. os.Stdout, os.Stderr = oldout, olderr // restoring the real stdout
  62. }()
  63. // copy the output in a separate goroutine so printing can't block indefinitely
  64. copyStd := func(reader *os.File) *(chan string) {
  65. stdC := make(chan string)
  66. go func() {
  67. var buf bytes.Buffer
  68. // io.Copy will end when we call reader.Close() below
  69. io.Copy(&buf, reader)
  70. stdC <- buf.String()
  71. }()
  72. return &stdC
  73. }
  74. outC := copyStd(rOut)
  75. errC := copyStd(rErr)
  76. // now run the command
  77. err = RunWithArgs(cmd, args, env)
  78. // and grab the stdout to return
  79. wOut.Close()
  80. wErr.Close()
  81. stdout = <-*outC
  82. stderr = <-*errC
  83. return stdout, stderr, err
  84. }