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_VERSION ignored when shelling out from ruby #121

Open
bronson opened this issue Oct 15, 2011 · 15 comments
Open

RBENV_VERSION ignored when shelling out from ruby #121

bronson opened this issue Oct 15, 2011 · 15 comments
Labels

Comments

@bronson
Copy link

bronson commented Oct 15, 2011

This shows that RBENV_VERSION works when executed from Perl but not from Ruby. In this example, global version is set to 1.9.2p290.

$ ruby --version
ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux]
$ perl -e 'system("RBENV_VERSION=system ruby -e \"puts RUBY_VERSION\"")'
1.8.7
$ ruby -e 'system("RBENV_VERSION=system ruby -e \"puts RUBY_VERSION\"")'
1.9.2

RBENV_VERSION should always work, shouldn't it?

bronson added a commit to bronson/rbenv that referenced this issue Oct 16, 2011
not sure if this still fixes issue rbenv#95 though.
@bronson
Copy link
Author

bronson commented Oct 16, 2011

That commit fixes this issue. Now I get the expected results:

$ ruby --version
ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux]
$ ruby -e 'system("RBENV_VERSION=system ruby -e \"puts RUBY_VERSION\"")'
1.8.7
$ rbenv shell system
$ ruby -e 'system("RBENV_VERSION=1.9.2-p290 ruby -e \"puts RUBY_VERSION\"")'
1.9.2

Is it good enough to be merged? Or does issue #95 require the bin path to come before the shim path?

I'd really like to find a good solution to this. Thanks!

@bronson
Copy link
Author

bronson commented Oct 23, 2011

I mean, does the rbenv -S issue mentioned in #95 (#95 (comment)) require the bin path to come before the shim path?

@bronson
Copy link
Author

bronson commented Nov 9, 2012

This is still an issue in 0.3.0.

@mislav
Copy link
Member

mislav commented Dec 13, 2012

Your problem is that, when calling your script from ruby, you have already gone through rbenv to reach the ruby. So, PATH is already set up.

However from ruby you're calling ruby again, and this time it never hits the rbenv shim… because PATH is already set up and ruby is available right there on the top, rbenv is skipped completely and you're locked into the same version of ruby which you first activated.

I don't know whether this is a bug, or how to solve it. It seems unsolvable from rbenv. If from a ruby process you want to shell out to rbenv, you would need to edit ENV['PATH'] first to restore it to the pristine state.

@sheerun
Copy link

sheerun commented Jan 25, 2013

Maybe rbenv should remove from PATH any paths that contain RBENV_ROOT before appending anything?

imho that's bug. nothing should prevent running other version of ruby from ruby script.

@mislav
Copy link
Member

mislav commented Jan 26, 2013

It's a common pitfall. You can clear the current env from a Ruby process like so:

rbenv_root = `rbenv root 2>/dev/null`.chomp

unless rbenv_root.empty?
  re = /^#{Regexp.escape rbenv_root}\/(versions|plugins|libexec)\b/
  paths = ENV["PATH"].split(":")
  paths.reject! {|p| p =~ re }
  ENV["PATH"] = paths.join(":")
end

@sheerun
Copy link

sheerun commented Jan 26, 2013

I think it should be rbenv responsibility, not ruby programmer.

@mislav
Copy link
Member

mislav commented Jan 26, 2013

True. I also don't think the above workaround is what users should be doing in the long run. However, that is what they need to do with the current version of rbenv (0.4).

You can also put this plugin in RBENV_ROOT/rbenv.d/exec/path_clean.bash:

# EXPERIMENTAL: clean up PATH of modifications made in rbenv.
# This DISABLES the feature added in 2a495dc for `ruby -S` compatibility.
path_without_rbenv() {
  local result=""
  local paths
  IFS=: paths=($PATH)

  for path in "${paths[@]}"; do
    if ! [[ "$path" =~ "${RBENV_ROOT}/versions/" || \
            "$path" =~ "${RBENV_ROOT}/plugins/"  || \
            "$path" == "${RBENV_ROOT}/libexec"   ]]; then
      result="${result}${path}:"
    fi
  done

  echo "${result%:}"
}

exec() {
  export PATH="$(path_without_rbenv)"
  builtin exec "$@"
}

@Sen
Copy link

Sen commented Mar 31, 2013

+1 for this
switch to jruby in script not work for me.
seems "global" ruby always there. how to unset global ruby? or is there any trick for this?

mislav added a commit that referenced this issue Apr 1, 2013
Enables shelling out from a ruby process started with rbenv to a rbenv
version other than the current one. Fixes #121

Current Ruby version is only prepended to PATH for `ruby -S`, per #14.
mislav added a commit that referenced this issue Apr 2, 2013
Enables shelling out from a ruby process started with rbenv to a rbenv
version other than the current one. Fixes #121

This removes the workaround created for #15 and solves `ruby -S` support
by setting RUBYPATH.
@mislav mislav closed this as completed in db143bb Oct 30, 2013
@aslakhellesoy
Copy link

\o/

@bronson
Copy link
Author

bronson commented Oct 30, 2013

This is huge. Kick ass, Mislav.

@trogdoro
Copy link

trogdoro commented Jan 7, 2014

I tried mutating the PATH so that it uses the 'ruby' shim, but rbenv still doesn't use the version from .ruby-version in the current dir:

Any ideas why?

The |... lines in this example represent the contents of files and output of shell commands.

/tmp/
  dir_with_ruby_1.8.7/
    .ruby-version
      | 1.8.7-p375

  invoke_ruby_with_popen3.rb
    | require 'open3'
    | output = Open3.popen3(
    |   {"PATH"=>"/Users/craig/.rbenv/shims:/usr/local/Cellar/rbenv/0.4.0/libexec:/usr/bin:/bin"},
    |   "ruby -v",
    |   :chdir=>"/tmp/dir_with_ruby_1.8.7"
    |   )
    | puts output[1].readlines.join('')

  $ ruby invoke_ruby_with_popen3.rb
    | /private/tmp/dir_with_ruby_1.8.7

@mislav
Copy link
Member

mislav commented Jan 7, 2014

@trogdoro Not sure what is happening, nor what's your use case. My general advice is to use which ruby to confirm that the call is really going to the rbenv ruby shim. Then check PWD and RBENV_DIR (if set) since those directories are where rbenv will search for .ruby-version. Also, remember that RBENV_VERSION if set has precedence over .ruby-version.

@trogdoro
Copy link

trogdoro commented Jan 7, 2014

Woops, forgot to blank out the RBENV_VERSION var. Adding "RBENV_VERSION"=>"" to the hash fixes it:

/tmp/
    - invoke_ruby_with_popen3.rb
      | require 'open3'
      | output = Open3.popen3(
      |   {"RBENV_VERSION"=>"", "PATH"=>"/Users/craig/.rbenv/shims:/usr/local/Cellar/rbenv/0.4.0/libexec:/usr/bin:/bin"},
      |   "ruby -v",
      |   :chdir=>"/tmp/dir_with_ruby_1.8.7"
      |   )
      | puts output[1].readlines.join('')

  $ ruby invoke_ruby_with_popen3.rb
    | ruby 1.8.7 (2013-12-22 patchlevel 375) [i686-darwin12.5.0]

Thanks!

cehoffman pushed a commit to cehoffman/rbenv that referenced this issue Apr 8, 2014
Enables shelling out from a ruby process started with rbenv to a ruby
process with a different RBENV_VERSION. Fixes rbenv#121

This removes the workaround created for rbenv#15 and solves `ruby -S` support
by setting RUBYPATH. PATH is never changed.

To illustrate how RUBYPATH changes in various configurations:

    PATH=~/bin:~/.rbenv/shims:/usr/bin:/bin
    RBENV_VERSION=1.8 ruby -S rake
    #=> executes ~/.rbenv/versions/1.8/bin/rake
    #=> RUBYPATH=~/bin:~/.rbenv/versions/1.8/bin:/usr/bin:/bin

    RBENV_VERSION=2.0 ruby -S rake
    #=> executes ~/.rbenv/versions/2.0/bin/rake
    #=> RUBYPATH=~/bin:~/.rbenv/versions/2.0/bin:/usr/bin:/bin

    RBENV_VERSION=system ruby -S rake
    #=> executes /usr/bin/rake
    #=> RUBYPATH=~/bin:/rbenv_shims_were_here:/usr/bin:/bin

    RBENV_VERSION=1.8 ruby -S rake
    #=> executes ~/.rbenv/versions/1.8/bin/rake
    #=> RUBYPATH=~/bin:~/.rbenv/versions/1.8/bin:/usr/bin:/bin
@mislav
Copy link
Member

mislav commented Sep 11, 2015

The fix of this was reverted in 95a039a so I'm reopening this.

@mislav mislav reopened this Sep 11, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants