2
2
package file
3
3
4
4
import (
5
+ "bufio"
6
+ "errors"
5
7
"io"
6
8
"os"
7
9
"os/exec"
10
+ "path/filepath"
11
+ "strings"
8
12
9
13
"gopkg.in/src-d/go-git.v4/plumbing/transport"
10
14
"gopkg.in/src-d/go-git.v4/plumbing/transport/internal/common"
@@ -30,6 +34,38 @@ func NewClient(uploadPackBin, receivePackBin string) transport.Transport {
30
34
})
31
35
}
32
36
37
+ func prefixExecPath (cmd string ) (string , error ) {
38
+ // Use `git --exec-path` to find the exec path.
39
+ execCmd := exec .Command ("git" , "--exec-path" )
40
+
41
+ err := execCmd .Start ()
42
+ if err != nil {
43
+ return "" , err
44
+ }
45
+
46
+ stdout , err := execCmd .StdoutPipe ()
47
+ if err != nil {
48
+ return "" , err
49
+ }
50
+ stdoutBuf := bufio .NewReader (stdout )
51
+
52
+ execPathBytes , isPrefix , err := stdoutBuf .ReadLine ()
53
+ if err != nil {
54
+ return "" , err
55
+ }
56
+ if isPrefix {
57
+ return "" , errors .New ("Couldn't read exec-path line all at once" )
58
+ }
59
+
60
+ err = execCmd .Wait ()
61
+ if err != nil {
62
+ return "" , err
63
+ }
64
+ execPath := string (execPathBytes )
65
+ execPath = strings .TrimSpace (execPath )
66
+ return filepath .Join (execPath , cmd ), nil
67
+ }
68
+
33
69
func (r * runner ) Command (cmd string , ep transport.Endpoint , auth transport.AuthMethod ,
34
70
) (common.Command , error ) {
35
71
@@ -40,7 +76,17 @@ func (r *runner) Command(cmd string, ep transport.Endpoint, auth transport.AuthM
40
76
cmd = r .ReceivePackBin
41
77
}
42
78
43
- return makeCommand (cmd , ep )
79
+ _ , err := exec .LookPath (cmd )
80
+ if err != nil {
81
+ if e , ok := err .(* exec.Error ); ok && e .Err == exec .ErrNotFound {
82
+ cmd , err = prefixExecPath (cmd )
83
+ if err != nil {
84
+ return nil , err
85
+ }
86
+ }
87
+ }
88
+
89
+ return & command {cmd : exec .Command (cmd , ep .Path ())}, nil
44
90
}
45
91
46
92
type command struct {
0 commit comments