Search code examples
rubyubuntureadlinerbenvupstart

Can't import readline in ruby script called by upstart


I'm trying to get a rails app to deploy with upstart. As part of this, I'm using an rbenv ruby (ruby 1.9.3p392, should it matter).

Through a long string of debugging, I've got things down to what I think is a minimal test case. This script:

require 'readline'

works when I run it from the command line, but when I start it through upstart with a stanza like:

script
  env > /tmp/upstart.env
  gem environment > /tmp/gem.env
  /home/topshelf-deploy/.rbenv/shims/ruby bundle_test.rb > /tmp/bt.log 2>&1
end script

my logfile contains:

/home/topshelf-deploy/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rb-readline-0.4.2/lib/rbreadline.rb:1091:in `<module:RbReadline>': undefined method `+' for nil:NilClass (NoMethodError)
    from /home/topshelf-deploy/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rb-readline-0.4.2/lib/rbreadline.rb:13:in `<top (required)>'
    from /home/topshelf-deploy/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
    from /home/topshelf-deploy/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
    from /home/topshelf-deploy/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rb-readline-0.4.2/lib/readline.rb:8:in `<module:Readline>'
    from /home/topshelf-deploy/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rb-readline-0.4.2/lib/readline.rb:6:in `<top (required)>'
    from /home/topshelf-deploy/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/rubygems/custom_require.rb:60:in `require'
    from /home/topshelf-deploy/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/rubygems/custom_require.rb:60:in `rescue in require'
    from /home/topshelf-deploy/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/rubygems/custom_require.rb:35:in `require'
    from bundle_test.rb:1:in `<main>'

My gem environment appears to be identical depending on whether I'm running via upstart or an interactive shell (where, again, this works fine). I've set the PATH to point to my rbenv ruby.

Any advice on how to get this working? My Google searches don't turn up anything remotely similar. I'm baffled.


Solution

  • Finally breaking down and looking at the source of rbreadline.rb:1091 shows me:

    ENV["HOME"] ||= ENV["HOMEDRIVE"]+ENV["HOMEPATH"]
    

    Ah. rb-readline requires that I have the HOME environment variable set. Because, reasons :P

    Added env HOME=/home/topshelf-deploy to my upstart configuration and all is well.