With most (all?) Ruby interpreters one can write ruby -we "..." and have the supplied Ruby code executed (with warnings).
With RVM one can write rvm ruby foo.rb and have the source file executed against all installed interpreters.
Is there a way with RVM to run a one-off line of code against all interpreters? I have tried executing both rvm ruby -we "..." and rvm -we ruby "..." to no good effect.
See rvm exec.
rvm exec ruby -we 'puts "#{`which ruby`.strip} #{RUBY_VERSION}"'
Related
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.
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
Homebrew, ruby 2.0.0p648, nokogiri 1.6.7.2 are installed. When require 'nokogiri' there appears an error:
-bash: require: command not found
What's wrong?
Try running the script from the console/terminal shell like this:
ruby script_name.rb
You can also try adding this shebang line to the top of your .rb file:
#!/usr/bin/env ruby
This will auto-identify the script as Ruby when you try to run it directly in some shells. Also see:
Why is it better to use “#!/usr/bin/env NAME” instead of “#!/path/to/NAME” as my shebang?
what is the use of “#!/usr/local/bin/ruby -w” at the start of a ruby program
You're running your command in bash -- this is a Ruby command.
You can't run a Ruby command directly in bash. If you want to use Ruby at command line, open the Ruby shell irb.
$ irb
and then you'll see the prompt
2.3.0 :001 >
The first number indicates the Ruby version you are using. In my case it is Ruby 2.3.0. The second number is the command number.
Then you may type
require 'nokogiri'
and it surely work, if you have this gem installed.
I get an error when I run %x{rvm use #myapp} in ruby and irb. The error is "RVM is not a function, selecting rubies with 'rvm use ...' will not work".
Here's what I've tried:
1. the "rvm use #myapp" command works in OSX command prompt (using OSX Mavericks)
2. made sure RVM is the latest version.
3. reloaded RVM check RVM is a function in the command prompt
4. (still fails in irb and ruby's %x{})
5. According to some SO posts, I changed OSX terminal preferences from login shell to /bin/bash and /bin/bash --login. Quit, opened new terminal windows but all efforts were in vain.
6. checked .bash_profile for [[-s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session *as a function*
Any ideas on how I can get %x{rvm use #myapp} to work in ruby and irb?
What happens here is that the shell you had started ruby or irb with had rvm defined both as a function and added to PATH the function takes precedence in shell and it all worked fine, but when you open ruby or irb it is a new process and it inherits only environment variables which includes PATH and does not inherit functions, additionally running %x{} from ruby creates another shell process which is neither a login or interactive shell, and they respectively would make shell load ~/.bash_profile and ~/.bashrc.
Depending on what do you want to do you have few options, to execute another ruby/gem you can use rvm ... do ... for from %x{} like this:
rvm #myapp do ruby -e '...'
OR:
rvm #myapp do gem install ...
OR:
rvm #myapp do bundle install
it allows single command to run in the context of given ruby
Try this trick:
%x{bash -c 'source "$HOME/.rvm/scripts/rvm"; rvm use #myapp'}
However, you really can use rvm as you've specified because even if you've set up the rvm you then lost your session because your terminal will be closed. Try to setup your environment with session gem, and control bash session with it.
require 'session'
#myapp = 'ruby-1.8.7-p374'
bash = Session::Bash.new
stdout, stderr = bash.execute 'source "$HOME/.rvm/scripts/rvm"'
stdout, stderr = bash.execute "rvm use #{#myapp}"
puts stdout
# => Using /home/malo/.rvm/gems/ruby-1.8.7-p374
In Terminal, ruby -v gives me:
ruby 1.8.7 (2011-12-28 patchlevel 357) [universal-darwin11.0]
But if I type /bin/bash then ruby -v I get:
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin11.4.0]
I suspect this is something to do with my PATH config(s). My $PATH variable is different in both the above environments. There are other issues e.g. rvm won't run unless I go into bash mode.
For info, my ~/.bashrc contains:
PATH=$PATH:$HOME/.rvm/bin # Add RVM to PATH for scripting
[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # This loads RVM into a shell session.
Looks like "login shell" is not enabled, you need to enable it in Terminal Emulator Preferences, sometimes it is needed to use /bin/bash --login.
There are also known issues with ZSH, but it seams to be unrelated.
Try which ruby from "terminal" and "/bin/bash". Your 1.9.3 is inside your ~/.rvm path.
Type rvm info. You should get a list of the settings for RVM.
In your ~/.bashrc OR ~/.bash_profile, you should have RVM's initialization code. If you don't you didn't install RVM completely and need to finish. Read all the instructions on the RVM installation page.
This was not due to a $PATH problem. What I've learned is that RVM cannot be run unless you change your default login shell to either Bash or ZSH. Just firing up Terminal in Mac won't work. You make the global change to using Bash like this:
chsh -s /bin/bash
(swap /bin/bash for whatever your bash path is, find out using which bash).
The RVM website does say that bash>=3.2.25 is a prerequisite, but doesn't say what that is or how to check whether you have it. It also advises you to run rvm requirements to check what you need - and you can't run this unless you change your shell (all quite confusing for somebody new to this).
Thanks to the replies above for getting me there in the end.
See also: Bad: modifier error when installing RVM
Long time lurker, first time poster!
Goal
My ultimate goal is to make a Rake setup script to setup my rvm environment stuff (I need to dynamically create gemsets, install gems to those gemsets, and run ruby scripts within those gemsets).
Problem
I need to setup rvm in the shell that I'm executing rvm commands in. The basic idea is to source the rvm scripts as outlined here.
The problem arises when I try and source the rvm script when executing a shell command within ruby. Its well documented that rvm only supports bash, but ruby doesn't seem to be using bash when executing shell commands.
What I've Tried
I've tried all the methods to execute shell commands listed here to no avail. I'll use the 'exec' method below for simplicity.
It seems that although ruby thinks its using the bash shell to execute these commands ... it is not. Observe!
exec 'echo $SHELL'
=> /bin/bash
But
exec 'source ~/.rvm/scripts/rvm; type rvm | head -1;'
=> sh: source: not found
=> rvm is ~/.rvm/bin/rvm
Which tells me that ruby is really using /bin/sh not /bin/bash (that output should return rvm is a function). I even went so far as to print the ruby env stuff, and ENV[SHELL] is '/bin/bash'
'Brute Force' Solution
I do have a workaround, but its really kludgy (this would necessitate that I 'AND' all of the commands together):
exec 'echo \'source ~/.rvm/scripts/rvm && type rvm | head -1\' | /bin/bash'
I'd like to avoid using shell scripts if possible -- it seems reasonable that I can accomplish this within ruby.
As it happens, RVM actually exposes a Ruby API that's included by default. Add $HOME/.rvm/lib to your $LOAD_PATH; you can now use require 'rvm'.
As far as I can tell, the main documentation for this is in the source files themselves (a summary is in rvm.rb).
Now you can write Ruby scripts that manipulate RVM, like this:
require 'rvm'
env = RVM.current
env.gemset.create('newgemset')
And so on.
Call bash with the -c parameter:
command = 'source ~/.rvm/scripts/rvm; type rvm | head -1'
exec "bash -c #{command.inspect}"