@@ -7,6 +7,7 @@ package git
77import (
88 "bytes"
99 "context"
10+ "errors"
1011 "io"
1112 "os"
1213 "strconv"
@@ -26,22 +27,20 @@ type CommandOptions struct {
2627// applied when the context does not already have a deadline.
2728const DefaultTimeout = time .Minute
2829
29- // cmd builds a *run.Command for " git" with the given arguments, environment
30- // variables and working directory. If the context does not already have a
31- // deadline, DefaultTimeout will be applied automatically .
30+ // cmd builds a *run.Command for git with the given arguments, environment
31+ // variables and working directory. DefaultTimeout will be applied if the context
32+ // does not already have a deadline .
3233func cmd (ctx context.Context , dir string , args []string , envs []string ) (* run.Command , context.CancelFunc ) {
3334 cancel := func () {}
34-
35- // Apply default timeout if the context doesn't already have a deadline.
3635 if _ , ok := ctx .Deadline (); ! ok {
3736 var timeoutCancel context.CancelFunc
3837 ctx , timeoutCancel = context .WithTimeout (ctx , DefaultTimeout )
3938 cancel = timeoutCancel
4039 }
4140
42- // run.Cmd joins all parts into a single string and then shell-parses it.
43- // We must quote each argument so that special characters (spaces, quotes,
44- // angle brackets, etc.) are preserved correctly.
41+ // run.Cmd joins all parts into a single string and then shell-parses it. We must
42+ // quote each argument so that special characters (spaces, quotes, angle
43+ // brackets, etc.) are preserved correctly.
4544 parts := make ([]string , 0 , 1 + len (args ))
4645 parts = append (parts , "git" )
4746 for _ , arg := range args {
@@ -59,9 +58,9 @@ func cmd(ctx context.Context, dir string, args []string, envs []string) (*run.Co
5958}
6059
6160// exec executes a git command in the given directory and returns stdout as
62- // bytes. Stderr is included in the error message on failure. If the command's
63- // context does not have a deadline, DefaultTimeout will be applied
64- // automatically. It returns an ErrExecTimeout if the execution was timed out.
61+ // bytes. Stderr is included in the error message on failure. DefaultTimeout will
62+ // be applied if the context does not already have a deadline. It returns
63+ // ErrExecTimeout if the execution was timed out.
6564func exec (ctx context.Context , dir string , args []string , envs []string ) ([]byte , error ) {
6665 c , cancel := cmd (ctx , dir , args , envs )
6766 defer cancel ()
@@ -71,7 +70,7 @@ func exec(ctx context.Context, dir string, args []string, envs []string) ([]byte
7170 logBuf = new (bytes.Buffer )
7271 logBuf .Grow (512 )
7372 defer func () {
74- logf (dir , args , logBuf .Bytes ())
73+ log (dir , args , logBuf .Bytes ())
7574 }()
7675 }
7776
@@ -81,8 +80,8 @@ func exec(ctx context.Context, dir string, args []string, envs []string) ([]byte
8180 stdout := new (bytes.Buffer )
8281 err := c .StdOut ().Run ().Stream (stdout )
8382
84- // Capture (partial) stdout for logging even on error, so failed commands
85- // produce a useful log entry rather than an empty one.
83+ // Capture (partial) stdout for logging even on error, so failed commands produce
84+ // a useful log entry rather than an empty one.
8685 if logOutput != nil {
8786 data := stdout .Bytes ()
8887 limit := len (data )
@@ -102,7 +101,7 @@ func exec(ctx context.Context, dir string, args []string, envs []string) ([]byte
102101}
103102
104103// pipe executes a git command in the given directory, streaming stdout to the
105- // given writer .
104+ // given io.Writer .
106105func pipe (ctx context.Context , dir string , args []string , envs []string , stdout io.Writer ) error {
107106 c , cancel := cmd (ctx , dir , args , envs )
108107 defer cancel ()
@@ -119,7 +118,7 @@ func pipe(ctx context.Context, dir string, args []string, envs []string, stdout
119118 }
120119
121120 defer func () {
122- logf (dir , args , buf .Bytes ())
121+ log (dir , args , buf .Bytes ())
123122 }()
124123 }
125124
@@ -138,8 +137,8 @@ func committerEnvs(committer *Signature) []string {
138137 }
139138}
140139
141- // logf logs a git command execution with optional output.
142- func logf (dir string , args []string , output []byte ) {
140+ // log logs a git command execution with its output.
141+ func log (dir string , args []string , output []byte ) {
143142 cmdStr := "git"
144143 if len (args ) > 0 {
145144 quoted := make ([]string , len (args ))
@@ -153,9 +152,9 @@ func logf(dir string, args []string, output []byte) {
153152 cmdStr = "git " + strings .Join (quoted , " " )
154153 }
155154 if len (dir ) == 0 {
156- log ("%s\n %s" , cmdStr , output )
155+ logf ("%s\n %s" , cmdStr , output )
157156 } else {
158- log ("%s: %s\n %s" , dir , cmdStr , output )
157+ logf ("%s: %s\n %s" , dir , cmdStr , output )
159158 }
160159}
161160
@@ -194,7 +193,7 @@ func mapContextError(err error, ctx context.Context) error {
194193 return err
195194 }
196195 if ctxErr := ctx .Err (); ctxErr != nil {
197- if ctxErr == context .DeadlineExceeded {
196+ if errors . Is ( ctxErr , context .DeadlineExceeded ) {
198197 return ErrExecTimeout
199198 }
200199 return ctxErr
@@ -205,6 +204,7 @@ func mapContextError(err error, ctx context.Context) error {
205204// isExitStatus reports whether err represents a specific process exit status
206205// code, using the run.ExitCoder interface provided by sourcegraph/run.
207206func isExitStatus (err error , code int ) bool {
208- exitCoder , ok := err .(run.ExitCoder )
207+ var exitCoder run.ExitCoder
208+ ok := errors .As (err , & exitCoder )
209209 return ok && exitCoder .ExitCode () == code
210210}
0 commit comments