@@ -396,57 +396,22 @@ def run_command(cmd, exit_on_error=true, printout_output=false)
396
396
log "Running command: #{ cmd } \n "
397
397
398
398
ret = ''
399
- @stdin_queue ||= Queue . new
400
-
401
- # We need to fetch input from the user to pass through to the underlying sub-process. We'll constantly listen
402
- # for input and place any received values on a queue for consumption by a pass-through thread that will forward
403
- # the contents to the underlying sub-process's stdin pipe.
404
- @stdin_thread ||= Thread . new do
405
- loop { @stdin_queue << $stdin. gets . chomp }
406
- end
407
-
408
399
# Open4 forks, which JRuby doesn't support. But JRuby added a popen4-compatible method on the IO class,
409
- # so we can use that instead.
410
- IO . popen ( "2>&1 #{ cmd } " ) do |output |
411
- threads = [ ]
412
-
413
- threads << Thread . new ( output ) do |output |
414
- # git-svn seems to do all of its prompting for user input via STDERR. When it prompts for input, it will
415
- # not terminate the line with a newline character, so we can't split the input up by newline. It will,
416
- # however, use a space to separate the user input from the prompt. So we split on word boundaries here
417
- # while draining STDERR.
418
- output . each ( ' ' ) do |word |
419
- ret << word
420
-
421
- if printout_output
422
- $stdout. print word
423
- else
424
- log word
425
- end
400
+ # so we can use that instead. Each command inherits the parent stdin so there's no need to manage it or close it before reading stdout.
401
+ IO . popen ( cmd , :in => 0 , :err => [ :child , :out ] ) do |output |
402
+ if printout_output || @options [ :verbose ]
403
+ # Normally, `IO.copy_stream()` would be used, but we need compatibility with interactive supprocesses.
404
+ while c = output . getc do
405
+ ret << c
406
+ putc c
407
+ STDOUT . flush # `putc`'s `STDOUT` is buffered by default, and `STDOUT.sync = true` is the wrong solution because it's a global hack.
426
408
end
409
+ else # Save output only without logging or printing to stdout.
410
+ ret = output . read
427
411
end
428
-
429
- # Simple pass-through thread to take anything the user types via STDIN and passes it through to the
430
- # sub-process's stdin pipe.
431
- Thread . new do
432
- loop do
433
- user_reply = @stdin_queue . pop
434
-
435
- # nil is our cue to stop looping (pun intended).
436
- break if user_reply . nil?
437
-
438
- stdin . puts user_reply
439
- stdin . close
440
- end
441
- end
442
-
443
- threads . each ( &:join )
444
-
445
- # Push nil to the stdin_queue to gracefully exit the STDIN pass-through thread.
446
- @stdin_queue << nil
447
412
end
448
413
449
- if exit_on_error && $?. exitstatus != 0
414
+ if exit_on_error && ! $?. success?
450
415
$stderr. puts "command failed:\n #{ cmd } "
451
416
exit -1
452
417
end
0 commit comments