1
votes

I was looking for a way to run 'rake spec' for all ruby versions.

So far I wrote this code in Rakefile but it doesn't work:

RUBIES = ['ruby-2.0.0', 'ruby-2.1.1', 'ruby-2.2.1']

RUBIES.each do |ruby_v|
  sh "rvm use #{ruby_v}"
  RSpec::Core::RakeTask.new(:spec)
end

Any ideas how may I accomplish this?

It would be great if I could pass down arguments specifying whether I want to run the tests for a single ruby version or for all.

EDIT:

Here's the Rakefile I used and the error I am getting. It's not the same file which I mentioned at the top. It uses rvm use #{ruby_v}; rspec spec as suggested by Keith in the answer.

1
You can't switch the Ruby version from within Ruby. - Stefan
Hmm. So, is there any way to write a rake task that would run specs for a number of different rubies? - Lokesh
RVM comes with wrappers. According to the docs, running /usr/local/rvm/wrappers/ruby-2.1.1@projectX/rake should work (you have to adjust the path) - Stefan
That is very helpful. Thanks @Stefan. The plus point here is that I don't have to rely upon presence of bash or zsh. Also the output appears on screen as soon as it's generated. - Lokesh

1 Answers

2
votes

rvm is a shell command and its Ruby setting applies only to the current instance of the shell. So when you run sh "rvm use #{ruby_v}" you're changing the rvm version of the shell that you have invoked, and then exiting from that shell.

In addition, your Ruby program is an operating system process running the Ruby virtual machine, so when you make the call to RSpec::Core::RakeTask.new(:spec), you're still in that same OS process and Ruby version with which you started your script.

You'll need to run the rspec tests in the shell that you invoke and change the Ruby version on. I thought something like this would work:

`rvm use #{ruby_v}; rspec spec`

...but as you pointed out, it does not. You need to run the new shell as a "login shell" so that rvm is set up correctly. In addition, the new shell must be told that the thing you're invoking is a shell command and not a script or binary executable. In other words:

1) have your command explicitly invoke bash or zsh (sh did not work for me on my Mac).

2) specify (probably with -l) that it is a login shell.

3) specify (probably with -c) that you are executing a shell command (rvm) and not a script or executable.

I am using zsh as my shell, but you should be able to substitute bash in the code below and it should work (and of course put your rspec command in there):

2.3.0 :024 > puts `zsh -lc "rvm current"`
ruby-2.3.0
 => nil
2.3.0 :025 > puts `zsh -lc "rvm use jruby; rvm current"`
Using /Users/kbennett/.rvm/gems/jruby-9.0.5.0
jruby-9.0.5.0
 => nil
2.3.0 :026 > puts `zsh -lc "rvm current"`
ruby-2.3.0
 => nil