diff options
Diffstat (limited to 'lib/rubygems/installer.rb')
-rw-r--r-- | lib/rubygems/installer.rb | 82 |
1 files changed, 49 insertions, 33 deletions
diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb index 162a50fdb7..844f292ba2 100644 --- a/lib/rubygems/installer.rb +++ b/lib/rubygems/installer.rb @@ -189,10 +189,12 @@ class Gem::Installer @package.prog_mode = options[:prog_mode] @package.data_mode = options[:data_mode] - if options[:user_install] - @gem_home = Gem.user_dir - @bin_dir = Gem.bindir gem_home unless options[:bin_dir] - @plugins_dir = Gem.plugindir(gem_home) + if @gem_home == Gem.user_dir + # If we get here, then one of the following likely happened: + # - `--user-install` was specified + # - `Gem::PathSupport#home` fell back to `Gem.user_dir` + # - GEM_HOME was manually set to `Gem.user_dir` + check_that_user_bin_dir_is_in_path end end @@ -222,10 +224,11 @@ class Gem::Installer File.open generated_bin, "rb" do |io| line = io.gets - shebang = /^#!.*ruby/ + shebang = /^#!.*ruby/o - if load_relative_enabled? - until line.nil? || line =~ shebang do + # TruffleRuby uses a bash prelude in default launchers + if load_relative_enabled? || RUBY_ENGINE == "truffleruby" + until line.nil? || shebang.match?(line) do line = io.gets end end @@ -236,7 +239,7 @@ class Gem::Installer # TODO: detect a specially formatted comment instead of trying # to find a string inside Ruby code. - next unless io.gets.to_s.include?("This file was generated by RubyGems") + next unless io.gets&.include?("This file was generated by RubyGems") ruby_executable = true existing = io.read.slice(/ @@ -316,7 +319,7 @@ class Gem::Installer FileUtils.rm_rf spec.extension_dir dir_mode = options[:dir_mode] - FileUtils.mkdir_p gem_dir, :mode => dir_mode && 0o755 + FileUtils.mkdir_p gem_dir, mode: dir_mode && 0o755 if @options[:install_as_default] extract_bin @@ -341,18 +344,16 @@ class Gem::Installer say spec.post_install_message if options[:post_install_message] && !spec.post_install_message.nil? - Gem::Specification.add_spec(spec) + Gem::Specification.add_spec(spec) unless @install_dir load_plugin run_post_install_hooks spec - - # TODO: This rescue is in the wrong place. What is raising this exception? - # move this rescue to around the code that actually might raise it. - rescue Zlib::GzipFile::Error - raise Gem::InstallError, "gzip error installing #{gem}" + rescue Errno::EACCES => e + # Permission denied - /path/to/foo + raise Gem::FilePermissionError, e.message.split(" - ").last end def run_pre_install_hooks # :nodoc: @@ -393,7 +394,7 @@ class Gem::Installer specs = [] Gem::Util.glob_files_in_dir("*.gemspec", File.join(gem_home, "specifications")).each do |path| - spec = Gem::Specification.load path.tap(&Gem::UNTAINT) + spec = Gem::Specification.load path specs << spec if spec end @@ -492,7 +493,6 @@ class Gem::Installer ensure_writable_dir @bin_dir spec.executables.each do |filename| - filename.tap(&Gem::UNTAINT) bin_path = File.join gem_dir, spec.bindir, filename next unless File.exist? bin_path @@ -569,7 +569,7 @@ class Gem::Installer File.unlink dst end - FileUtils.symlink src, dst, :verbose => Gem.configuration.really_verbose + FileUtils.symlink src, dst, verbose: Gem.configuration.really_verbose rescue NotImplementedError, SystemCallError alert_warning "Unable to use symlinks, installing wrapper" generate_bin_script filename, bindir @@ -634,7 +634,6 @@ class Gem::Installer def ensure_loadable_spec ruby = spec.to_ruby_for_cache - ruby.tap(&Gem::UNTAINT) begin eval ruby @@ -655,32 +654,37 @@ class Gem::Installer def process_options # :nodoc: @options = { - :bin_dir => nil, - :env_shebang => false, - :force => false, - :only_install_dir => false, - :post_install_message => true, + bin_dir: nil, + env_shebang: false, + force: false, + only_install_dir: false, + post_install_message: true, }.merge options @env_shebang = options[:env_shebang] @force = options[:force] @install_dir = options[:install_dir] - @gem_home = options[:install_dir] || Gem.dir - @plugins_dir = Gem.plugindir(@gem_home) + @user_install = options[:user_install] @ignore_dependencies = options[:ignore_dependencies] @format_executable = options[:format_executable] @wrappers = options[:wrappers] @only_install_dir = options[:only_install_dir] - # If the user has asked for the gem to be installed in a directory that is - # the system gem directory, then use the system bin directory, else create - # (or use) a new bin dir under the gem_home. - @bin_dir = options[:bin_dir] || Gem.bindir(gem_home) + @bin_dir = options[:bin_dir] @development = options[:development] @build_root = options[:build_root] @build_args = options[:build_args] + @gem_home = @install_dir || user_install_dir || Gem.dir + + # If the user has asked for the gem to be installed in a directory that is + # the system gem directory, then use the system bin directory, else create + # (or use) a new bin dir under the gem_home. + @bin_dir ||= Gem.bindir(@gem_home) + + @plugins_dir = Gem.plugindir(@gem_home) + unless @build_root.nil? @bin_dir = File.join(@build_root, @bin_dir.gsub(/^[a-zA-Z]:/, "")) @gem_home = File.join(@build_root, @gem_home.gsub(/^[a-zA-Z]:/, "")) @@ -714,8 +718,7 @@ class Gem::Installer end def verify_gem_home # :nodoc: - FileUtils.mkdir_p gem_home, :mode => options[:dir_mode] && 0o755 - raise Gem::FilePermissionError, gem_home unless File.writable?(gem_home) + FileUtils.mkdir_p gem_home, mode: options[:dir_mode] && 0o755 end def verify_spec @@ -936,7 +939,7 @@ TEXT build_info_dir = File.join gem_home, "build_info" dir_mode = options[:dir_mode] - FileUtils.mkdir_p build_info_dir, :mode => dir_mode && 0o755 + FileUtils.mkdir_p build_info_dir, mode: dir_mode && 0o755 build_info_file = File.join build_info_dir, "#{spec.full_name}.info" @@ -969,6 +972,19 @@ TEXT private + def user_install_dir + # never install to user home in --build-root mode + return unless @build_root.nil? + + # Please note that @user_install might have three states: + # * `true`: `--user-install` + # * `false`: `--no-user-install` and + # * `nil`: option was not specified + if @user_install || (@user_install.nil? && Gem.default_user_install) + Gem.user_dir + end + end + def build_args @build_args ||= begin require_relative "command" |