diff --git a/lib/rscons.rb b/lib/rscons.rb index 70c2963..bf54ef1 100644 --- a/lib/rscons.rb +++ b/lib/rscons.rb @@ -83,6 +83,33 @@ module Rscons end end end + + # Return an Array containing a command used to execute commands. + # + # This will normally be an empty Array, but on Windows if Rscons detects + # that it is running in MSYS then ["env"] will be returned. + # + # @return [Array] Command used to execute commands. + def self.command_executer + @@command_executer ||= + if Object.const_get("RUBY_PLATFORM") =~ /mingw/ + if ENV.keys.find {|key| key =~ /MSYS/} + begin + if IO.popen(["env", "echo", "success"]) {|io| io.read.strip} == "success" + ["env"] + end + rescue + end + end + end || [] + end + + # Set the command executer array. + # + # @param val [Array] Command used to execute commands. + def self.command_executer=(val) + @@command_executer = val + end end # Unbuffer $stdout diff --git a/lib/rscons/environment.rb b/lib/rscons/environment.rb index 1980315..2233a4b 100644 --- a/lib/rscons/environment.rb +++ b/lib/rscons/environment.rb @@ -245,7 +245,7 @@ module Rscons end env_args = options[:env] ? [options[:env]] : [] options_args = options[:options] ? [options[:options]] : [] - system(*env_args, *command, *options_args).tap do |result| + system(*env_args, *Rscons.command_executer, *command, *options_args).tap do |result| unless result or @echo == :command $stdout.write "Failed command was: " print_command.call diff --git a/spec/rscons_spec.rb b/spec/rscons_spec.rb index 81a412f..37e288a 100644 --- a/spec/rscons_spec.rb +++ b/spec/rscons_spec.rb @@ -66,4 +66,50 @@ describe Rscons do expect(Rscons.get_system_shell).to eq(["sh", "-c"]) end end + + context "command executer" do + describe ".command_executer" do + before(:each) do + Rscons.class_variable_set(:@@command_executer, nil) + end + + after(:each) do + Rscons.class_variable_set(:@@command_executer, nil) + end + + it "returns ['env'] if mingw platform in MSYS and 'env' works" do + Object.should_receive(:const_get).and_return("x86-mingw") + ENV.should_receive(:keys).and_return(["MSYSCON"]) + io = StringIO.new("success\n") + IO.should_receive(:popen).with(["env", "echo", "success"]).and_yield(io) + expect(Rscons.command_executer).to eq(["env"]) + end + + it "returns [] if mingw platform in MSYS and 'env' does not work" do + Object.should_receive(:const_get).and_return("x86-mingw") + ENV.should_receive(:keys).and_return(["MSYSCON"]) + IO.should_receive(:popen).with(["env", "echo", "success"]).and_raise "ENOENT" + expect(Rscons.command_executer).to eq([]) + end + + it "returns [] if mingw platform not in MSYS" do + Object.should_receive(:const_get).and_return("x86-mingw") + ENV.should_receive(:keys).and_return(["COMSPEC"]) + expect(Rscons.command_executer).to eq([]) + end + + it "returns [] if not mingw platform" do + Object.should_receive(:const_get).and_return("x86-linux") + expect(Rscons.command_executer).to eq([]) + end + end + + describe ".command_executer=" do + it "overrides the value of @@command_executer" do + Rscons.class_variable_set(:@@command_executer, ["env"]) + Rscons.command_executer = [] + expect(Rscons.class_variable_get(:@@command_executer)).to eq([]) + end + end + end end