|
30 | 30 | package utils
|
31 | 31 |
|
32 | 32 | import (
|
33 |
| - "bufio" |
34 | 33 | "bytes"
|
35 | 34 | "crypto/md5"
|
36 | 35 | "encoding/hex"
|
@@ -282,72 +281,53 @@ func PrintableCommand(parts []string) string {
|
282 | 281 |
|
283 | 282 | const (
|
284 | 283 | Ignore = 0 // Redirect to null
|
285 |
| - Show = 1 // Show on stdout/stderr as normal |
286 |
| - ShowIfVerbose = 2 // Show if verbose is set, Ignore otherwise |
287 |
| - Capture = 3 // Capture into buffer |
| 284 | + Show = 1 // Print the stream |
| 285 | + ShowIfVerbose = 2 // Print the stream only if verbose |
| 286 | + Capture = 3 // Capture into buffer and don't print |
| 287 | + Stream = 4 // Stream data as it comes in, no capture |
288 | 288 | )
|
289 | 289 |
|
290 | 290 | func ExecCommand(ctx *types.Context, command *exec.Cmd, stdout int, stderr int) ([]byte, []byte, error) {
|
291 | 291 | if ctx.Verbose {
|
292 | 292 | ctx.GetLogger().UnformattedFprintln(os.Stdout, PrintableCommand(command.Args))
|
293 | 293 | }
|
294 | 294 |
|
295 |
| - var stdoutCopy io.ReadCloser |
296 |
| - var stderrCopy io.ReadCloser |
297 |
| - |
298 |
| - if stdout == Capture { |
| 295 | + if stdout != Stream { |
299 | 296 | buffer := &bytes.Buffer{}
|
300 | 297 | command.Stdout = buffer
|
301 |
| - } else if stdout == Show || stdout == ShowIfVerbose && ctx.Verbose { |
302 |
| - stdoutCopy, _ = command.StdoutPipe() |
| 298 | + } else { |
| 299 | + command.Stdout = os.Stdout |
303 | 300 | }
|
304 | 301 |
|
305 |
| - if stderr == Capture { |
| 302 | + if stderr != Stream { |
306 | 303 | buffer := &bytes.Buffer{}
|
307 | 304 | command.Stderr = buffer
|
308 |
| - } else if stderr == Show || stderr == ShowIfVerbose && ctx.Verbose { |
309 |
| - stderrCopy, _ = command.StderrPipe() |
| 305 | + } else { |
| 306 | + command.Stderr = os.Stderr |
310 | 307 | }
|
311 | 308 |
|
312 | 309 | err := command.Start()
|
313 | 310 | if err != nil {
|
314 | 311 | return nil, nil, i18n.WrapError(err)
|
315 | 312 | }
|
316 | 313 |
|
317 |
| - var outbytes, errbytes []byte |
318 |
| - |
319 |
| - if stdoutCopy != nil && stderrCopy != nil { |
320 |
| - stdOut := bufio.NewScanner(stdoutCopy) |
321 |
| - stdErr := bufio.NewScanner(stderrCopy) |
322 |
| - stdOut.Split(bufio.ScanLines) |
323 |
| - stdErr.Split(bufio.ScanLines) |
324 |
| - |
325 |
| - go func() { |
326 |
| - for stdOut.Scan() { |
327 |
| - txt := stdOut.Text() + "\n" |
328 |
| - fmt.Fprint(os.Stderr, txt) |
329 |
| - outbytes = append(outbytes, txt...) |
330 |
| - } |
331 |
| - }() |
| 314 | + err = command.Wait() |
332 | 315 |
|
333 |
| - go func() { |
334 |
| - for stdErr.Scan() { |
335 |
| - txt := stdErr.Text() + "\n" |
336 |
| - fmt.Fprint(os.Stderr, txt) |
337 |
| - errbytes = append(errbytes, txt...) |
338 |
| - } |
339 |
| - }() |
| 316 | + var outbytes, errbytes []byte |
| 317 | + // this operation is a no-op in case of streaming |
| 318 | + if buf, ok := command.Stdout.(*bytes.Buffer); ok { |
| 319 | + outbytes = buf.Bytes() |
| 320 | + } |
| 321 | + if buf, ok := command.Stderr.(*bytes.Buffer); ok { |
| 322 | + errbytes = buf.Bytes() |
340 | 323 | }
|
341 | 324 |
|
342 |
| - err = command.Wait() |
| 325 | + if stdout == Show || (stdout == ShowIfVerbose && ctx.Verbose) { |
| 326 | + ctx.GetLogger().UnformattedWrite(os.Stdout, outbytes) |
| 327 | + } |
343 | 328 |
|
344 |
| - if stdoutCopy == nil || stderrCopy == nil { |
345 |
| - if buf, ok := command.Stdout.(*bytes.Buffer); ok { |
346 |
| - outbytes = buf.Bytes() |
347 |
| - } |
348 |
| - if buf, ok := command.Stderr.(*bytes.Buffer); ok { |
349 |
| - errbytes = buf.Bytes() |
350 |
| - } |
| 329 | + if stderr == Show || (stderr == ShowIfVerbose && ctx.Verbose) { |
| 330 | + ctx.GetLogger().UnformattedWrite(os.Stderr, errbytes) |
351 | 331 | }
|
352 | 332 |
|
353 | 333 | return outbytes, errbytes, i18n.WrapError(err)
|
|
0 commit comments