aboutsummaryrefslogtreecommitdiffstats
path: root/plumbing/transport/file
diff options
context:
space:
mode:
Diffstat (limited to 'plumbing/transport/file')
-rw-r--r--plumbing/transport/file/client.go55
-rw-r--r--plumbing/transport/file/client_test.go22
-rw-r--r--plumbing/transport/file/server_test.go15
3 files changed, 90 insertions, 2 deletions
diff --git a/plumbing/transport/file/client.go b/plumbing/transport/file/client.go
index 0b42abf..d229fdd 100644
--- a/plumbing/transport/file/client.go
+++ b/plumbing/transport/file/client.go
@@ -2,9 +2,13 @@
package file
import (
+ "bufio"
+ "errors"
"io"
"os"
"os/exec"
+ "path/filepath"
+ "strings"
"gopkg.in/src-d/go-git.v4/plumbing/transport"
"gopkg.in/src-d/go-git.v4/plumbing/transport/internal/common"
@@ -30,6 +34,45 @@ func NewClient(uploadPackBin, receivePackBin string) transport.Transport {
})
}
+func prefixExecPath(cmd string) (string, error) {
+ // Use `git --exec-path` to find the exec path.
+ execCmd := exec.Command("git", "--exec-path")
+
+ stdout, err := execCmd.StdoutPipe()
+ if err != nil {
+ return "", err
+ }
+ stdoutBuf := bufio.NewReader(stdout)
+
+ err = execCmd.Start()
+ if err != nil {
+ return "", err
+ }
+
+ execPathBytes, isPrefix, err := stdoutBuf.ReadLine()
+ if err != nil {
+ return "", err
+ }
+ if isPrefix {
+ return "", errors.New("Couldn't read exec-path line all at once")
+ }
+
+ err = execCmd.Wait()
+ if err != nil {
+ return "", err
+ }
+ execPath := string(execPathBytes)
+ execPath = strings.TrimSpace(execPath)
+ cmd = filepath.Join(execPath, cmd)
+
+ // Make sure it actually exists.
+ _, err = exec.LookPath(cmd)
+ if err != nil {
+ return "", err
+ }
+ return cmd, nil
+}
+
func (r *runner) Command(cmd string, ep transport.Endpoint, auth transport.AuthMethod,
) (common.Command, error) {
@@ -40,8 +83,16 @@ func (r *runner) Command(cmd string, ep transport.Endpoint, auth transport.AuthM
cmd = r.ReceivePackBin
}
- if _, err := exec.LookPath(cmd); err != nil {
- return nil, err
+ _, 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
+ }
+ } else {
+ return nil, err
+ }
}
return &command{cmd: exec.Command(cmd, ep.Path())}, nil
diff --git a/plumbing/transport/file/client_test.go b/plumbing/transport/file/client_test.go
index 030175e..864cddc 100644
--- a/plumbing/transport/file/client_test.go
+++ b/plumbing/transport/file/client_test.go
@@ -14,6 +14,28 @@ import (
func Test(t *testing.T) { TestingT(t) }
+type ClientSuite struct {
+ CommonSuite
+}
+
+var _ = Suite(&ClientSuite{})
+
+func (s *ClientSuite) TestCommand(c *C) {
+ runner := &runner{
+ UploadPackBin: transport.UploadPackServiceName,
+ ReceivePackBin: transport.ReceivePackServiceName,
+ }
+ ep, err := transport.NewEndpoint(filepath.Join("fake", "repo"))
+ c.Assert(err, IsNil)
+ var emptyAuth transport.AuthMethod
+ _, err = runner.Command("git-receive-pack", ep, emptyAuth)
+ c.Assert(err, IsNil)
+
+ // Make sure we get an error for one that doesn't exist.
+ _, err = runner.Command("git-fake-command", ep, emptyAuth)
+ c.Assert(err, NotNil)
+}
+
const bareConfig = `[core]
repositoryformatversion = 0
filemode = true
diff --git a/plumbing/transport/file/server_test.go b/plumbing/transport/file/server_test.go
index ee72282..080beef 100644
--- a/plumbing/transport/file/server_test.go
+++ b/plumbing/transport/file/server_test.go
@@ -35,6 +35,10 @@ func (s *ServerSuite) SetUpSuite(c *C) {
}
func (s *ServerSuite) TestPush(c *C) {
+ if !s.checkExecPerm(c) {
+ c.Skip("go-git binary has not execution permissions")
+ }
+
// git <2.0 cannot push to an empty repository without a refspec.
cmd := exec.Command("git", "push",
"--receive-pack", s.ReceivePackBin,
@@ -48,6 +52,10 @@ func (s *ServerSuite) TestPush(c *C) {
}
func (s *ServerSuite) TestClone(c *C) {
+ if !s.checkExecPerm(c) {
+ c.Skip("go-git binary has not execution permissions")
+ }
+
pathToClone := c.MkDir()
cmd := exec.Command("git", "clone",
@@ -59,3 +67,10 @@ func (s *ServerSuite) TestClone(c *C) {
out, err := cmd.CombinedOutput()
c.Assert(err, IsNil, Commentf("combined stdout and stderr:\n%s\n", out))
}
+
+func (s *ServerSuite) checkExecPerm(c *C) bool {
+ const userExecPermMask = 0100
+ info, err := os.Stat(s.ReceivePackBin)
+ c.Assert(err, IsNil)
+ return (info.Mode().Perm() & userExecPermMask) == userExecPermMask
+}