postmodern / chruby

Changes the current Ruby
MIT License
2.85k stars 190 forks source link

Set GEM_HOME for non-root users when using system ruby #421

Closed postmodern closed 2 years ago

postmodern commented 4 years ago

Since RubyGems does not default to --user-install, it would be very useful for chruby to set GEM_HOME to ~/.gem (and update PATH accordingly) when a non-root user invokes chruby system. chruby reset or chruby clear should fully reset the environment.

postmodern commented 4 years ago

Alternatively we could add a chruby user command for this functionality.

todd-a-jacobs commented 2 years ago

This solves a different problem than the one I originally brought up in #462, but I think it solves a related problem that I have experienced myself, but rarely cared enough about because the system Ruby is always so far behind ruby-head. However, I agree that it makes a lot of sense to do this (why duplicate a copy of the system Ruby just to have a user-specific GEM_HOME?) but want to differentiate between the use cases they solve.

I very much like the idea of shadowing the system Ruby with a local GEM_HOME, although I'm not sure off the top of my head if rubygems can look in more than one location for gems, or what the negative consequences might be. For example, chruby system basically unsets all the GEM_ variables, so GEM_HOME, GEM_PATH, etc. would have to be modified anyway, assuming most of them offer PATH-like behavior. Even if they do, what happens if GEM_PATH=~/.gems:/System/Library/Templates/Data/Library/Ruby/Gems/2.6.0/gems/ finds a gem that matches but isn't compatible?

Maybe I simply don't understand enough about how the gem lookup process works. However, if I'm understanding it correctly, we might need to shadow the system gems by symlinking the current system gems into the user's home directory when initializing chruby in the shell each time. The macOS cp -c might be a good option for that on Darwin systems, too, granting CoW for the shadowed gems, although it would be much less portable across systems where ln -s is available.

postmodern commented 2 years ago

I very much like the idea of shadowing the system Ruby with a local GEMHOME, although I'm not sure off the top of my head if rubygems can look in more than one location for gems, or what the negative consequences might be. For example, chruby system basically unsets all the GEM variables, so GEM_HOME, GEM_PATH, etc. would have to be modified anyway, assuming most of them offer PATH-like behavior. Even if they do, what happens if GEM_PATH=~/.gems:/System/Library/Templates/Data/Library/Ruby/Gems/2.6.0/gems/ finds a gem that matches but isn't compatible?

RubyGems should sequentially search GEM_PATH directories until it find a matching gem. If we change chruby system to also set GEM_HOME and GEM_PATH, this might require adding two different names for system without GEM_HOME and with GEM_HOME (chruby user?). Maybe we could also allow overriding the system with GEM_HOME ruby to act as the desired default ruby in #462? (Ex: chruby --user ruby-X.Y.Z?)

eregon commented 2 years ago

I think there are two ways:

postmodern commented 2 years ago

I would prefer Option 1 becoming the defacto behavior of rubygems, but the maintainers of rubygems seem overly cautious about changing rubygems.

I agree setting GEM_HOME could break globally installed ruby scripts/apps that are meant to also be ran by normal users. I'll close this in favor of maintaining strict separation between system ruby and chruby's rubies.