Open postmodern opened 4 years ago
It would mean a new env var (GEM_USER_DIR?), adding and removing it from PATH.
I'm not sure it's worth the trouble and it seems nobody cared so far, so probably this flag is almost never used. I detailed that a bit more in https://github.com/postmodern/chruby/pull/431#issuecomment-612017314
There is also the IMHO significant issue that supporting --user-install
means we might again mix gem directories for different Rubies, which can lead to many unpleasant consequences (warnings from RubyGems and segfaults in some configurations), and would undo the "This guarantees a unique GEM_HOME
/gem directories per installed Ruby" guarantee added in https://github.com/postmodern/chruby/pull/419
Considering that, and that I think no user asked for this in such a long time, I would prefer to not support --user-install
, as it could cause more harm than help, and there is no reason (AFAIK) to use --user-install
which chruby, it's unnecessary and dangerous/annoying (sharing gems from multiple Rubies in the same dir).
Since Gem.user_dir is derived from ruby_engine
and RbConfig::CONFIG['ruby_version']
, we'd just need to add a RUBY_API_VERSION
/RUBY_ENGINE_VERSION
env variable to track the API version level. Then we could derive the string and add/remove it from both PATH
and GEM_PATH
.
I am leaning more towards supporting both the per-ruby (i.e. ruby-2.6.1) GEM_HOME
and a fallback per-ruby-API-version (i.e. 2.6.0) "User Installation Directory". This would allow gem install --user-install
to behave normally, and allow sharing some gems between patch-releases of rubies. Of course there are some issues with sharing gems between rubies (C extensions and explicit bin
#!
), however those can be worked around by running gem pristin
, or simply just choosing not to use gem install --user-install
if you don't want to risk it.
Yeah, it's true the risk should be limited to people using --user-install
.
I would call Gem.user_dir
though, there is no guarantee the path will not change in future RubyGems versions.
There is also a non-trivial interaction with GEM_HOME/GEM_PATH
, so Gem.user_dir + "/bin"
should be only added to PATH if GEM_PATH is not set, to avoid duplicate entries in PATH.
Actually, that's more complicated than I thought, even GEM_HOME/GEM_PATH don't change the USER INSTALLATION DIRECTORY
, which in such a case is not even part of Gem.path
and so won't be found by require
!
$ GEM_HOME=a GEM_PATH=a gem env
...
- USER INSTALLATION DIRECTORY: /home/eregon/.gem/ruby/2.6.0
...
- GEM PATHS:
- a
- GEM CONFIGURATION:
...
$ GEM_HOME=a GEM_PATH=a ruby -e 'p Gem.path'
["/pwd/a"]
$ GEM_HOME=a GEM_PATH=a gem i --user-install path
Fetching path-2.0.1.gem
WARNING: You don't have /home/eregon/.gem/ruby/2.6.0/bin in your PATH,
gem executables will not run.
Successfully installed path-2.0.1
1 gem installed
$ GEM_HOME=a GEM_PATH=a ruby -e 'require "path"'
Traceback (most recent call last):
2: from -e:1:in `<main>'
1: from /.../rubygems/core_ext/kernel_require.rb:54:in `require'
/.../rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such file -- path (LoadError)
Which makes me think --user-install
is so brittle and such a hack that it doesn't seem worth supporting.
@eregon Good call on pulling out the value of Gem.user_dir
. The shell's hash
function takes care of duplicate PATH
entries. Also, you need to add Gem.user_dir
to GEM_PATH
in order to require
the installed gems.
Hmm I might push this back to post-1.0. Since chruby currently uses ~/.gem/$ruby_engine/X.Y.Z
as the GEM_HOME
, there's a possibility that a Gem.user_dir
may overlap with a previous GEM_HOME
.
That makes sense to me, indeed chruby gems could mix with --user-install
gems of Ruby 2.x.0 and nobody wants to debug that.
I think --user-install
should be supported based on user demand. If nobody requested it since chruby exists then it seems nobody needs it. There are/will be probably more ways to configure RubyGems in weird ways, I'm not sure it's worth supporting them.
When a user installs a gem with
gem install --user-install
it installs the gem into the Gem.user_dir path (ex:~/.gem/$RUBY_ENGINE/$RUBY_API_VERSION
). chruby should probably support the "user installation directory", in order to prevent--user-install
ed gems from simply disappearing.Simplest way to support
--user-install
is to add/remote the "user installation directory" to both$GEM_PATH
and$PATH
, in addition to the rubygems "gem root".