OSDN Git Service

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