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,41 @@ 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 := & command {cmd : exec .Command ("git" , "--exec-path" )}
40
+
41
+ // Required, to populate stdErrCloser.
42
+ _ , err := execCmd .StderrPipe ()
43
+ if err != nil {
44
+ return "" , err
45
+ }
46
+ stdout , err := execCmd .StdoutPipe ()
47
+ if err != nil {
48
+ return "" , err
49
+ }
50
+ stdoutBuf := bufio .NewReader (stdout )
51
+
52
+ err = execCmd .Start ()
53
+ if err != nil {
54
+ return "" , err
55
+ }
56
+ execPathBytes , isPrefix , err := stdoutBuf .ReadLine ()
57
+ if err != nil {
58
+ return "" , err
59
+ }
60
+ if isPrefix {
61
+ return "" , errors .New ("Couldn't read exec-path line all at once" )
62
+ }
63
+ err = execCmd .Close ()
64
+ if err != nil {
65
+ return "" , err
66
+ }
67
+ execPath := string (execPathBytes )
68
+ execPath = strings .TrimSpace (execPath )
69
+ return filepath .Join (execPath , cmd ), nil
70
+ }
71
+
33
72
func (r * runner ) Command (cmd string , ep transport.Endpoint , auth transport.AuthMethod ,
34
73
) (common.Command , error ) {
35
74
@@ -40,7 +79,17 @@ func (r *runner) Command(cmd string, ep transport.Endpoint, auth transport.AuthM
40
79
cmd = r .ReceivePackBin
41
80
}
42
81
43
- return makeCommand (cmd , ep )
82
+ _ , err := exec .LookPath (cmd )
83
+ if err != nil {
84
+ if e , ok := err .(* exec.Error ); ok && e .Err == exec .ErrNotFound {
85
+ cmd , err = prefixExecPath (cmd )
86
+ if err != nil {
87
+ return nil , err
88
+ }
89
+ }
90
+ }
91
+
92
+ return & command {cmd : exec .Command (cmd , ep .Path ())}, nil
44
93
}
45
94
46
95
type command struct {
0 commit comments