"RVM is not a function" error when running in ruby script and irb - ruby

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

Related

Use rvm to force specific Ruby in Xcode Run Script build phase

Outside of Xcode I use a specific version of Ruby, using RVM to manage multiple Ruby installations.
Apple's command line dev tools install Ruby at /usr/bin/ruby and is version 1.8.7.
I use 1.9.3 through RVM.
Is there a way to force Xcode to use my 1.9.3 installation when running its Run Script build phases?
I already tried setting the Shell path to the full path of my specific Ruby, but that didn't seem to make a difference, by which I mean that the particular Gems I have installed in my 1.9.3 weren't available/visible to the script when run within Xcode.
If I run my project through xcodebuild on the command line, the Run Script phase uses my specific Ruby because it's being run from within my shell environment (even if the Shell path in the project file is set to /usr/bin/ruby, it still uses my 1.9.3).
What can I do to make the IDE use my 1.9.3 Ruby install?
I had the same (well, worse) problem, and the code that follows worked for me.
The key thing to realize is that, on the command line, you are using <something>/bin/rvm, but in a shell script, in order for rvm to change that environment, you must use a function, and you must first load that function to your shell script by calling source <something>/scripts/rvm. More on all this here.
This code is also gisted.
#!/usr/bin/env bash
# Xcode scripting does not invoke rvm. To get the correct ruby,
# we must invoke rvm manually. This requires loading the rvm
# *shell function*, which can manipulate the active shell-script
# environment.
# cf. http://rvm.io/workflow/scripting
# Load RVM into a shell session *as a function*
if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
# First try to load from a user install
source "$HOME/.rvm/scripts/rvm"
elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
# Then try to load from a root install
source "/usr/local/rvm/scripts/rvm"
else
printf "ERROR: An RVM installation was not found.\n"
exit 128
fi
# rvm will use the controlling versioning (e.g. .ruby-version) for the
# pwd using this function call.
rvm use .
As a protip, I find embedding shell code in a project.pbxproj file yucky. For all but the most trivial stuff, my actual run script step is usually just a one-line call out to an external script:
Try this at the beginning of your script in Xcode:
source "$HOME/.rvm/scripts/rvm"

How to permanently switch ruby -v 1.8.7 to 1.9.3

By using these commands
source ~/.rvm/scripts/rvm
rvm use 1.9.3 --default
The version in current session is 1.9.3 but when I close terminal and reopen ruby version comes back to 1.8.7.
Do I need to add something to the .bash_profile ?
Edit: I found the another way is when I reopen terminal everytime just type source .bash_profile. The version then is 1.9.3. Is there anyway to execute the .bash_profile permanently ?
Yes you need to add something to your bash profile. See here:
https://rvm.io/rvm/basics/
Quote:
The rvm installation documentation instructs you to put the following line at the very end of your bash profile:
# This loads RVM into a shell session
[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm"
Create a file named .rvmrc with the text rvm use 1.9.3 --default.
We're treading into sysadmin waters here but one possible explanation might be because of how you're logging into your shell and your OS. See the discussion of what files are loaded by your shell here and what makes up a login vs. non-login shell here.

Switching rubies in shell script

When executing a bash shell script I am using ruby 1.9.3. Then, within the script, I want to switch to JRub (I'm using rvm). I tried switching to JRuby by doing rvm use jruby within the script, but this didn't work, it said:
RVM is not a function, selecting rubies with 'rvm use ...' will not work.
You need to change your terminal emulator preferences to allow login shell.
Sometimes it is required to use `/bin/bash --login` as the command.
Please visit https://rvm.io/integration/gnome-terminal/ for a example.
./run.sh: line 10: jruby: command not found
When I do type rvm | head -n1 at the command prompt, I get: rvm is a function. So I'm not sure of the problem. I thought it might be because I installed JRuby using sudo (sudo rvm install jruby). So I ran the shell script again using sudo. Again I received the error.
How can I switch rubies from within a bash shell script with rvm?
Thanks
I ended up adding this to the line before:
[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm"
as explained in this thread (sorry - though I was aware of this thread before, I didn't quite grasp it):
RVM doesn't switch Rubies
/complete/path/to/rvm your shell seems to have an 'rvm' builtin command defined.

Ruby versions differ in Terminal & bash

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

Cannot execute RVM shell commands in ruby

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}"

Resources