github.com/Benchkram/bob@v0.0.0-20220321080157-7c8f3876e225/pkg/cmdutil/run.go (about) 1 package cmdutil 2 3 import ( 4 "bytes" 5 "fmt" 6 "os/exec" 7 "strconv" 8 9 "github.com/cli/cli/git" 10 ) 11 12 type Runnable interface { 13 Run() error 14 Output() ([]byte, error) 15 OutputCombined() ([]byte, error) 16 } 17 18 type run struct { 19 cmd *exec.Cmd 20 } 21 22 func (run *run) Run() error { 23 var stdout, stderr bytes.Buffer 24 run.cmd.Stdout = &stdout 25 run.cmd.Stderr = &stderr 26 27 err := run.cmd.Run() 28 if err != nil { 29 return CmdError{ 30 Stderr: &stderr, 31 Args: run.cmd.Args, 32 Err: err, 33 } 34 } 35 36 return nil 37 } 38 39 func (run *run) Output() ([]byte, error) { 40 var stderr bytes.Buffer 41 run.cmd.Stderr = &stderr 42 43 output, err := run.cmd.Output() 44 45 if err != nil { 46 return nil, CmdError{ 47 Stderr: &stderr, 48 Args: run.cmd.Args, 49 Err: err, 50 } 51 } 52 53 return output, nil 54 } 55 56 func (run *run) OutputCombined() ([]byte, error) { 57 var b bytes.Buffer 58 run.cmd.Stdout = &b 59 run.cmd.Stderr = &b 60 61 err := run.cmd.Run() 62 if err != nil { 63 return nil, CmdError{ 64 Stderr: &b, 65 Args: run.cmd.Args, 66 Err: err, 67 } 68 } 69 70 return b.Bytes(), nil 71 } 72 73 // gitprepare inits git cmd with `root` as the working dir. 74 func gitprepare(root string, args ...string) (r Runnable, _ error) { 75 cmd, err := git.GitCommand(args...) 76 if err != nil { 77 return r, fmt.Errorf("failed to make git command: %w", err) 78 } 79 80 cmd.Dir = root 81 82 return &run{cmd}, nil 83 } 84 85 func RunGit(root string, args ...string) error { 86 r, err := gitprepare(root, args...) 87 if err != nil { 88 return err 89 } 90 return r.Run() 91 } 92 93 func RunGitWithOutput(root string, args ...string) ([]byte, error) { 94 r, err := gitprepare(root, args...) 95 if err != nil { 96 return nil, err 97 } 98 return r.OutputCombined() 99 } 100 101 func GitStatus(root string) ([]byte, error) { 102 r, err := gitprepare(root, "status", "--porcelain") 103 if err != nil { 104 return nil, err 105 } 106 return r.Output() 107 } 108 109 func GitDryCommit(root string, message string) ([]byte, error) { 110 r, err := gitprepare(root, "commit", "-m", strconv.Quote(message), "--dry-run", "--porcelain") 111 if err != nil { 112 return nil, err 113 } 114 return r.Output() 115 } 116 117 func GitCommit(root string, message string) ([]byte, error) { 118 r, err := gitprepare(root, "commit", "-m", strconv.Quote(message)) 119 if err != nil { 120 return nil, err 121 } 122 return r.OutputCombined() 123 } 124 125 func GitAddDry(root string, targetDir string) ([]byte, error) { 126 r, err := gitprepare(root, "add", targetDir, "--dry-run") 127 if err != nil { 128 return nil, err 129 } 130 131 return r.Output() 132 } 133 134 func GitAdd(root string, targetDir string) error { 135 r, err := gitprepare(root, "add", targetDir) 136 if err != nil { 137 return err 138 } 139 140 return r.Run() 141 }