postmodern/chgems

Running 'chgems' resets the ruby version set by 'chruby'

Closed this issue · 17 comments

kgrz commented

(In my home directory & chgems executable installed by cloning the git repo)

$ mkdir test
$ cd test
$ ruby -v   # => ruby 1.8.7
$ chruby 2.0
$ ruby -v   # => ruby 2.0.0-p247
$ chgems
# Entering /Users/<username>/Documents/github_clones/codetriage with gems in .gem/ruby/2.0.0/ ...
$ ruby -v # => ruby 1.8.7
$ gem env
# RubyGems Environment:
#  - RUBYGEMS VERSION: 1.3.6
#  - RUBY VERSION: 1.8.7 (2012-02-08 patchlevel 358) [universal-darwin12.0]
#  - INSTALLATION DIRECTORY: /Users/<username>/test/.gem/ruby/2.0.0
#  - RUBY EXECUTABLE: /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
#  - EXECUTABLE DIRECTORY: /Users/<username>/test/.gem/ruby/2.0.0/bin
#  - RUBYGEMS PLATFORMS:
#    - ruby
#    - universal-darwin-12
#  - GEM PATHS:
#     - /Users/<username>/test/.gem/ruby/2.0.0
#     - /Users/<username>/.gem/ruby/2.0.0
#     - /Users/<username>/.rubies/ruby-2.0.0-p247/lib/ruby/gems/2.0.0
#  - GEM CONFIGURATION:
#     - :update_sources => true
#     - :verbose => true
#     - :benchmark => false
#     - :backtrace => false
#     - :bulk_threshold => 1000
#     - "gem" => "--no-rdoc"
#  - REMOTE SOURCES:
#     - http://rubygems.org/

As an extension, if I set the default ruby in my shell profile, the gem_path doesn't get set at all. So, if I add the line chruby 2.0 to my zshrc, this is the behaviour:

$ mkdir test
$ cd test
$ ruby -v   # ruby 2.0.0-p247
$ chgems
# Entering /Users/<username>/Documents/github_clones/codetriage with gems in .gem/ruby/2.0.0/ ...
$ ruby -v   # ruby 2.0.0-p247
$ gem env
# RubyGems Environment:
#  - RUBYGEMS VERSION: 2.0.3
#  - RUBY VERSION: 2.0.0 (2013-06-27 patchlevel 247) [x86_64-darwin12.4.0]
#  - INSTALLATION DIRECTORY: /Users/<username>/.gem/ruby/2.0.0
#  - RUBY EXECUTABLE: /Users/<username>/.rubies/ruby-2.0.0-p247/bin/ruby
#  - EXECUTABLE DIRECTORY: /Users/<username>/.gem/ruby/2.0.0/bin
#  - RUBYGEMS PLATFORMS:
#    - ruby
#    - x86_64-darwin-12
#  - GEM PATHS:
#     - /Users/<username>/.gem/ruby/2.0.0
#     - /Users/<username>/.rubies/ruby-2.0.0-p247/lib/ruby/gems/2.0.0
#  - GEM CONFIGURATION:
#     - :update_sources => true
#     - :verbose => true
#     - :backtrace => false
#     - :bulk_threshold => 1000
#     - "gem" => "--no-rdoc"
#  - REMOTE SOURCES:
#     - https://rubygems.org/

You might want to set the default ruby in ~/.zprofile, so it only get's ran for login-shells. This would prevent it setting the default ruby when other sub-shells are spawned.

kgrz commented

That did work. However, when I run chgems, the ruby version gets changed to 1.8.7 and when I run chruby after that, it gets changed to ruby 2.0 but the gem env also changes (first image in the first comment)

I'm seeing the same behavior:

failbowl% ruby -v
ruby 1.8.7 (2012-02-08 patchlevel 358) [universal-darwin11.0]
failbowl% chruby 2.1.0
failbowl% ruby -v
ruby 2.1.0p0 (2013-12-25 revision 44422) [x86_64-darwin11.0]
failbowl% chgems .
Entering /Users/grb/proj/investment with gems in .gem/ruby/2.1.0/ ...
failbowl% ruby -v
ruby 1.8.7 (2012-02-08 patchlevel 358) [universal-darwin11.0]

My .zshrc contains two lines: one to add Homebrew to $PATH, and the chruby.sh line; no auto.sh or anything else. If I chgems, it resets the Ruby version to system. If I chruby, it resets the gem environment.

I thought that it might be related to zsh version (I was running 4.3.11, which ships with OS X Lion). I upgraded to 5.0.5 and got the same result. I also get the same result with bash 4.2.42, again with a minimal .bashrc.

Could you paste your .zshrc, $PATH and which ruby?

@garybernhardt This is just wild speculation, but I suspect somewhere in your zsh configuration $PATH is being reset or the homebrew path is being prepended, thus overriding chruby's changes.

Shell session with all of that stuff (hopefully exhaustively):

failbowl% cat ~/.zshrc
export PATH=/usr/local/sbin:/usr/local/bin:${PATH}
source /usr/local/share/chruby/chruby.sh
failbowl% cd proj/investment
failbowl% echo $PATH; which ruby; ruby -v
/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin:/usr/texbin
/usr/bin/ruby
ruby 1.8.7 (2012-02-08 patchlevel 358) [universal-darwin11.0]
failbowl% chruby 2.1.0
failbowl% echo $PATH; which ruby; ruby -v
/Users/grb/.gem/ruby/2.1.0/bin:/Users/grb/.rubies/ruby-2.1.0/lib/ruby/gems/2.1.0/bin:/Users/grb/.rubies/ruby-2.1.0/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin:/usr/texbin
/Users/grb/.rubies/ruby-2.1.0/bin/ruby
ruby 2.1.0p0 (2013-12-25 revision 44422) [x86_64-darwin11.0]
failbowl% chgems .
Entering /Users/grb/proj/investment with gems in .gem/ruby/2.1.0/ ...
failbowl% echo $PATH; which ruby; ruby -v
/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin:/usr/texbin:/Users/grb/proj/investment/.gem/ruby/2.1.0/bin:/Users/grb/.gem/ruby/2.1.0/bin:/Users/grb/.rubies/ruby-2.1.0/lib/ruby/gems/2.1.0/bin:/Users/grb/.rubies/ruby-2.1.0/bin:/usr/local/sbin
/usr/bin/ruby
ruby 1.8.7 (2012-02-08 patchlevel 358) [universal-darwin11.0]```

@garybernhardt just as I suspected, when chgems spawns the sub-shell, the zsh configuration prepends all directories onto the path, overriding /Users/grb/proj/investment/.gem/ruby/2.1.0/bin:/Users/grb/.gem/ruby/2.1.0/bin:/Users/grb/.rubies/ruby-2.1.0/lib/ruby/gems/2.1.0/bin:/Users/grb/.rubies/ruby-2.1.0/bin.

Also, it appears /usr/local/bin is already in your $PATH, but is after /usr/bin. Normally /usr/local/bin is supposed to take precedence over over /usr/bin. I wonder if this is an artifact of zsh's built-in configuration.

/usr/local/bin is actually in there twice: once from someone's (zsh's?) default configuration, and again from my .zshrc explicitly putting it at the front, so I think that part's OK, although it's weird.

I'm not sure why zsh is prepending all of the directories, though. That's very strange. What shell are you using, @postmodern? Bash?

@garybernhardt bash 4 on Fedora. In bash's system configuration, it actually checks if PATH is already set and skips populating it. Not sure if that behavior was added by Fedora or from upstream.

@garybernhardt I cannot reproduce this on Fedora 19 with bash 4.2 or zsh 5.0:

bash

$ which ruby
/usr/bin/ruby
$ ruby -v
ruby 2.0.0p353 (2013-11-22 revision 43784) [x86_64-linux]
$ chruby 1.9
$ which ruby
/opt/rubies/ruby-1.9.3-p484/bin/ruby
$ ruby -v
ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-linux]
$ chgems project/
Entering /home/hal/project with gems in .gem/ruby/1.9.3/ ...
$ which ruby
/opt/rubies/ruby-1.9.3-p484/bin/ruby
$ ruby -v
ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-linux]

zsh

% which ruby 
/usr/bin/ruby
% ruby -v
ruby 2.0.0p353 (2013-11-22 revision 43784) [x86_64-linux]
% chruby 1.9
% which ruby
/opt/rubies/ruby-1.9.3-p484/bin/ruby
% ruby -v
ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-linux]
% chgems project/
Entering /home/hal/project with gems in .gem/ruby/1.9.3/ ...
% which ruby
/opt/rubies/ruby-1.9.3-p484/bin/ruby
% ruby -v
ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-linux]

@havenwood and myself suspect this bug is caused by how path_helper is called in /etc/zshenv, which populates $PATH using /etc/paths and /etc/paths.d.

Both /etc/profile and /etc/zshenv eval path_finder which sets PATH to colon-separated /etc/paths file content followed by /etc/paths.d/* file contents then exports PATH.

That does look tremendously suspicious. I actually glanced at zshenv before my first comment, but somehow didn't make the connection. I'll try to exorcise this badness tomorrow if no one beats me to it.

I confirm that it's path_finder, as invoked from zshenv. path_finder itself would be fine if it were invoked from zprofile. That's what Apple did for bash (it's invoked from /etc/profile, not /etc/bashrc). To make OS X behave correctly, it seems like the right thing is to sudo mv /etc/zshenv /etc/zprofile. I've done that with no ill effects so far.

So, what to do? Document the badness in the README? Try to find a hack to work around it? (I'm not sure what such a hack would possibly look like.)

I confirmed via Twitter followers that this is still a problem in OS X Mavericks.

Ah ha! I forgot about that known Mavericks bug. We probably should mention that Maverick's zsh is broken. However, since it's such a trivial mistake that affects much more than just chgems, we should report this to Apple.