Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rbenv-gemset v0.5.0 seems broken with rbenv+jruby #56

Closed
neovatar opened this issue Dec 15, 2013 · 21 comments
Closed

rbenv-gemset v0.5.0 seems broken with rbenv+jruby #56

neovatar opened this issue Dec 15, 2013 · 21 comments

Comments

@neovatar
Copy link

Steps to reproduce:

  • Install rbenv and rbenv-gemset
  • Install jruby: rbenv install jruby-1.7.9
  • Use jruby rbenv global jruby-1.7.9
  • Do ruby --version, it seems to hang
  • Do RBENV_DEBUG=true ruby --version, seems rbenv + rbenv-gemset is caught in an endless loop

Its works fine with rbenv-gemset v0.4.2

@jf
Copy link
Owner

jf commented Dec 15, 2013

thanks, @neovatar for the nice report! But shouldnt jruby be called as jruby? So u wouldnt do ruby --version - but jruby --version

@jf
Copy link
Owner

jf commented Dec 15, 2013

But if it's the case that for whatever reason, calling ruby --version with rbenv-gemset v0.5.0 seems to hang (which it shouldnt!), I will take a look at it. Give me some time, though. Will be busy for the next couple of days...

@neovatar
Copy link
Author

Calling it via jruby --version also hangs.

The Problem ist that the following line in rbenv-gemset/etc/rbenv.d/exec/gemset.bash

GEM_PATH="$GEM_PATH:$($(rbenv which gem) env gemdir)"

seems to trigger the whole plugin circle again (calling rbenv-gemset/etc/rbenv.d/which/gemset.bash then calling rbenv-gemset/etc/rbenv.d/exec/gemset.bash again). Unfortunately I know nothing about rbenv plugin developement, so I cannot tell why it happens with jruby, but not with native ruby. Probably the way the binaries are called via rbenv differs?

@neovatar
Copy link
Author

I think its a bug in ruby-build:

.rbenv/versions/2.0.0-p353/bin/gem starts with:

#!/home/tom/.rbenv/versions/2.0.0-p353/bin/ruby

but .rbenv/versions/jruby-1.7.9/bin/gem starts with:

#!/usr/bin/env jruby

this will trigger rbenv-gemsets plugin execution, resulting in an endless loop since rbenb-gemset also calls the gem command to get the gem environment.

Changing #!/usr/bin/env jruby to #!/home/tom/.rbenv/versions/jruby-1.7.9/bin/jruby fixed the endless loop.

And putting #!/usr/bin/env ruby instead of #!/home/tom/.rbenv/versions/2.0.0-p353/bin/ruby in .rbenv/versions/2.0.0-p353/bin/gem produced the endless loop with a binary ruby.

What would be the best way to proceed?

@neovatar
Copy link
Author

Ok, it seems the gem tool wrapper is not created by ruby-build or rbenv but by jruby/rubygems. Actually putting #!/usr/bin/env jruby works unless you use rbenv and rbenv-gemset because only then the hooks trigger the endless loop :(

Would it be ok for you to have a jruby specific fix in your plugin?

@jf
Copy link
Owner

jf commented Dec 15, 2013

Thanks for the hard work, @neovatar ! It's always good to see somebody putting in the effort. Let me get back to you on this? I'll see what can be done.

@neovatar
Copy link
Author

I think its a little bit ugly, but it works. Maybe you can come up with something more elegant - its bedtime for me now ;)

@jf jf closed this as completed in 62791cd Dec 16, 2013
@jf
Copy link
Owner

jf commented Dec 16, 2013

thanks, @neovatar . I like your approach. Definitely going down the right path here, but yeah as u say, not so clean... You can check the latest commit for what I deem to be a better approach. You definitely pointed me down the right path, and saved a lot of time for me. Thanks!

@neovatar
Copy link
Author

Thanks for the fix! I still think ruby-build should patch the shebangs in gem and jgem, maybe I'll open a ticket.

@jf
Copy link
Owner

jf commented Dec 16, 2013

hey sorry, hang on there. I might have been too hasty there. I need to correct that patch! But yeah, definitely open the tickets with jruby, thanks!

@neovatar
Copy link
Author

Just had a quick check of your fix, you're right, it does not work right. I do not have time to test it thoroughly before tonight. Seems some basically installed gems are missing with that method.

Maybe create a branch for this fix until we are sure it works?

@neovatar
Copy link
Author

Ah, you are mssing paths because you use Gem.path.first, maybe try the following code, worked for me:

 set +e
 WHICH_RUBY=$(rbenv which ruby 2>/dev/null)
 set -e
 if [[ "$WHICH_RUBY" != "" ]]; then
   GEM_PATH="$GEM_PATH:$("$WHICH_RUBY" -e 'print Gem.path.join(":")')"
 else
   GEM_PATH="$GEM_PATH:$("$(rbenv which jruby)" -e 'print Gem.path.join(":")')"
 fi

@jf
Copy link
Owner

jf commented Dec 16, 2013

no... that's too much. I've checked in the fix already.

@neovatar
Copy link
Author

Sorry but this does not work. You can also call jruby as ruby, in that case your code does not detect jruby is used, thus going in an endless loop again :(

The reason that jruby can be called as ruby is, that you can run script that have a shebang like #!/usr/bin/env ruby line. This is default rbenv behaviour.

Even if my first fix is ugly, it detects jruby usage, even if jruby is called via ruby. You may want to consider it again :)

@jf
Copy link
Owner

jf commented Dec 16, 2013

How are you installing your jruby? I dont have this setup where I can call jruby as ruby. I'm not aware that this would be how it normally works. I'm opening to listening if this is the way that most people end up installing it (in which case it's still easy to change the code and yet still be relative elegant).

@neovatar
Copy link
Author

@jf
Copy link
Owner

jf commented Dec 16, 2013

duh, ok! It is mentioned in the docs, I'll grant you that.

I really dont like "let's bundle everything" approaches (ie., using everything in Gem.path). Can you see if the latest commit works for you? I've fixed things by simply swopping the order around. So check for a jruby specifically first. And then fall back to the standard ruby! Far better, wouldnt u say, than simply looking at the output of rbenv version? Now if these guys are going to have installs where they want to be able to call NON-jruby rubies with jruby.... well. They can go to .

If by "first fix" u mean faceebb, I'd say it's not foolproof. I dont want to have to rely on somebody naming their ruby version with "jruby". Even a "JRUBY-xxx" would fail.

@jf
Copy link
Owner

jf commented Dec 16, 2013

Thanks for really helping out, and participating in this issue, btw!

@neovatar
Copy link
Author

Awww, thanks to you for maintainig the plugin :)

Youre right, my suggestion was not foolproof. You last code works, but still seems a bit complicated to me. But I can live with it ;)

I would suggest:

 if [[ "$($(rbenv which ruby) --version)" =~ 'jruby' ]]; then
   GEM_PATH="$GEM_PATH:$($(rbenv which ruby) $(rbenv which gem) env gemdir)"
 else  
   GEM_PATH="$GEM_PATH:$($(rbenv which gem) env gemdir)"
 fi

What do you think? It uses the output of the called ruby to check if it is jruby. That would rule out the academic corner case that is still left open with your last code.

@jf
Copy link
Owner

jf commented Dec 16, 2013

I dont know.... That corner case is practically only theoretical. And if somebody really chooses to do it that way (OR somebody else has written code that ended up on this machine that caused it to be this way!), methinks they should be punished... :}

I do like how your suggestion is immediately more intuitively readable; but I dont exactly want to do one more call ("--version") if I can help it. So at least for the moment, I will pass on this... Nice code, though! (Just as a note - I would do rbenv which jruby in the 2nd line. EDIT: ok, maybe it's not really necessary.... but I think it would be more readable and yet still safe to do so).

@neovatar
Copy link
Author

I agree with you and I will have a look at ruby-build tonight, maybe its possible to replace the shebangs with correct rbenv ones (like in the cruby version).

mislav pushed a commit to rbenv/ruby-build that referenced this issue Dec 20, 2013
…benv

The default shebang for binstubs in a JRuby installation is
`#!/usr/bin/env jruby`. On a rbenv-managed JRuby, this will execute the
`jruby` rbenv shim. In a situation where a JRuby tool like `gem` is
executed from within a running rbenv by a rbenv plugin, (e.g.
rbenv-gemset) this can trigger another rbenv run to resolve the shim.
This can lead to endless recursion of rbenv calls.

Fixes #471, closes #473
References jf/rbenv-gemset#56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants