diff --git a/.travis.yml b/.travis.yml index e36cde7..b687a85 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,8 @@ rvm: - - 1.9.2 - 1.9.3 - 2.0.0 + - jruby-19mode matrix: allow_failures: - - rvm: jruby-19mode - rvm: rbx-19mode diff --git a/lib/cocaine/command_line.rb b/lib/cocaine/command_line.rb index d4f3d0a..f8e8af5 100644 --- a/lib/cocaine/command_line.rb +++ b/lib/cocaine/command_line.rb @@ -15,15 +15,6 @@ def path=(supplemental_path) @supplemental_environment['PATH'] = (Array(supplemental_path) + [ENV['PATH']]).join(File::PATH_SEPARATOR) end - def posix_spawn_available? - @posix_spawn_available ||= begin - require 'posix/spawn' - true - rescue LoadError => e - false - end - end - def environment @supplemental_environment ||= {} end @@ -40,12 +31,16 @@ def unfake! @runner = nil end + def java? + RUBY_PLATFORM =~ /java/ + end + private def best_runner - return PosixRunner.new if posix_spawn_available? - return ProcessRunner.new if Process.respond_to?(:spawn) - BackticksRunner.new + [PosixRunner, ProcessRunner, BackticksRunner].detect do |runner| + runner.supported? + end.new end end diff --git a/lib/cocaine/command_line/runners/backticks_runner.rb b/lib/cocaine/command_line/runners/backticks_runner.rb index ea7ee79..fa4f12f 100644 --- a/lib/cocaine/command_line/runners/backticks_runner.rb +++ b/lib/cocaine/command_line/runners/backticks_runner.rb @@ -5,6 +5,13 @@ module Cocaine class CommandLine class BackticksRunner + def self.supported? + true + end + + def supported? + self.class.supported? + end def call(command, env = {}) with_modified_environment(env) do diff --git a/lib/cocaine/command_line/runners/fake_runner.rb b/lib/cocaine/command_line/runners/fake_runner.rb index 537c692..02f6b14 100644 --- a/lib/cocaine/command_line/runners/fake_runner.rb +++ b/lib/cocaine/command_line/runners/fake_runner.rb @@ -3,6 +3,13 @@ module Cocaine class CommandLine class FakeRunner + def self.supported? + false + end + + def supported? + self.class.supported? + end attr_reader :commands diff --git a/lib/cocaine/command_line/runners/popen_runner.rb b/lib/cocaine/command_line/runners/popen_runner.rb index d75b282..8e6e506 100644 --- a/lib/cocaine/command_line/runners/popen_runner.rb +++ b/lib/cocaine/command_line/runners/popen_runner.rb @@ -3,6 +3,14 @@ module Cocaine class CommandLine class PopenRunner + def self.supported? + true + end + + def supported? + self.class.supported? + end + def call(command, env = {}) with_modified_environment(env) do IO.popen(command, "r") do |pipe| diff --git a/lib/cocaine/command_line/runners/posix_runner.rb b/lib/cocaine/command_line/runners/posix_runner.rb index 55e453b..fea7e1d 100644 --- a/lib/cocaine/command_line/runners/posix_runner.rb +++ b/lib/cocaine/command_line/runners/posix_runner.rb @@ -3,31 +3,45 @@ module Cocaine class CommandLine class PosixRunner - if Cocaine::CommandLine.posix_spawn_available? - - def call(command, env = {}) - input, output = IO.pipe - pid = spawn(env, command, :out => output) - output.close - result = "" - while partial_result = input.read(8192) - result << partial_result - end - waitpid(pid) - result + def self.available? + begin + require 'posix/spawn' + true + rescue LoadError => e + false end + end - private + def self.supported? + available? && !Cocaine::CommandLine.java? + end - def spawn(*args) - POSIX::Spawn.spawn(*args) - end + def supported? + self.class.supported? + end - def waitpid(pid) - Process.waitpid(pid) + def call(command, env = {}) + input, output = IO.pipe + pid = spawn(env, command, :out => output) + output.close + result = "" + while partial_result = input.read(8192) + result << partial_result end + waitpid(pid) + result + end + private + + def spawn(*args) + POSIX::Spawn.spawn(*args) + end + + def waitpid(pid) + Process.waitpid(pid) end + end end end diff --git a/lib/cocaine/command_line/runners/process_runner.rb b/lib/cocaine/command_line/runners/process_runner.rb index 899c8ed..163e2e1 100644 --- a/lib/cocaine/command_line/runners/process_runner.rb +++ b/lib/cocaine/command_line/runners/process_runner.rb @@ -3,33 +3,41 @@ module Cocaine class CommandLine class ProcessRunner - if Process.respond_to?(:spawn) - - def call(command, env = {}) - input, output = IO.pipe - pid = spawn(env, command, :out => output) - output.close - result = input.read - waitpid(pid) - result - end + def self.available? + Process.respond_to?(:spawn) + end - private + def self.supported? + available? && !Cocaine::CommandLine.java? + end - def spawn(*args) - Process.spawn(*args) - end + def supported? + self.class.supported? + end - def waitpid(pid) - begin - Process.waitpid(pid) - rescue Errno::ECHILD => e - # In JRuby, waiting on a finished pid raises. - end - end + def call(command, env = {}) + input, output = IO.pipe + pid = spawn(env, command, :out => output) + output.close + result = input.read + waitpid(pid) + result + end + private + + def spawn(*args) + Process.spawn(*args) + end + + def waitpid(pid) + begin + Process.waitpid(pid) + rescue Errno::ECHILD => e + # In JRuby, waiting on a finished pid raises. + end end + end end end - diff --git a/lib/cocaine/exceptions.rb b/lib/cocaine/exceptions.rb index 943c9e3..8824171 100644 --- a/lib/cocaine/exceptions.rb +++ b/lib/cocaine/exceptions.rb @@ -1,8 +1,8 @@ # coding: UTF-8 module Cocaine - class CommandLineError < StandardError; end + class CommandLineError < StandardError; end class CommandNotFoundError < CommandLineError; end - class ExitStatusError < CommandLineError; end - class InterpolationError < CommandLineError; end + class ExitStatusError < CommandLineError; end + class InterpolationError < CommandLineError; end end diff --git a/spec/cocaine/command_line/runners/backticks_runner_spec.rb b/spec/cocaine/command_line/runners/backticks_runner_spec.rb index b665585..0e9ca43 100644 --- a/spec/cocaine/command_line/runners/backticks_runner_spec.rb +++ b/spec/cocaine/command_line/runners/backticks_runner_spec.rb @@ -1,20 +1,22 @@ require 'spec_helper' describe Cocaine::CommandLine::BackticksRunner do - it_behaves_like 'a command that does not block' + if Cocaine::CommandLine::BackticksRunner.supported? + it_behaves_like 'a command that does not block' - it 'runs the command given' do - subject.call("echo hello").should == "hello\n" - end + it 'runs the command given' do + subject.call("echo hello").should == "hello\n" + end - it 'modifies the environment and runs the command given' do - subject.call("echo $yes", {"yes" => "no"}).should == "no\n" - end + it 'modifies the environment and runs the command given' do + subject.call("echo $yes", {"yes" => "no"}).should == "no\n" + end - it 'sets the exitstatus when a command completes' do - subject.call("ruby -e 'exit 0'") - $?.exitstatus.should == 0 - subject.call("ruby -e 'exit 5'") - $?.exitstatus.should == 5 + it 'sets the exitstatus when a command completes' do + subject.call("ruby -e 'exit 0'") + $?.exitstatus.should == 0 + subject.call("ruby -e 'exit 5'") + $?.exitstatus.should == 5 + end end end diff --git a/spec/cocaine/command_line/runners/popen_runner_spec.rb b/spec/cocaine/command_line/runners/popen_runner_spec.rb index 28323e5..cc8a543 100644 --- a/spec/cocaine/command_line/runners/popen_runner_spec.rb +++ b/spec/cocaine/command_line/runners/popen_runner_spec.rb @@ -1,21 +1,22 @@ require 'spec_helper' describe Cocaine::CommandLine::PopenRunner do - it_behaves_like 'a command that does not block' + if Cocaine::CommandLine::PopenRunner.supported? + it_behaves_like 'a command that does not block' - it 'runs the command given' do - subject.call("echo hello").should == "hello\n" - end + it 'runs the command given' do + subject.call("echo hello").should == "hello\n" + end - it 'modifies the environment and runs the command given' do - subject.call("echo $yes", {"yes" => "no"}).should == "no\n" - end + it 'modifies the environment and runs the command given' do + subject.call("echo $yes", {"yes" => "no"}).should == "no\n" + end - it 'sets the exitstatus when a command completes' do - subject.call("ruby -e 'exit 0'") - $?.exitstatus.should == 0 - subject.call("ruby -e 'exit 5'") - $?.exitstatus.should == 5 + it 'sets the exitstatus when a command completes' do + subject.call("ruby -e 'exit 0'") + $?.exitstatus.should == 0 + subject.call("ruby -e 'exit 5'") + $?.exitstatus.should == 5 + end end end - diff --git a/spec/cocaine/command_line/runners/posix_runner_spec.rb b/spec/cocaine/command_line/runners/posix_runner_spec.rb index c28c107..6b63acf 100644 --- a/spec/cocaine/command_line/runners/posix_runner_spec.rb +++ b/spec/cocaine/command_line/runners/posix_runner_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe Cocaine::CommandLine::PosixRunner do - if Cocaine::CommandLine::posix_spawn_available? + if Cocaine::CommandLine::PosixRunner.supported? it_behaves_like 'a command that does not block' it 'runs the command given' do @@ -20,4 +20,3 @@ end end end - diff --git a/spec/cocaine/command_line/runners/process_runner_spec.rb b/spec/cocaine/command_line/runners/process_runner_spec.rb index 3554032..c346e36 100644 --- a/spec/cocaine/command_line/runners/process_runner_spec.rb +++ b/spec/cocaine/command_line/runners/process_runner_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe Cocaine::CommandLine::ProcessRunner do - if Process.respond_to?(:spawn) + if Cocaine::CommandLine::ProcessRunner.supported? it_behaves_like "a command that does not block" it 'runs the command given' do diff --git a/spec/cocaine/command_line_spec.rb b/spec/cocaine/command_line_spec.rb index 4eb5e10..f5c2a0c 100644 --- a/spec/cocaine/command_line_spec.rb +++ b/spec/cocaine/command_line_spec.rb @@ -238,38 +238,39 @@ describe "command execution" do it "uses the BackticksRunner by default" do - Process.stubs(:respond_to?).with(:spawn).returns(false) - Cocaine::CommandLine.stubs(:posix_spawn_available?).returns(false) + Cocaine::CommandLine::ProcessRunner.stubs(:supported?).returns(false) + Cocaine::CommandLine::PosixRunner.stubs(:supported?).returns(false) cmd = Cocaine::CommandLine.new("echo", "hello") + cmd.runner.class.should == Cocaine::CommandLine::BackticksRunner end it "uses the ProcessRunner on 1.9 and it's available" do - Process.stubs(:respond_to?).with(:spawn).returns(true) - Cocaine::CommandLine.stubs(:posix_spawn_available?).returns(false) + Cocaine::CommandLine::ProcessRunner.stubs(:supported?).returns(true) + Cocaine::CommandLine::PosixRunner.stubs(:supported?).returns(false) cmd = Cocaine::CommandLine.new("echo", "hello") cmd.runner.class.should == Cocaine::CommandLine::ProcessRunner end - it "uses the PosixRunner if the posix-spawn gem is available" do - Cocaine::CommandLine.stubs(:posix_spawn_available?).returns(true) + it "uses the PosixRunner if the PosixRunner is available" do + Cocaine::CommandLine::PosixRunner.stubs(:supported?).returns(true) cmd = Cocaine::CommandLine.new("echo", "hello") cmd.runner.class.should == Cocaine::CommandLine::PosixRunner end - it "uses the BackticksRunner if the posix-spawn gem is available, but we told it to use Backticks all the time" do - Cocaine::CommandLine.stubs(:posix_spawn_available?).returns(true) + it "uses the BackticksRunner if the PosixRunner is available, but we told it to use Backticks all the time" do + Cocaine::CommandLine::PosixRunner.stubs(:supported?).returns(true) Cocaine::CommandLine.runner = Cocaine::CommandLine::BackticksRunner.new cmd = Cocaine::CommandLine.new("echo", "hello") cmd.runner.class.should == Cocaine::CommandLine::BackticksRunner end - it "uses the BackticksRunner if the posix-spawn gem is available, but we told it to use Backticks" do - Cocaine::CommandLine.stubs(:posix_spawn_available?).returns(true) + it "uses the BackticksRunner if the PosixRunner is available, but we told it to use Backticks" do + Cocaine::CommandLine::PosixRunner.stubs(:supported?).returns(true) cmd = Cocaine::CommandLine.new("echo", "hello", :runner => Cocaine::CommandLine::BackticksRunner.new) cmd.runner.class.should == Cocaine::CommandLine::BackticksRunner