Skip to content

Commit

Permalink
Add Gem.default_install
Browse files Browse the repository at this point in the history
Most people don't install gems in the default directory, but in the
user's directory (--user-install), this can be configured by
distributions using /etc/gemrc, but that doesn't work for bundler since
it doesn't read gem configurations.

The default installation directory should be Gem.user_dir, not
Gem.default_dir, but changing this invariably would break backwards
compatibility.

Instead we can add another default directory which is where gems will be
installed to by default.

Gem.default_dir is where the system gems are installed to,
Gem.default_install is where the gems installed by the user are
installed to.

The method Gem.default_install can be overridden by distributions to
Gem.user_dir, therefore making all installations user installations by
default (essentially the same as --user-install).

This way both bundler and gem will install gems in the same directory by
default without users having to manually set GEM_HOME to volatile
locations such as $HOME/.local/share/gem/ruby/3.0.0.

All distributions need to do is turn this new behavior on.

If a user has sudo privileges, he/she can do --no-user-install to install
gems in the system directory (Gem.default_dir), which is the current
default behavior.

The current behavior remains unaffected: gems are still installed to
Gem.default_dir by default.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
  • Loading branch information
felipec committed Feb 27, 2023
1 parent 0f3d7db commit 68c0127
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 1 deletion.
7 changes: 7 additions & 0 deletions lib/rubygems/defaults.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ module Gem
@pre_uninstall_hooks ||= []
@pre_install_hooks ||= []

##
# Determines the default install directory

def self.default_install
@default_install ||= Gem.default_dir
end

##
# An Array of the default sources that come with RubyGems

Expand Down
2 changes: 1 addition & 1 deletion lib/rubygems/path_support.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class Gem::PathSupport
# hashtable, or defaults to ENV, the system environment.
#
def initialize(env)
@home = env["GEM_HOME"] || Gem.default_dir
@home = env["GEM_HOME"] || Gem.default_install

if File::ALT_SEPARATOR
@home = @home.gsub(File::ALT_SEPARATOR, File::SEPARATOR)
Expand Down
2 changes: 2 additions & 0 deletions test/rubygems/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ def setup
@orig_default_gem_home = RbConfig::CONFIG["default_gem_home"]
RbConfig::CONFIG["default_gem_home"] = @gemhome
else
Gem.instance_variable_set(:@default_install, @gemhome)
Gem.instance_variable_set(:@default_dir, @gemhome)
end

Expand Down Expand Up @@ -469,6 +470,7 @@ def teardown
if Gem.java_platform?
RbConfig::CONFIG["default_gem_home"] = @orig_default_gem_home
else
Gem.instance_variable_set :@default_install, nil
Gem.instance_variable_set :@default_dir, nil
end

Expand Down
16 changes: 16 additions & 0 deletions test/rubygems/test_rubygems.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,22 @@ def self.default_dir
end
end

def test_operating_system_customizing_default_install
path = util_install_operating_system_rb <<-RUBY
module Gem
def self.default_install
Gem.user_dir
end
end
RUBY

assert system(
*ruby_with_rubygems_and_fake_operating_system_in_load_path(path),
"-e",
"raise unless Gem.dir == Gem.user_dir"
)
end

private

def util_install_operating_system_rb(content)
Expand Down

0 comments on commit 68c0127

Please sign in to comment.