How can I use rvm within a Makefile? - ruby

Working on this project: https://github.com/cucumber/bool
There's a makefile to construct the various items, and I'd like to use RVM to be able to switch between rubies for the stuff within the ruby directory, however, when I give the makefile commands to switch rubies, I get a nasty error
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.
Of course, it works just fine if I issue rvm use 1.9.3 on the command line, so this is a symptom of something else, but I'm not sure what.

When you call RVM from cron (or a Makefile, I would expect) it's important to set up the right environment. The Scout team have a great blog article explaining this:
http://blog.scoutapp.com/articles/2010/09/07/rvm-and-cron-in-production
The important part is ensuring you have a full login shell so you have access to RVM.
/bin/bash -l -c 'the_command_inside_makefile"

This seems like a good use for an RVM wrapper script, which will let you generate a shell script which loads a given RVM ruby instance into that environment without using the normal, interactive RVM setup.
For example:
rvm wrapper 1.9.3#bool ruby bool
... will create a wrapped script called 'bool' with a given Ruby selected.

Related

Unable to create rvmrc, RVM is not a function, selecting rubies with 'rvm use ...' will not work

alex#ubuntu:~/Documents/ruby_projects/my_project$ rvm --create --rvmrc 1.9.3#my_project
this one gives me
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.
Why am I unable to create rvmrc this way?
It could be you've corrupted your rvm installation somehow. It may be possible to fix it by wrecking around in the various shell script files it incorporates, but the easiest way to cure that problem is to re-install it.
If re-installing on top of your existing install doesn't work, try removing it completely before installing with:
rvm implode
It's usually best to create a new shell after it's been destroyed in order to start with a clean-slate. RVM has all kinds of hooks that can persist in any existing shells even after it's been imploded.
You need to read the message and follow the instructions.
A basic use of rvm is to:
rvm [use] <ruby-version>
where omitting the use keyword is still meaning to use a ruby but will not display a message.

How to load the RVM part of user's .bashrc to run Ruby CGI scripts under Apache?

I've configured a new server on Ubuntu 12.04 and I started to use RVM.
I've installed RVM under my user (as myself, not as root with sudo) by following the Ryan Bigg's guide, with no previous system-wide installed Ruby. So, I didn't have any Ruby under /usr/bin. My first task then was to replace the shebang line of all my CGI scripts, from
!#/usr/bin/ruby
to
!#/usr/bin/env ruby
However my scripts didn't run under Apache. In the terminal I could run them (by typing ./index.cgi, for example), but not over a browser. A relevant note: in both the user is the same, i.e., the Apache user is the same as the one logged on terminal. Through php tests, I've checked the RVM enviroment (last lines of .bashrc) was not loaded under Apache.
I saw this tip for running CGI scripts with RVM, which suggests to put the complete path of specific version of Ruby in the shebang line. That can be useful if you have scripts which run on different versions of Ruby. But that solution doesn't work for me, because my scripts must run on different machines, with different users and different paths.
The solution which works for me is to put a symlink of the desired Ruby version under /usr/bin:
sudo ln -s /home/apache_user/.rvm/rubies/ruby-1.8.7-p370/bin/ruby /usr/bin/ruby
But I want to know if there's a better solution, because I guess that rvm --default use is better than sudo ln -s.
I am thinking about:
loading the RVM Environment on startup (but I don't know how to achieve that);
loading the RVM Environment for each web request (which can degrade performance, and I don't know how to configure Apache to do that);
maybe the RVM Environment is loaded and all I must do is to guess the name of relevant variables to pass with PassEnv directive. But I doubt that. (Why Apache would run the .bashrc instead of another shell like csh or ksh?)
you can source the ruby environment, I'm not sure if it's enough to source it in $HOME for apache or if you need to modify /etc/init.d/apache2, but the line is:
source /path/to/rvm/environments/<name>
where for <name> you can either use full ruby name or an alias name
You can create aliases with:
rvm alias create veve 1.9.3-p125#my-project
which for RVM installed in /home/app/.rvm will allow you to use:
source /home/app/.rvm/environments/veve
in .bashrc or /etc/init.d/apache2 (just near top, bellow shebang).
you could always do
sudo ln -s /usr/local/rvm/rubies/default/bin/ruby /usr/bin/ruby
That will link the default version of the rvm-managed Ruby to /usr/bin/ruby and you will never have to do anything. set it and forget it.

How do I specify the order of "default" rvms?

I have RVM installed, with project rvmrc files enabled.
In my bashrc I have:
rvm use 1.9.2
However, in one of my project rvmrc files I have:
rvm use 1.8.7
Which works great, however if I open up a new terminal window within the project I get:
Using /home/.../.rvm/gems/ruby-1.8.7-p352
Using /home/.../.rvm/gems/ruby-1.9.2-p290
Obviously, I want to 1.8.7, but the bashrc gets run after the project rvmrc. Meaning I'm using the wrong rvm so either have to cd out and back into the directory or run rvm use 1.8.7 again.
Is there anyway to force the rvmrc file to run after the bashrc?
I know about rvm default, but not sure if I want to\can use this.
please read this: https://rvm.beginrescueend.com/support/faq/#shell_login it describes which files should be used in which use cases.
as for rvm --default 1.9.2 it should be used over manually entering version into your rc file as it is loading ruby only if one was not yet selected.
Simplest solution for your rc files problem (I guess you have one) would be rvm get head --auto which will reorganize sourcing rvm in your rc files - to make it fully functional you need to restart your graphical session (or just reboot computer).

How to interact with RVM from ruby?

I am trying to get informations about the installed versions of ruby inside RVM and the associated gemsets and gems.
My first idea was to use a system call to rvm list to get the installed Rubies and rvm use #{ruby_version} && rvm gemset list for every Ruby. But there is an issue with that. It seems that rvm use #{ruby_version} is executed and confirmed by RVM (output Using #{path_to_ruby), but the gemsets listed are the one from the Ruby version that runs the script.
Is there any way to communicate with RVM from a Rubyscript via CLI or an API?
I'll take a stab at this - I think your problem is that rvm works mostly by mucking around with your environmental variables to point your shell to the different gemsets and ruby versions.
But when you run rvm use in a subshell the changes of the env variables are not propagated up to the parent shell.
Without having looked into this too much yet, my initial idea would for you to run the rvm use thing + then in that same subshell session run something that lists the contents of all these updated env vars (see here for which ones you need to look at: http://beginrescueend.com/rvm/info/ )...then in your ruby script you need to set the environment to match the environment in your subshell.
In shellspeak what you usually do in a case like this is "source" the script instead of executing it. I.e. source "the_script_that_sets_environment_variables". But when you are in a ruby script and use backticks to run stuff in a subshell you can't propagate the environment back up to the parent without doing it manually.
Another solution might be to take a look at the RVM Ruby API. I didn't find much documentation on it yet, but it might also do the trick for your case:
http://www.rubyflow.com/items/4285

What is the purpose of the RVM binary if it can be run as a function?

I've recently started using Ruby and was told to look into using RVM. I'm currently trying to understand how it operates but as far as I can tell from the website it can be run either as a binary or as a function in the shell by modifying .bash_profile.
What are the binaries for? I noticed they got installed to ~/bin, which felt sort of messy, and they did not seem to be invoked when using the rvm command. Are the binaries even needed when running RVM as a shell function?
It is normal and desirable for users of unix to put binaries in ~/bin (you would normally add that to your $PATH), so don't feel like it's messy to install stuff there.
That said, ~/bin/rvm is a script that will let you run rvm commands (like install), but is unable to edit your shell's environment (like all programs). Commands that need to edit the environment (like use), would not be possible without the rvm function. Not being super familiar with rvm, I am guessing the ~/bin/rvm exists for people that don't want to include the rvm stuff in all their shells. AFAICT, you don't need any of the stuff rvm puts in ~/bin if you are going to alter your ~/.bashrc as recommended.

Resources