Accessing Ruby gems in a script

Get help. Get answers. Let others lend you a hand.

Moderator: Mr_Noodle

Accessing Ruby gems in a script Mon Jan 07, 2013 9:57 pm • by dcboz
After hours of trial and error (I think) I've finally nailed a scripting problem with Hazel and Ruby that is causing "[Error] Shell script failed: Error processing shell script on file..." errors. Everything was working fine until I upgraded to ruby-1.9.3-p327 as I needed a function that's not present in the 1.8.x code. A script that ran from the Terminal, and still does, fails in Hazel.

My question boils down to this. How do I get ruby running within an embedded script to recognise where the third-party gem files are located? Read on for more detail.

As far as I can tell, the script fails on the require 'gemname' call for any gems that are not built into ruby itself. Here's my test code in Hazel.

Code: Select all
cat "$1" >> /Users/DCB/Desktop/Hazel.log
/Users/DCB/.rvm/rubies/ruby-1.9.3-p327/bin/ruby -v >> /Users/DCB/Desktop/Hazel.log
/Users/DCB/.rvm/rubies/ruby-1.9.3-p327/bin/ruby ~/Documents/test.rb "$1" >> /Users/DCB/Desktop/Hazel.log


The first two lines are proving Hazel is neither erroring on the filename, nor is it failing to get the wrong version of ruby. From this I learnt I had to provide the full ruby path. The final line runs a test script.

Code: Select all
#!/usr/bin/ruby

require 'rubygems'
#require 'plist'         # If missing, from commandline run "gem install plist"
require 'optparse'
#require 'logger'      # If missing, from commandline run "gem install logger"
#require 'nokogiri'

puts "Test script works"
ARGV.each do |a|
   puts a
end


As shown above the script runs without error and correctly outputs the file name from with in the script. Both rubygems and optparse are built-in gems and work fine. If I uncomment any of plist, logger or nokogiri I get a scripting error.

To try and fix this I added the following to the script in order to set the GEM paths but it failed.

Code: Select all
cat "$1" >> /Users/DCB/Desktop/Hazel.log
/Users/DCB/.rvm/rubies/ruby-1.9.3-p327/bin/ruby -v >> /Users/DCB/Desktop/Hazel.log
export GEM_HOME=/Users/DCB/.rvm/gems/ruby-1.9.3-p327/gems
export GEM_PATH=/Users/DCB/.rvm/gems/ruby-1.9.3-p327/gems
/Users/DCB/.rvm/rubies/ruby-1.9.3-p327/bin/ruby ~/Documents/test.rb "$1" >> /Users/DCB/Desktop/Hazel.log


The same two lines appear in my .bash_profile as well. The embedded script's shell is /bin/bash

How do I get ruby running within an embedded script to recognise where the gem files are located?

Thanks,

-David
dcboz
 
Posts: 3
Joined: Mon Jan 07, 2013 9:43 pm

Re: Accessing Ruby gems in a script Tue Jan 08, 2013 2:09 pm • by a_freyer
A quick read of the ruby environment variables you have the benefit of in terminal but not Hazel, you may have to define a few more:

Ruby Documentation on Environment Variables wrote:HOME
HOMEDRIVE
HOMEPATH


Is there a change if you define these? I would anticipate the gems each try to use these very common paths.
a_freyer
 
Posts: 631
Joined: Tue Sep 30, 2008 9:21 am
Location: Colorado

Re: Accessing Ruby gems in a script Wed Jan 09, 2013 1:05 am • by dcboz
Thanks for the suggestion a_freyer. It wasn't the right one but got me on the path to ultimate success. There were multiple things happening at once.

The solution has been to:

[list=]set GEM_PATH[/list]
[list=]set RUBYLIB[/list]
[list=]explicity call Ruby via its full path[/list]
[list=]use the -S option on Ruby to have it look through sub-folders[/list]
[list=]fix a bug in one of the gems to make it 1.9.x compatible[/list]

My call now looks like this:

Code: Select all
export GEM_PATH=/Users/DCB/.rvm/gems/ruby-1.9.3-p327:/Users/DCB/.rvm/gems/ruby-1.9.3-p327@global
export RUBYLIB=/Users/DCB/.rvm
/Users/DCB/.rvm/rubies/ruby-1.9.3-p327/bin/ruby -S ~/Documents/dayone_updater.rb <listofargs> "$1" &>~/Library/Logs/Hazel/Hazel.log


The Ruby script creates its own log file, however that doesn't catch errors, hence the redirect to Hazel's log.

This is messy and it would be great if Hazel could use the variables available to the terminal. Perhaps someone knows a better way than the two export statements above as they will have to change across multiple rules each time I update ruby. I'll look to see if it is possible to set them from within Ruby's script.

-David
dcboz
 
Posts: 3
Joined: Mon Jan 07, 2013 9:43 pm

Re: Accessing Ruby gems in a script Mon Jan 14, 2013 1:05 pm • by Mr_Noodle
I am considering making it so at least sh/bash will read config files though it wont eliminate all the problems. The shell startup file procedure is a mess so there will still be issues with which variables are declared in which config files and whether those are the right ones that are read in.
Mr_Noodle
Site Admin
 
Posts: 11865
Joined: Sun Sep 03, 2006 1:30 am
Location: New York City

Re: Accessing Ruby gems in a script Mon Jan 14, 2013 9:35 pm • by dcboz
I can see that it would be confusing if there are inconsistencies. At the moment it's pretty confusing anyway and in my case, suffers from the need to repeat, and subsequently update, multiple items each time I upgrade Ruby.
dcboz
 
Posts: 3
Joined: Mon Jan 07, 2013 9:43 pm

Re: Accessing Ruby gems in a script Fri Jan 25, 2013 4:29 am • by nbsheeran
David -

I believe the issue is RVM. When Hazel (and other programs such as Keyboard Maestro) execute a shell script, they are not using a login shell and your RVM-Ruby environment isn't being used. The RVM website has the answer here:

https://rvm.io/workflow/scripting/

I use this snippet (from the above link) in the beginning of any script that Hazel will execute, and it should work:

Code: Select all
#!/bin/bash
# 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"

fi


Then put your desired commands after that. It works for me.

- Neal
nbsheeran
 
Posts: 2
Joined: Fri Jan 25, 2013 4:16 am

Re: Accessing Ruby gems in a script Fri Jan 25, 2013 4:55 am • by nbsheeran
One thing I forgot. For me, I have a specific gemset for a project (my Octopress-powered static blog). So the first two commands after the snippet above are these:

Code: Select all
cd /Users/me/code/octopress
rvm use 1.9.3@octopress


And then I can issue the specific rake commands in that directory. I just tested this with Hazel: when a .markdown file appears in a folder, Hazel moves it and executes a shell script that includes commands for regenerating the site and then uploading to my site.
nbsheeran
 
Posts: 2
Joined: Fri Jan 25, 2013 4:16 am

Re: Accessing Ruby gems in a script Mon Aug 12, 2013 11:32 am • by gtd
If you happen to be using rbenv instead of rvm then it's a bit easier to get the environment set up correctly. There are a few ways to do it, but i've taken to referencing the ruby shim directly in the hashbang line at the top of my script, like:

Code: Select all
#!/Users/gtd/.rbenv/shims/ruby


It's relatively easy to understand how it all works just reading Sam's description at https://github.com/sstephenson/rbenv
gtd
 
Posts: 1
Joined: Mon Aug 12, 2013 11:08 am


Return to Support

cron