lib/backticks/runner.rb in backticks-0.1.1 vs lib/backticks/runner.rb in backticks-0.3.0

- old
+ new

@@ -31,14 +31,14 @@ # @return [#parameters] the CLI-translation object used by this runner attr_reader :cli # Create an instance of Runner. # @param [#parameters] cli object used to convert Ruby method parameters into command-line parameters - def initialize(cli:Backticks::CLI::Getopt) - @interactive = false - @buffered = false + def initialize(buffered:false, cli:Backticks::CLI::Getopt, interactive:false) + @buffered = buffered @cli = cli + @interactive = interactive end # Run a command whose parameters are expressed using some Rubyish sugar. # This method accepts an arbitrary number of positional parameters; each # parameter can be a Hash, an array, or a simple Object. Arrays and simple @@ -54,35 +54,40 @@ # # @return [Command] the running command # # @example Run docker-compose with complex parameters # command('docker-compose', {file: 'joe.yml'}, 'up', {d:true}, 'mysvc') - def command(*args) + def run(*args) argv = @cli.parameters(*args) - if self.buffered run_buffered(argv) else run_unbuffered(argv) end end + alias command run + # Run a command. Use a pty to capture the unbuffered output. # # @param [Array] argv command to run; argv[0] is program name and the # remaining elements are parameters and flags # @return [Command] the running command private def run_unbuffered(argv) stdout, stdout_w = PTY.open - stdin_r, stdin = IO.pipe - stderr, stderr_w = IO.pipe + stdin_r, stdin = PTY.open + stderr, stderr_w = PTY.open pid = spawn(*argv, in: stdin_r, out: stdout_w, err: stderr_w) stdin_r.close stdout_w.close stderr_w.close + unless @interactive + stdin.close + stdin = nil + end - Command.new(pid, stdin, stdout, stderr, interactive:@interactive) + Command.new(pid, stdin, stdout, stderr) end # Run a command. Perform no translation or substitution. Use a pipe # to read the output, which may be buffered by the OS. Return the program's # exit status and stdout. @@ -90,10 +95,14 @@ # @param [Array] argv command to run; argv[0] is program name and the # remaining elements are command-line arguments. # @return [Command] the running command private def run_buffered(argv) stdin, stdout, stderr, thr = Open3.popen3(*argv) + unless @interactive + stdin.close + stdin = nil + end - Command.new(thr.pid, stdin, stdout, stderr, interactive:@interactive) + Command.new(thr.pid, stdin, stdout, stderr) end end -end \ No newline at end of file +end