From 77deb17e04eb56cdda4ad6c02ed5757d1290e089 Mon Sep 17 00:00:00 2001 From: Mike Mangino Date: Tue, 6 Feb 2018 20:41:16 +0000 Subject: [PATCH 1/8] move code from cocaine --- lib/terrapin/command_line/multi_pipe.rb | 42 ++++++++++++++++++++++--- spec/support/nonblocking_examples.rb | 13 ++++++++ 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/lib/terrapin/command_line/multi_pipe.rb b/lib/terrapin/command_line/multi_pipe.rb index 87c76ef..166de50 100644 --- a/lib/terrapin/command_line/multi_pipe.rb +++ b/lib/terrapin/command_line/multi_pipe.rb @@ -29,19 +29,51 @@ def close_write end def read - @stdout_output = read_stream(@stdout_in) - @stderr_output = read_stream(@stderr_in) + read_streams(@stdout_in, @stderr_in) end def close_read - @stdout_in.close + begin + @stdout_in.close + rescue IOError + # do nothing + end + + begin @stderr_in.close + rescue IOError + # do nothing + end + end + + def read_streams(output, error) + @stdout_output = "" + @stderr_output = "" + read_fds = [output, error] + while !read_fds.empty? + to_read, = IO.select(read_fds) + if to_read.include?(output) + @stdout_output << read_stream(output) + read_fds.delete(output) if output.closed? + end + + if to_read.include?(error) + @stderr_output << read_stream(error) + read_fds.delete(error) if error.closed? + end + end end def read_stream(io) result = "" - while partial_result = io.read(8192) - result << partial_result + begin + while partial_result = io.read_nonblock(8192) + result << partial_result + end + rescue EOFError, Errno::EPIPE + io.close + rescue Errno::EINTR, Errno::EWOULDBLOCK, Errno::EAGAIN + # do nothing end result end diff --git a/spec/support/nonblocking_examples.rb b/spec/support/nonblocking_examples.rb index 73a32e1..b246ae2 100644 --- a/spec/support/nonblocking_examples.rb +++ b/spec/support/nonblocking_examples.rb @@ -1,4 +1,17 @@ shared_examples_for "a command that does not block" do + it "does not block if the command output a lot on stderr" do + cmd = Terrapin::CommandLine.new( + "ruby", + "-e '$stdout.puts %{hello}; $stderr.puts %{goodbye}*10_000'", + :swallow_stderr => false + ) + Timeout.timeout(5) do + cmd.run + end + expect(cmd.command_output).to eq "hello\n" + expect(cmd.command_error_output).to eq "#{"goodbye" * 10_000}\n" + end + it 'does not block if the command outputs a lot of data' do garbage_file = Tempfile.new("garbage") 10.times{ garbage_file.write("A" * 1024 * 1024) } From c3956cf73d408ec42db06c304665d0dfe963141e Mon Sep 17 00:00:00 2001 From: Brian Kung <2836167+briankung@users.noreply.github.com> Date: Fri, 6 Sep 2019 14:49:43 -0500 Subject: [PATCH 2/8] Insert an inspect on the exit status For https://github.com/thoughtbot/terrapin/issues/12. This would be helpful to confirm that we are getting a `nil` exit status. Thanks! --- lib/terrapin/command_line.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/terrapin/command_line.rb b/lib/terrapin/command_line.rb index 5626afd..e24bcf9 100644 --- a/lib/terrapin/command_line.rb +++ b/lib/terrapin/command_line.rb @@ -89,7 +89,7 @@ def run(interpolations = {}) unless @expected_outcodes.include?(@exit_status) message = [ - "Command '#{full_command}' returned #{@exit_status}. Expected #{@expected_outcodes.join(", ")}", + "Command '#{full_command}' returned #{@exit_status.inspect}. Expected #{@expected_outcodes.join(", ")}", "Here is the command output: STDOUT:\n", command_output, "\nSTDERR:\n", command_error_output ].join("\n") From f9febf9a925f2c0aa263ea7e00f8ca6b41a407b5 Mon Sep 17 00:00:00 2001 From: Leif Gensert Date: Fri, 14 Feb 2025 09:54:26 -0800 Subject: [PATCH 3/8] remove space --- .github/workflows/dynamic-readme.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dynamic-readme.yml b/.github/workflows/dynamic-readme.yml index 41bb5db..f880407 100644 --- a/.github/workflows/dynamic-readme.yml +++ b/.github/workflows/dynamic-readme.yml @@ -1,6 +1,6 @@ name: update-templates -on: +on: push: branches: - main From 08175961cb3cd107b13ee328d2b7796e9745a25e Mon Sep 17 00:00:00 2001 From: Leif Gensert Date: Wed, 19 Feb 2025 17:31:24 -0800 Subject: [PATCH 4/8] use current version of JRuby --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc3d3fb..d0ef3ff 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ jobs: fail-fast: false matrix: ruby: - - jruby-9.4.1.0 + - jruby-9.4.12.0 - "2.7" - "3.0" - "3.1" From 8a6ae579e81c26717a8bbef35ea6ac593230df7f Mon Sep 17 00:00:00 2001 From: Leif Gensert Date: Wed, 19 Feb 2025 17:33:42 -0800 Subject: [PATCH 5/8] add newer ruby version --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d0ef3ff..fcebefa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,6 +16,8 @@ jobs: - "3.0" - "3.1" - "3.2" + - "3.3" + - "3.4" runs-on: 'ubuntu-latest' From f2963d623e08ecc6e5b5a6aebcfeeb5066f3f157 Mon Sep 17 00:00:00 2001 From: Leif Gensert Date: Wed, 19 Feb 2025 17:33:54 -0800 Subject: [PATCH 6/8] upgrade checkout action --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fcebefa..13e2e05 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: runs-on: 'ubuntu-latest' steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} From 86b39e822b5199b5d30ad3d351c7f714767698a6 Mon Sep 17 00:00:00 2001 From: Leif Gensert Date: Fri, 21 Feb 2025 09:36:31 -0800 Subject: [PATCH 7/8] implement stderr test correctly --- spec/support/nonblocking_examples.rb | 20 +++++++++---------- .../runners/backticks_runner_spec.rb | 2 +- .../command_line/runners/popen_runner_spec.rb | 2 +- .../runners/process_runner_spec.rb | 2 +- 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/spec/support/nonblocking_examples.rb b/spec/support/nonblocking_examples.rb index 4d1996b..46eb33b 100644 --- a/spec/support/nonblocking_examples.rb +++ b/spec/support/nonblocking_examples.rb @@ -1,15 +1,13 @@ -shared_examples_for "a command that does not block" do - it "does not block if the command output a lot on stderr" do - cmd = Terrapin::CommandLine.new( - "ruby", - "-e '$stdout.puts %{hello}; $stderr.puts %{goodbye}*10_000'", - :swallow_stderr => false - ) - Timeout.timeout(5) do - cmd.run +shared_examples_for "a command that does not block" do |opts = {}| + if opts[:supports_stderr] + it "does not block if the command output a lot on stderr" do + Timeout.timeout(5) do + output = subject.call("ruby -e '$stdout.puts %{hello}; $stderr.puts %{goodbye}*10_000'") + + expect(output.output).to eq "hello\n" + expect(output.error_output).to eq "#{"goodbye" * 10_000}\n" + end end - expect(cmd.command_output).to eq "hello\n" - expect(cmd.command_error_output).to eq "#{"goodbye" * 10_000}\n" end it 'does not block if the command outputs a lot of data' do diff --git a/spec/terrapin/command_line/runners/backticks_runner_spec.rb b/spec/terrapin/command_line/runners/backticks_runner_spec.rb index dea9a25..def79ab 100644 --- a/spec/terrapin/command_line/runners/backticks_runner_spec.rb +++ b/spec/terrapin/command_line/runners/backticks_runner_spec.rb @@ -2,7 +2,7 @@ describe Terrapin::CommandLine::BackticksRunner do if Terrapin::CommandLine::BackticksRunner.supported? - it_behaves_like 'a command that does not block' + it_behaves_like 'a command that does not block', :supports_stderr => false it 'runs the command given and captures the output in an Output' do output = subject.call("echo hello") diff --git a/spec/terrapin/command_line/runners/popen_runner_spec.rb b/spec/terrapin/command_line/runners/popen_runner_spec.rb index 8e5d993..fabd2b7 100644 --- a/spec/terrapin/command_line/runners/popen_runner_spec.rb +++ b/spec/terrapin/command_line/runners/popen_runner_spec.rb @@ -2,7 +2,7 @@ describe Terrapin::CommandLine::PopenRunner do if Terrapin::CommandLine::PopenRunner.supported? - it_behaves_like 'a command that does not block' + it_behaves_like 'a command that does not block', :supports_stderr => false it 'runs the command given and captures the output in an Output' do output = subject.call("echo hello") diff --git a/spec/terrapin/command_line/runners/process_runner_spec.rb b/spec/terrapin/command_line/runners/process_runner_spec.rb index 91dfa0e..02945f9 100644 --- a/spec/terrapin/command_line/runners/process_runner_spec.rb +++ b/spec/terrapin/command_line/runners/process_runner_spec.rb @@ -2,7 +2,7 @@ describe Terrapin::CommandLine::ProcessRunner do if Terrapin::CommandLine::ProcessRunner.supported? - it_behaves_like "a command that does not block" + it_behaves_like "a command that does not block", { :supports_stderr => true } it 'runs the command given and captures the output' do output = subject.call("echo hello") From c343bb712e0400d747fd16556e488a743bab5869 Mon Sep 17 00:00:00 2001 From: Leif Gensert Date: Fri, 28 Feb 2025 08:35:20 -0800 Subject: [PATCH 8/8] make options consistent --- spec/terrapin/command_line/runners/backticks_runner_spec.rb | 2 +- spec/terrapin/command_line/runners/popen_runner_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/terrapin/command_line/runners/backticks_runner_spec.rb b/spec/terrapin/command_line/runners/backticks_runner_spec.rb index def79ab..cced409 100644 --- a/spec/terrapin/command_line/runners/backticks_runner_spec.rb +++ b/spec/terrapin/command_line/runners/backticks_runner_spec.rb @@ -2,7 +2,7 @@ describe Terrapin::CommandLine::BackticksRunner do if Terrapin::CommandLine::BackticksRunner.supported? - it_behaves_like 'a command that does not block', :supports_stderr => false + it_behaves_like 'a command that does not block', { :supports_stderr => false } it 'runs the command given and captures the output in an Output' do output = subject.call("echo hello") diff --git a/spec/terrapin/command_line/runners/popen_runner_spec.rb b/spec/terrapin/command_line/runners/popen_runner_spec.rb index fabd2b7..0b5ebec 100644 --- a/spec/terrapin/command_line/runners/popen_runner_spec.rb +++ b/spec/terrapin/command_line/runners/popen_runner_spec.rb @@ -2,7 +2,7 @@ describe Terrapin::CommandLine::PopenRunner do if Terrapin::CommandLine::PopenRunner.supported? - it_behaves_like 'a command that does not block', :supports_stderr => false + it_behaves_like 'a command that does not block', { :supports_stderr => false } it 'runs the command given and captures the output in an Output' do output = subject.call("echo hello")