提交 a16a1216 编写于 作者: J Jingwen Owen Ou

Merge pull request #714 from github/exec_cmd

Use `Exec` except Windows for the last command run in the commands chain
......@@ -2,11 +2,14 @@ package cmd
import (
"fmt"
"github.com/github/hub/utils"
"github.com/github/hub/Godeps/_workspace/src/github.com/kballard/go-shellquote"
"os"
"os/exec"
"runtime"
"strings"
"syscall"
"github.com/github/hub/Godeps/_workspace/src/github.com/kballard/go-shellquote"
"github.com/github/hub/utils"
)
type Cmd struct {
......@@ -34,19 +37,25 @@ func (cmd *Cmd) WithArgs(args ...string) *Cmd {
return cmd
}
func (cmd *Cmd) ExecOutput() (string, error) {
func (cmd *Cmd) CombinedOutput() (string, error) {
output, err := exec.Command(cmd.Name, cmd.Args...).CombinedOutput()
return string(output), err
}
func (cmd *Cmd) Exec() error {
binary, lookErr := exec.LookPath(cmd.Name)
if lookErr != nil {
return fmt.Errorf("command not found: %s", cmd.Name)
// Run runs command with `Exec` on platforms except Windows
// which only supports `Spawn`
func (cmd *Cmd) Run() error {
if runtime.GOOS == "windows" {
return cmd.Spawn()
} else {
return cmd.Exec()
}
}
c := exec.Command(binary, cmd.Args...)
// Spawn runs command with spawn(3)
func (cmd *Cmd) Spawn() error {
c := exec.Command(cmd.Name, cmd.Args...)
c.Stdin = os.Stdin
c.Stdout = os.Stdout
c.Stderr = os.Stderr
......@@ -54,6 +63,20 @@ func (cmd *Cmd) Exec() error {
return c.Run()
}
// Exec runs command with exec(3)
// Note that Windows doesn't support exec(3): http://golang.org/src/pkg/syscall/exec_windows.go#L339
func (cmd *Cmd) Exec() error {
binary, err := exec.LookPath(cmd.Name)
if err != nil {
return fmt.Errorf("command not found: %s", cmd.Name)
}
args := []string{binary}
args = append(args, cmd.Args...)
return syscall.Exec(binary, args, os.Environ())
}
func New(cmd string) *Cmd {
cmds, err := shellquote.Split(cmd)
utils.Check(err)
......
......@@ -7,11 +7,11 @@ import (
"strings"
"syscall"
"github.com/github/hub/Godeps/_workspace/src/github.com/kballard/go-shellquote"
flag "github.com/github/hub/Godeps/_workspace/src/github.com/ogier/pflag"
"github.com/github/hub/cmd"
"github.com/github/hub/git"
"github.com/github/hub/utils"
"github.com/github/hub/Godeps/_workspace/src/github.com/kballard/go-shellquote"
flag "github.com/github/hub/Godeps/_workspace/src/github.com/ogier/pflag"
)
type ExecError struct {
......@@ -76,7 +76,7 @@ func (r *Runner) Execute() ExecError {
return r.Call(cmd, args)
}
err = git.Spawn(args.Command, args.Params...)
err = git.Run(args.Command, args.Params...)
return newExecError(err)
}
......@@ -106,8 +106,15 @@ func printCommands(cmds []*cmd.Cmd) {
}
func executeCommands(cmds []*cmd.Cmd) error {
for _, c := range cmds {
err := c.Exec()
for i, c := range cmds {
var err error
// Run with `Exec` for the last command in chain
if i == len(cmds)-1 {
err = c.Run()
} else {
err = c.Spawn()
}
if err != nil {
return err
}
......
......@@ -48,7 +48,7 @@ func (r *TestRepo) Setup() {
func (r *TestRepo) clone(repo, dir string) error {
cmd := cmd.New("git").WithArgs("clone", repo, dir)
output, err := cmd.ExecOutput()
output, err := cmd.CombinedOutput()
if err != nil {
err = fmt.Errorf("error cloning %s to %s: %s", repo, dir, output)
}
......
......@@ -130,7 +130,7 @@ func Show(sha string) (string, error) {
cmd := cmd.New("git")
cmd.WithArg("show").WithArg("-s").WithArg("--format=%s%n%+b").WithArg(sha)
output, err := cmd.ExecOutput()
output, err := cmd.CombinedOutput()
output = strings.TrimSpace(output)
return output, err
......@@ -144,7 +144,7 @@ func Log(sha1, sha2 string) (string, error) {
shaRange := fmt.Sprintf("%s...%s", sha1, sha2)
execCmd.WithArg(shaRange)
outputs, err := execCmd.ExecOutput()
outputs, err := execCmd.CombinedOutput()
if err != nil {
return "", fmt.Errorf("Can't load git log %s..%s", sha1, sha2)
}
......@@ -191,14 +191,14 @@ func Alias(name string) (string, error) {
return Config(fmt.Sprintf("alias.%s", name))
}
func Spawn(command string, args ...string) error {
func Run(command string, args ...string) error {
cmd := cmd.New("git")
cmd.WithArg(command)
for _, a := range args {
cmd.WithArg(a)
}
return cmd.Exec()
return cmd.Run()
}
func execGitCmd(input ...string) (outputs []string, err error) {
......@@ -207,7 +207,7 @@ func execGitCmd(input ...string) (outputs []string, err error) {
cmd.WithArg(i)
}
out, err := cmd.ExecOutput()
out, err := cmd.CombinedOutput()
for _, line := range strings.Split(out, "\n") {
line = strings.TrimSpace(line)
if line != "" {
......
......@@ -118,7 +118,7 @@ func openTextEditor(program, file string) error {
}
editCmd.WithArg(file)
return editCmd.Exec()
return editCmd.Spawn()
}
func readTitleAndBody(reader io.Reader, cs string) (title, body string, err error) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册