This repository has been archived by the owner. It is now read-only.

Can't make calls to heroku CLI from within a Rake task without the Heroku gem in the Gemfile #617

Closed
alikhajeh1 opened this Issue Oct 31, 2012 · 16 comments

Comments

Projects
None yet
@alikhajeh1
Copy link

alikhajeh1 commented Oct 31, 2012

I removed the Heroku gem from our Gemfile and upgraded to use the Heroku toolbelt but now my rake tasks can't call the Heroku CLI.

The following line in a rake task:
system 'heroku pgbackups:url --app myapp'
Fails with:
...gems/bundler-1.0.21/lib/bundler/rubygems_integration.rb:143:in `block in replace_gem': heroku is not part of the bundle. Add it to Gemfile. (Gem::LoadError)

The following method:
system '/usr/local/heroku/bin/heroku pgbackups:url --app myapp'
Fails with:
Could not find libv8-3.3.10.4 in any of the sources
Run bundle install to install missing gems.

The above methods both work fine when run from the command line directly, they only fail within a rake task. I'm using OSX with RVM. What's the best way to do this?

@mogmi

This comment has been minimized.

Copy link

mogmi commented Nov 3, 2012

Same issue here, I guess I'll put back the Heroku gem in the Gemfile for now - is there any other way?

@ddollar

This comment has been minimized.

Copy link
Contributor

ddollar commented Nov 3, 2012

Remove the heroku gem from your Gemfile and make sure that which heroku is not pointing at some old gem stub.

@alikhajeh1

This comment has been minimized.

Copy link
Author

alikhajeh1 commented Nov 3, 2012

Tried that, no luck.

$ which heroku
/usr/local/heroku/bin/heroku

The Heroku installer has, correctly, updated the path as well:
#Added by the Heroku Toolbelt
export PATH="/usr/local/heroku/bin:$PATH"

@ddollar

This comment has been minimized.

Copy link
Contributor

ddollar commented Nov 3, 2012

What does which heroku show from inside your rake task?

@alikhajeh1

This comment has been minimized.

Copy link
Author

alikhajeh1 commented Nov 3, 2012

Good point, 'which heroku' was pointing to an old gem stub, I deleted that and there's still an issue:

$ heroku --version
heroku-toolbelt/2.33.0 (x86_64-darwin10.8.0) ruby/1.9.3

$ bundle exec irb
1.9.2p290 :001 > which heroku
=> "/usr/local/heroku/bin/heroku\n"
1.9.2p290 :002 > heroku --version
/Users/ali/.rvm/gems/ruby-1.9.2-p290@toolkit/gems/bundler-1.2.1/lib/bundler/spec_set.rb:90:in `block in materialize': Could not find libv8-3.3.10.4 in any of the sources (Bundler::GemNotFound)

@pauljamesrussell

This comment has been minimized.

Copy link

pauljamesrussell commented Nov 13, 2012

I'm having the same issue having done the same thing. Not much to add other than the fact that I've checked that the path is still preserved inside bundle exec. I guess bundler is somehow overriding the lib load path :/

@blakewatters

This comment has been minimized.

Copy link

blakewatters commented Nov 26, 2012

This is a huge pain in the ass if you have Rake tasks automating Heroku CLI workflows. This does not appear to be related to a lingering binstub. Instead, it looks like the Ruby environment required by the toolbelt is in conflict with what Bundler sets up.

Executing the toolbelt CLI works fine for me, but an attempt to execute it from within a subshell in the app throws dependency errors that I cannot resolve:

1.9.2p318 :001 > `which heroku`
 => "/usr/local/heroku/bin/heroku\n" 
1.9.2p318 :002 > `heroku --version`
/Users/blake/.rvm/gems/ruby-1.9.2-p318@gateguru/gems/bundler-1.2.1/lib/bundler/spec_set.rb:90:in `block in materialize': Could not find libv8-3.3.10.4 in any of the sources (Bundler::GemNotFound)
    from /Users/blake/.rvm/gems/ruby-1.9.2-p318@gateguru/gems/bundler-1.2.1/lib/bundler/spec_set.rb:83:in `map!'
    from /Users/blake/.rvm/gems/ruby-1.9.2-p318@gateguru/gems/bundler-1.2.1/lib/bundler/spec_set.rb:83:in `materialize'
    from /Users/blake/.rvm/gems/ruby-1.9.2-p318@gateguru/gems/bundler-1.2.1/lib/bundler/definition.rb:113:in `specs'
    from /Users/blake/.rvm/gems/ruby-1.9.2-p318@gateguru/gems/bundler-1.2.1/lib/bundler/definition.rb:158:in `specs_for'
    from /Users/blake/.rvm/gems/ruby-1.9.2-p318@gateguru/gems/bundler-1.2.1/lib/bundler/definition.rb:147:in `requested_specs'
    from /Users/blake/.rvm/gems/ruby-1.9.2-p318@gateguru/gems/bundler-1.2.1/lib/bundler/environment.rb:23:in `requested_specs'
    from /Users/blake/.rvm/gems/ruby-1.9.2-p318@gateguru/gems/bundler-1.2.1/lib/bundler/runtime.rb:11:in `setup'
    from /Users/blake/.rvm/gems/ruby-1.9.2-p318@gateguru/gems/bundler-1.2.1/lib/bundler.rb:116:in `setup'
    from /Users/blake/.rvm/gems/ruby-1.9.2-p318@gateguru/gems/bundler-1.2.1/lib/bundler/setup.rb:17:in `<top (required)>'
    from /usr/local/heroku/ruby/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
    from /usr/local/heroku/ruby/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
 => "" 
1.9.2p318 :003 > ^D

It looks like the environment changes introduced by rvm is blocking out the toolbelt's ability to initialize. Any ideas beside ripping out all of the dependencies on the CLI in my scripts and porting everything to heroku-api?

@blakewatters

This comment has been minimized.

Copy link

blakewatters commented Nov 26, 2012

Okay I have figured this out, if you are running on OS X + RVM with Bundler and the Toolbelt, your attempts to execute the Toolbelt from within a Rake task are going to fail because RVM has manipulated your Ruby environment in ways incompatible with the Toolbelt's expectations.

To work around this, I inspected the environment by executing bundle exec irb within my project and then running system("env | mate") to pop open a dump the current environment within TextMate. I dug through the environment variables and found that if you blank out the following environment variables when shelling out to the Toolbelt, all will begin working again:

  • GEM_HOME
  • BUNDLE_GEMFILE
  • GEM_PATH
  • RUBY_OPT

A simple wrapper method for executing the toolbelt in a clean environment looks something like:

# Executes a command in the Heroku Toolbelt
def heroku(command)
  system("GEM_HOME='' BUNDLE_GEMFILE='' GEM_PATH='' RUBYOPT='' /usr/local/heroku/bin/heroku #{command}")
end

Hope this helps!

@jordanandree

This comment has been minimized.

Copy link

jordanandree commented Dec 4, 2012

Recently had the same problem while writing a Rake task with Heroku CLI integration.

The solution @blakewatters posted has worked for me.

@wuputah

This comment has been minimized.

Copy link
Contributor

wuputah commented Dec 12, 2012

Hi all- sorry for the pain here. We recommend interacting directly with the API whenever possible to avoid these types of issues. heroku/heroku.rb is the main client to use from Ruby.

@wuputah wuputah closed this Dec 12, 2012

@nbuggia

This comment has been minimized.

Copy link

nbuggia commented Jul 22, 2013

@wuputah - I looked through the Heroku API documentation and I didn't see a method for 'heroku run', as in

 $ heroku run rake db:migrate

How would you do this via the API?

thanks!
nate

@wuputah

This comment has been minimized.

Copy link
Contributor

wuputah commented Jul 24, 2013

cc/ @geemus

@geemus

This comment has been minimized.

Copy link
Member

geemus commented Jul 24, 2013

@nbuggia - you can find all the details of doing this here: https://devcenter.heroku.com/articles/platform-api-reference#dyno-create. There is a also a concrete example of running rake db:migrate and using the rendezvous gem to stream the response here: https://github.com/swanson/stringer/blob/master/Rakefile#L106. Hope that helps, but do let me know if you have further questions.

@nbuggia

This comment has been minimized.

Copy link

nbuggia commented Aug 2, 2013

Thanks geemus!

@trevor

This comment has been minimized.

Copy link

trevor commented Nov 14, 2013

for google results re: "is not part of the bundle. Add it to Gemfile."

Shelling out
Any Ruby code that opens a subshell (like system, backticks, or %x{}) will automatically use the current Bundler
environment. If you need to shell out to a Ruby command that is not part of your current bundle, use the
with_clean_env method with a block. Any subshells created inside the block will be given the environment present
before Bundler was activated. For example, Homebrew commands run Ruby, but don't work inside a bundle:
Bundler.with_clean_env do
  `brew install wget`
end

-- http://bundler.io/v1.3/man/bundle-exec.1.html

@Workman

This comment has been minimized.

Copy link

Workman commented May 7, 2014

@trevor's answer was especially helpful for my implementation. Thanks!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.