diff --git a/lib/mercurial-ruby/command.rb b/lib/mercurial-ruby/command.rb index c0f1a36..6b4eac1 100644 --- a/lib/mercurial-ruby/command.rb +++ b/lib/mercurial-ruby/command.rb @@ -47,8 +47,8 @@ def execute_without_caching def execution_proc Proc.new do debug(command) - result, error = '', '' - Open3.popen3(command) do |_, stdout, stderr| + result, error, status = '', '', nil + Open3.popen3(command) do |_, stdout, stderr, wait_thr| Timeout.timeout(timeout) do while tmp = stdout.read(102400) result += tmp @@ -58,14 +58,15 @@ def execution_proc while tmp = stderr.read(1024) error += tmp end + status = wait_thr.value end - raise_error_if_needed(error) + raise_error_if_needed(error, status) result end end - def raise_error_if_needed(error) - if error && error != '' + def raise_error_if_needed(error, status = nil) + if (status.nil? || status.exitstatus != 0) && error && error != '' raise CommandError, error end end diff --git a/test/test_command.rb b/test/test_command.rb index 7036d3b..f46b0ef 100644 --- a/test/test_command.rb +++ b/test/test_command.rb @@ -16,6 +16,18 @@ Mercurial::Command.new("cd #{ @repository.path } && hg shikaka").execute }.must_raise Mercurial::CommandError end + + it "should not translate exit status of zero with shell errors to ruby exceptions" do + lambda{ + Mercurial::Command.new("echo stderr >&2 && echo stdout && exit 0").execute + }.must_equal "stdout" + end + + it "should translate exit status of non-zero with shell errors to ruby exceptions" do + lambda{ + Mercurial::Command.new("echo stderr >&2 && echo stdout && exit 1").execute + }.must_raise Mercurial::CommandError + end it "should execute commands with timeout" do Mercurial.configuration.stubs(:shell_timeout).returns(1)