From 3af2b9d8712777f094df40cbc483731e7aa64ee1 Mon Sep 17 00:00:00 2001 From: Jeremy Stribling Date: Wed, 2 Aug 2017 14:52:46 -0700 Subject: [PATCH] plumbing: use --exec-path to find pack executables Suggested by smola. Issue: #527 --- plumbing/transport/file/client.go | 35 ++++++++++++++++++- plumbing/transport/file/client_cmd_unix.go | 18 ---------- plumbing/transport/file/client_cmd_windows.go | 29 --------------- 3 files changed, 34 insertions(+), 48 deletions(-) delete mode 100644 plumbing/transport/file/client_cmd_unix.go delete mode 100644 plumbing/transport/file/client_cmd_windows.go diff --git a/plumbing/transport/file/client.go b/plumbing/transport/file/client.go index 3d058aa0c..3082110fd 100644 --- a/plumbing/transport/file/client.go +++ b/plumbing/transport/file/client.go @@ -30,6 +30,29 @@ func NewClient(uploadPackBin, receivePackBin string) transport.Transport { }) } +func prefixExecPath(cmd string) (string, error) { + // Use `git --exec-path` to find the exec path. + execCmd := &command{cmd: exec.Command("git", "--exec-path")} + err = execCmd.Start() + if err != nil { + return "", err + } + err = execCmd.Close() + if err != nil { + return "", err + } + stdout, err := execCmd.StdoutPipe() + if err != nil { + return "", err + } + execPath, err := ioutil.ReadAll(stdout) + if err != nil { + return "", err + } + execPath = strings.TrimSpace(execPath) + return filepath.Join(execPath, cmd), nil +} + func (r *runner) Command(cmd string, ep transport.Endpoint, auth transport.AuthMethod, ) (common.Command, error) { @@ -40,7 +63,17 @@ func (r *runner) Command(cmd string, ep transport.Endpoint, auth transport.AuthM cmd = r.ReceivePackBin } - return makeCommand(cmd, ep) + _, err := exec.LookPath(cmd) + if err != nil { + if e, ok := err.(*exec.Error); ok && e.Err == exec.ErrNotFound { + cmd, err = prefixExecPath(cmd) + if err != nil { + return nil, err + } + } + } + + return &command{cmd: exec.Command(cmd, ep.Path())}, nil } type command struct { diff --git a/plumbing/transport/file/client_cmd_unix.go b/plumbing/transport/file/client_cmd_unix.go deleted file mode 100644 index abe3e9ffd..000000000 --- a/plumbing/transport/file/client_cmd_unix.go +++ /dev/null @@ -1,18 +0,0 @@ -// +build !windows - -package file - -import ( - "os/exec" - - "gopkg.in/src-d/go-git.v4/plumbing/transport" - "gopkg.in/src-d/go-git.v4/plumbing/transport/internal/common" -) - -func makeCommand(cmd string, ep transport.Endpoint) (common.Command, error) { - if _, err := exec.LookPath(cmd); err != nil { - return nil, err - } - - return &command{cmd: exec.Command(cmd, ep.Path())}, nil -} diff --git a/plumbing/transport/file/client_cmd_windows.go b/plumbing/transport/file/client_cmd_windows.go deleted file mode 100644 index b58bbb2da..000000000 --- a/plumbing/transport/file/client_cmd_windows.go +++ /dev/null @@ -1,29 +0,0 @@ -// +build windows - -package file - -import ( - "os/exec" - "strings" - - "gopkg.in/src-d/go-git.v4/plumbing/transport" - "gopkg.in/src-d/go-git.v4/plumbing/transport/internal/common" -) - -// In the default Windows git install, there is no separate -// git-upload-pack or git-receive-pack binaries; we must use "git -// upload-pack" and "git receive-pack" instead. -func makeCommand(cmd string, ep transport.Endpoint) (common.Command, error) { - var subcommands []string - if strings.HasPrefix(cmd, "git-") { - subcommands = strings.SplitN(cmd, "-", 2) - cmd = subcommands[0] - } - - if _, err := exec.LookPath(cmd); err != nil { - return nil, err - } - - return &command{cmd: exec.Command( - cmd, append(subcommands[1:], ep.Path())...)}, nil -}