@@ -7,37 +7,62 @@ package gh
7
7
8
8
import (
9
9
"bytes"
10
+ "context"
10
11
"fmt"
12
+ "io"
13
+ "os"
11
14
"os/exec"
12
15
13
16
"github.com/cli/safeexec"
14
17
)
15
18
16
- // Exec gh command with provided arguments .
17
- func Exec (args ... string ) (stdOut , stdErr bytes.Buffer , err error ) {
18
- path , err := path ()
19
+ // Exec invokes a gh command in a subprocess and captures the output and error streams .
20
+ func Exec (args ... string ) (stdout , stderr bytes.Buffer , err error ) {
21
+ ghExe , err := ghLookPath ()
19
22
if err != nil {
20
- err = fmt .Errorf ("could not find gh executable in PATH. error: %w" , err )
21
23
return
22
24
}
23
- return run (path , nil , args ... )
25
+ err = run (context .Background (), ghExe , nil , nil , & stdout , & stderr , args )
26
+ return
27
+ }
28
+
29
+ // ExecContext invokes a gh command in a subprocess and captures the output and error streams.
30
+ func ExecContext (ctx context.Context , args ... string ) (stdout , stderr bytes.Buffer , err error ) {
31
+ ghExe , err := ghLookPath ()
32
+ if err != nil {
33
+ return
34
+ }
35
+ err = run (ctx , ghExe , nil , nil , & stdout , & stderr , args )
36
+ return
24
37
}
25
38
26
- func path () (string , error ) {
39
+ // Exec invokes a gh command in a subprocess with its stdin, stdout, and stderr streams connected to
40
+ // those of the parent process. This is suitable for running gh commands with interactive prompts.
41
+ func ExecInteractive (ctx context.Context , args ... string ) error {
42
+ ghExe , err := ghLookPath ()
43
+ if err != nil {
44
+ return err
45
+ }
46
+ return run (ctx , ghExe , nil , os .Stdin , os .Stdout , os .Stderr , args )
47
+ }
48
+
49
+ func ghLookPath () (string , error ) {
50
+ if ghExe := os .Getenv ("GH_PATH" ); ghExe != "" {
51
+ return ghExe , nil
52
+ }
27
53
return safeexec .LookPath ("gh" )
28
54
}
29
55
30
- func run (path string , env []string , args ... string ) (stdOut , stdErr bytes.Buffer , err error ) {
31
- cmd := exec .Command (path , args ... )
32
- cmd .Stdout = & stdOut
33
- cmd .Stderr = & stdErr
56
+ func run (ctx context.Context , ghExe string , env []string , stdin io.Reader , stdout , stderr io.Writer , args []string ) error {
57
+ cmd := exec .CommandContext (ctx , ghExe , args ... )
58
+ cmd .Stdin = stdin
59
+ cmd .Stdout = stdout
60
+ cmd .Stderr = stderr
34
61
if env != nil {
35
62
cmd .Env = env
36
63
}
37
- err = cmd .Run ()
38
- if err != nil {
39
- err = fmt .Errorf ("failed to run gh: %s. error: %w" , stdErr .String (), err )
40
- return
64
+ if err := cmd .Run (); err != nil {
65
+ return fmt .Errorf ("gh execution failed: %w" , err )
41
66
}
42
- return
67
+ return nil
43
68
}
0 commit comments