summaryrefslogtreecommitdiff
path: root/ruby_2_2/lib/rubygems/installer.rb
diff options
context:
space:
mode:
Diffstat (limited to 'ruby_2_2/lib/rubygems/installer.rb')
-rw-r--r--ruby_2_2/lib/rubygems/installer.rb826
1 files changed, 0 insertions, 826 deletions
diff --git a/ruby_2_2/lib/rubygems/installer.rb b/ruby_2_2/lib/rubygems/installer.rb
deleted file mode 100644
index a27569fe2e..0000000000
--- a/ruby_2_2/lib/rubygems/installer.rb
+++ /dev/null
@@ -1,826 +0,0 @@
-#--
-# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
-# All rights reserved.
-# See LICENSE.txt for permissions.
-#++
-
-require 'rubygems/command'
-require 'rubygems/exceptions'
-require 'rubygems/package'
-require 'rubygems/ext'
-require 'rubygems/user_interaction'
-require 'fileutils'
-
-##
-# The installer installs the files contained in the .gem into the Gem.home.
-#
-# Gem::Installer does the work of putting files in all the right places on the
-# filesystem including unpacking the gem into its gem dir, installing the
-# gemspec in the specifications dir, storing the cached gem in the cache dir,
-# and installing either wrappers or symlinks for executables.
-#
-# The installer invokes pre and post install hooks. Hooks can be added either
-# through a rubygems_plugin.rb file in an installed gem or via a
-# rubygems/defaults/#{RUBY_ENGINE}.rb or rubygems/defaults/operating_system.rb
-# file. See Gem.pre_install and Gem.post_install for details.
-
-class Gem::Installer
-
- ##
- # Paths where env(1) might live. Some systems are broken and have it in
- # /bin
-
- ENV_PATHS = %w[/usr/bin/env /bin/env]
-
- ##
- # Deprecated in favor of Gem::Ext::BuildError
-
- ExtensionBuildError = Gem::Ext::BuildError # :nodoc:
-
- include Gem::UserInteraction
-
- ##
- # Filename of the gem being installed.
-
- attr_reader :gem
-
- ##
- # The directory a gem's executables will be installed into
-
- attr_reader :bin_dir
-
- attr_reader :build_root # :nodoc:
-
- ##
- # The gem repository the gem will be installed into
-
- attr_reader :gem_home
-
- ##
- # The options passed when the Gem::Installer was instantiated.
-
- attr_reader :options
-
- ##
- # Sets the specification for .gem-less installs.
-
- attr_writer :spec
-
- @path_warning = false
-
- @install_lock = Mutex.new
-
- class << self
-
- ##
- # True if we've warned about PATH not including Gem.bindir
-
- attr_accessor :path_warning
-
- ##
- # Certain aspects of the install process are not thread-safe. This lock is
- # used to allow multiple threads to install Gems at the same time.
-
- attr_reader :install_lock
-
- ##
- # Overrides the executable format.
- #
- # This is a sprintf format with a "%s" which will be replaced with the
- # executable name. It is based off the ruby executable name's difference
- # from "ruby".
-
- attr_writer :exec_format
-
- # Defaults to use Ruby's program prefix and suffix.
- def exec_format
- @exec_format ||= Gem.default_exec_format
- end
-
- end
-
- ##
- # Constructs an Installer instance that will install the gem located at
- # +gem+. +options+ is a Hash with the following keys:
- #
- # :bin_dir:: Where to put a bin wrapper if needed.
- # :development:: Whether or not development dependencies should be installed.
- # :env_shebang:: Use /usr/bin/env in bin wrappers.
- # :force:: Overrides all version checks and security policy checks, except
- # for a signed-gems-only policy.
- # :format_executable:: Format the executable the same as the Ruby executable.
- # If your Ruby is ruby18, foo_exec will be installed as
- # foo_exec18.
- # :ignore_dependencies:: Don't raise if a dependency is missing.
- # :install_dir:: The directory to install the gem into.
- # :security_policy:: Use the specified security policy. See Gem::Security
- # :user_install:: Indicate that the gem should be unpacked into the users
- # personal gem directory.
- # :only_install_dir:: Only validate dependencies against what is in the
- # install_dir
- # :wrappers:: Install wrappers if true, symlinks if false.
- # :build_args:: An Array of arguments to pass to the extension builder
- # process. If not set, then Gem::Command.build_args is used
-
- def initialize(gem, options={})
- require 'fileutils'
-
- @gem = gem
- @options = options
- @package = Gem::Package.new @gem
-
- process_options
-
- @package.security_policy = @security_policy
-
- if options[:user_install] and not options[:unpack] then
- @gem_home = Gem.user_dir
- @bin_dir = Gem.bindir gem_home unless options[:bin_dir]
- check_that_user_bin_dir_is_in_path
- end
- end
-
- ##
- # Checks if +filename+ exists in +@bin_dir+.
- #
- # If +@force+ is set +filename+ is overwritten.
- #
- # If +filename+ exists and is a RubyGems wrapper for different gem the user
- # is consulted.
- #
- # If +filename+ exists and +@bin_dir+ is Gem.default_bindir (/usr/local) the
- # user is consulted.
- #
- # Otherwise +filename+ is overwritten.
-
- def check_executable_overwrite filename # :nodoc:
- return if @force
-
- generated_bin = File.join @bin_dir, formatted_program_filename(filename)
-
- return unless File.exist? generated_bin
-
- ruby_executable = false
- existing = nil
-
- open generated_bin, 'rb' do |io|
- next unless io.gets =~ /^#!/ # shebang
- io.gets # blankline
-
- # TODO detect a specially formatted comment instead of trying
- # to run a regexp against Ruby code.
- next unless io.gets =~ /This file was generated by RubyGems/
-
- ruby_executable = true
- existing = io.read.slice(/^gem (['"])(.*?)(\1),/, 2)
- end
-
- return if spec.name == existing
-
- # somebody has written to RubyGems' directory, overwrite, too bad
- return if Gem.default_bindir != @bin_dir and not ruby_executable
-
- question = "#{spec.name}'s executable \"#{filename}\" conflicts with "
-
- if ruby_executable then
- question << existing
-
- return if ask_yes_no "#{question}\nOverwrite the executable?", false
-
- conflict = "installed executable from #{existing}"
- else
- question << generated_bin
-
- return if ask_yes_no "#{question}\nOverwrite the executable?", false
-
- conflict = generated_bin
- end
-
- raise Gem::InstallError,
- "\"#{filename}\" from #{spec.name} conflicts with #{conflict}"
- end
-
- ##
- # Lazy accessor for the spec's gem directory.
-
- def gem_dir
- @gem_dir ||= File.join(gem_home, "gems", spec.full_name)
- end
-
- ##
- # Lazy accessor for the installer's spec.
-
- def spec
- @spec ||= @package.spec
- rescue Gem::Package::Error => e
- raise Gem::InstallError, "invalid gem: #{e.message}"
- end
-
- ##
- # Installs the gem and returns a loaded Gem::Specification for the installed
- # gem.
- #
- # The gem will be installed with the following structure:
- #
- # @gem_home/
- # cache/<gem-version>.gem #=> a cached copy of the installed gem
- # gems/<gem-version>/... #=> extracted files
- # specifications/<gem-version>.gemspec #=> the Gem::Specification
-
- def install
- pre_install_checks
-
- FileUtils.rm_f File.join gem_home, 'specifications', @spec.spec_name
-
- run_pre_install_hooks
-
- # Completely remove any previous gem files
- FileUtils.rm_rf gem_dir
-
- FileUtils.mkdir_p gem_dir
-
- spec.loaded_from = spec_file
-
- if @options[:install_as_default]
- extract_bin
- write_default_spec
- else
- extract_files
-
- build_extensions
- write_build_info_file
- run_post_build_hooks
-
- generate_bin
- write_spec
- write_cache_file
- end
-
- say spec.post_install_message unless spec.post_install_message.nil?
-
- Gem::Installer.install_lock.synchronize { Gem::Specification.add_spec spec }
-
- 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}"
- end
-
- def run_pre_install_hooks # :nodoc:
- Gem.pre_install_hooks.each do |hook|
- if hook.call(self) == false then
- location = " at #{$1}" if hook.inspect =~ /@(.*:\d+)/
-
- message = "pre-install hook#{location} failed for #{spec.full_name}"
- raise Gem::InstallError, message
- end
- end
- end
-
- def run_post_build_hooks # :nodoc:
- Gem.post_build_hooks.each do |hook|
- if hook.call(self) == false then
- FileUtils.rm_rf gem_dir
-
- location = " at #{$1}" if hook.inspect =~ /@(.*:\d+)/
-
- message = "post-build hook#{location} failed for #{spec.full_name}"
- raise Gem::InstallError, message
- end
- end
- end
-
- def run_post_install_hooks # :nodoc:
- Gem.post_install_hooks.each do |hook|
- hook.call self
- end
- end
-
- ##
- #
- # Return an Array of Specifications contained within the gem_home
- # we'll be installing into.
-
- def installed_specs
- @specs ||= begin
- specs = []
-
- Dir[File.join(gem_home, "specifications", "*.gemspec")].each do |path|
- spec = Gem::Specification.load path.untaint
- specs << spec if spec
- end
-
- specs
- end
- end
-
- ##
- # Ensure that the dependency is satisfied by the current installation of
- # gem. If it is not an exception is raised.
- #
- # spec :: Gem::Specification
- # dependency :: Gem::Dependency
-
- def ensure_dependency(spec, dependency)
- unless installation_satisfies_dependency? dependency then
- raise Gem::InstallError, "#{spec.name} requires #{dependency}"
- end
- true
- end
-
- ##
- # True if the gems in the system satisfy +dependency+.
-
- def installation_satisfies_dependency?(dependency)
- return true if @options[:development] and dependency.type == :development
- return true if installed_specs.detect { |s| dependency.matches_spec? s }
- return false if @only_install_dir
- not dependency.matching_specs.empty?
- end
-
- ##
- # Unpacks the gem into the given directory.
-
- def unpack(directory)
- @gem_dir = directory
- extract_files
- end
-
- ##
- # The location of of the spec file that is installed.
- #
-
- def spec_file
- File.join gem_home, "specifications", "#{spec.full_name}.gemspec"
- end
-
- ##
- # The location of of the default spec file for default gems.
- #
-
- def default_spec_file
- File.join gem_home, "specifications/default", "#{spec.full_name}.gemspec"
- end
-
- ##
- # Writes the .gemspec specification (in Ruby) to the gem home's
- # specifications directory.
-
- def write_spec
- open spec_file, 'w' do |file|
- spec.installed_by_version = Gem.rubygems_version
-
- file.puts spec.to_ruby_for_cache
-
- file.fsync rescue nil # for filesystems without fsync(2)
- end
- end
-
- ##
- # Writes the full .gemspec specification (in Ruby) to the gem home's
- # specifications/default directory.
-
- def write_default_spec
- File.open(default_spec_file, "w") do |file|
- file.puts spec.to_ruby
- end
- end
-
- ##
- # Creates windows .bat files for easy running of commands
-
- def generate_windows_script(filename, bindir)
- if Gem.win_platform? then
- script_name = filename + ".bat"
- script_path = File.join bindir, File.basename(script_name)
- File.open script_path, 'w' do |file|
- file.puts windows_stub_script(bindir, filename)
- end
-
- verbose script_path
- end
- end
-
- def generate_bin # :nodoc:
- return if spec.executables.nil? or spec.executables.empty?
-
- Dir.mkdir @bin_dir unless File.exist? @bin_dir
- raise Gem::FilePermissionError.new(@bin_dir) unless File.writable? @bin_dir
-
- spec.executables.each do |filename|
- filename.untaint
- bin_path = File.join gem_dir, spec.bindir, filename
-
- unless File.exist? bin_path then
- # TODO change this to a more useful warning
- warn "#{bin_path} maybe `gem pristine #{spec.name}` will fix it?"
- next
- end
-
- mode = File.stat(bin_path).mode
- FileUtils.chmod mode | 0111, bin_path unless (mode | 0111) == mode
-
- check_executable_overwrite filename
-
- if @wrappers then
- generate_bin_script filename, @bin_dir
- else
- generate_bin_symlink filename, @bin_dir
- end
-
- end
- end
-
- ##
- # Creates the scripts to run the applications in the gem.
- #--
- # The Windows script is generated in addition to the regular one due to a
- # bug or misfeature in the Windows shell's pipe. See
- # http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/193379
-
- def generate_bin_script(filename, bindir)
- bin_script_path = File.join bindir, formatted_program_filename(filename)
-
- FileUtils.rm_f bin_script_path # prior install may have been --no-wrappers
-
- File.open bin_script_path, 'wb', 0755 do |file|
- file.print app_script_text(filename)
- end
-
- verbose bin_script_path
-
- generate_windows_script filename, bindir
- end
-
- ##
- # Creates the symlinks to run the applications in the gem. Moves
- # the symlink if the gem being installed has a newer version.
-
- def generate_bin_symlink(filename, bindir)
- if Gem.win_platform? then
- alert_warning "Unable to use symlinks on Windows, installing wrapper"
- generate_bin_script filename, bindir
- return
- end
-
- src = File.join gem_dir, spec.bindir, filename
- dst = File.join bindir, formatted_program_filename(filename)
-
- if File.exist? dst then
- if File.symlink? dst then
- link = File.readlink(dst).split File::SEPARATOR
- cur_version = Gem::Version.create(link[-3].sub(/^.*-/, ''))
- return if spec.version < cur_version
- end
- File.unlink dst
- end
-
- FileUtils.symlink src, dst, :verbose => Gem.configuration.really_verbose
- end
-
- ##
- # Generates a #! line for +bin_file_name+'s wrapper copying arguments if
- # necessary.
- #
- # If the :custom_shebang config is set, then it is used as a template
- # for how to create the shebang used for to run a gem's executables.
- #
- # The template supports 4 expansions:
- #
- # $env the path to the unix env utility
- # $ruby the path to the currently running ruby interpreter
- # $exec the path to the gem's executable
- # $name the name of the gem the executable is for
- #
-
- def shebang(bin_file_name)
- ruby_name = RbConfig::CONFIG['ruby_install_name'] if @env_shebang
- path = File.join gem_dir, spec.bindir, bin_file_name
- first_line = File.open(path, "rb") {|file| file.gets}
-
- if /\A#!/ =~ first_line then
- # Preserve extra words on shebang line, like "-w". Thanks RPA.
- shebang = first_line.sub(/\A\#!.*?ruby\S*((\s+\S+)+)/, "#!#{Gem.ruby}")
- opts = $1
- shebang.strip! # Avoid nasty ^M issues.
- end
-
- if which = Gem.configuration[:custom_shebang]
- # replace bin_file_name with "ruby" to avoid endless loops
- which = which.gsub(/ #{bin_file_name}$/," #{RbConfig::CONFIG['ruby_install_name']}")
-
- which = which.gsub(/\$(\w+)/) do
- case $1
- when "env"
- @env_path ||= ENV_PATHS.find {|env_path| File.executable? env_path }
- when "ruby"
- "#{Gem.ruby}#{opts}"
- when "exec"
- bin_file_name
- when "name"
- spec.name
- end
- end
-
- "#!#{which}"
- elsif not ruby_name then
- "#!#{Gem.ruby}#{opts}"
- elsif opts then
- "#!/bin/sh\n'exec' #{ruby_name.dump} '-x' \"$0\" \"$@\"\n#{shebang}"
- else
- # Create a plain shebang line.
- @env_path ||= ENV_PATHS.find {|env_path| File.executable? env_path }
- "#!#{@env_path} #{ruby_name}"
- end
- end
-
- ##
- # Ensures the Gem::Specification written out for this gem is loadable upon
- # installation.
-
- def ensure_loadable_spec
- ruby = spec.to_ruby_for_cache
- ruby.untaint
-
- begin
- eval ruby
- rescue StandardError, SyntaxError => e
- raise Gem::InstallError,
- "The specification for #{spec.full_name} is corrupt (#{e.class})"
- end
- end
-
- def ensure_required_ruby_version_met # :nodoc:
- if rrv = spec.required_ruby_version then
- unless rrv.satisfied_by? Gem.ruby_version then
- raise Gem::InstallError, "#{spec.name} requires Ruby version #{rrv}."
- end
- end
- end
-
- def ensure_required_rubygems_version_met # :nodoc:
- if rrgv = spec.required_rubygems_version then
- unless rrgv.satisfied_by? Gem.rubygems_version then
- raise Gem::InstallError,
- "#{spec.name} requires RubyGems version #{rrgv}. " +
- "Try 'gem update --system' to update RubyGems itself."
- end
- end
- end
-
- def ensure_dependencies_met # :nodoc:
- deps = spec.runtime_dependencies
- deps |= spec.development_dependencies if @development
-
- deps.each do |dep_gem|
- ensure_dependency spec, dep_gem
- end
- end
-
- def process_options # :nodoc:
- @options = {
- :bin_dir => nil,
- :env_shebang => false,
- :force => false,
- :only_install_dir => false
- }.merge options
-
- @env_shebang = options[:env_shebang]
- @force = options[:force]
- @install_dir = options[:install_dir]
- @gem_home = options[:install_dir] || Gem.dir
- @ignore_dependencies = options[:ignore_dependencies]
- @format_executable = options[:format_executable]
- @security_policy = options[:security_policy]
- @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)
- @development = options[:development]
- @build_root = options[:build_root]
-
- @build_args = options[:build_args] || Gem::Command.build_args
-
- unless @build_root.nil?
- require 'pathname'
- @build_root = Pathname.new(@build_root).expand_path
- @bin_dir = File.join(@build_root, options[:bin_dir] || Gem.bindir(@gem_home))
- @gem_home = File.join(@build_root, @gem_home)
- alert_warning "You build with buildroot.\n Build root: #{@build_root}\n Bin dir: #{@bin_dir}\n Gem home: #{@gem_home}"
- end
- end
-
- def check_that_user_bin_dir_is_in_path # :nodoc:
- user_bin_dir = @bin_dir || Gem.bindir(gem_home)
- user_bin_dir = user_bin_dir.gsub(File::SEPARATOR, File::ALT_SEPARATOR) if
- File::ALT_SEPARATOR
-
- path = ENV['PATH']
- if Gem.win_platform? then
- path = path.downcase
- user_bin_dir = user_bin_dir.downcase
- end
-
- path = path.split(File::PATH_SEPARATOR)
-
- unless path.include? user_bin_dir then
- unless !Gem.win_platform? && (path.include? user_bin_dir.sub(ENV['HOME'], '~'))
- unless self.class.path_warning then
- alert_warning "You don't have #{user_bin_dir} in your PATH,\n\t gem executables will not run."
- self.class.path_warning = true
- end
- end
- end
- end
-
- def verify_gem_home(unpack = false) # :nodoc:
- FileUtils.mkdir_p gem_home
- raise Gem::FilePermissionError, gem_home unless
- unpack or File.writable?(gem_home)
- end
-
- def verify_spec_name
- return if spec.name =~ Gem::Specification::VALID_NAME_PATTERN
- raise Gem::InstallError, "#{spec} has an invalid name"
- end
-
- ##
- # Return the text for an application file.
-
- def app_script_text(bin_file_name)
- return <<-TEXT
-#{shebang bin_file_name}
-#
-# This file was generated by RubyGems.
-#
-# The application '#{spec.name}' is installed as part of a gem, and
-# this file is here to facilitate running it.
-#
-
-require 'rubygems'
-
-version = "#{Gem::Requirement.default}"
-
-if ARGV.first
- str = ARGV.first
- str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
- if str =~ /\\A_(.*)_\\z/ and Gem::Version.correct?($1) then
- version = $1
- ARGV.shift
- end
-end
-
-gem '#{spec.name}', version
-load Gem.bin_path('#{spec.name}', '#{bin_file_name}', version)
-TEXT
- end
-
- ##
- # return the stub script text used to launch the true Ruby script
-
- def windows_stub_script(bindir, bin_file_name)
- ruby = Gem.ruby.gsub(/^\"|\"$/, "").tr(File::SEPARATOR, "\\")
- return <<-TEXT
-@ECHO OFF
-IF NOT "%~f0" == "~f0" GOTO :WinNT
-@"#{ruby}" "#{File.join(bindir, bin_file_name)}" %1 %2 %3 %4 %5 %6 %7 %8 %9
-GOTO :EOF
-:WinNT
-@"#{ruby}" "%~dpn0" %*
-TEXT
- end
-
- ##
- # Builds extensions. Valid types of extensions are extconf.rb files,
- # configure scripts and rakefiles or mkrf_conf files.
-
- def build_extensions
- builder = Gem::Ext::Builder.new spec, @build_args
-
- builder.build_extensions
- end
-
- ##
- # Logs the build +output+ in +build_dir+, then raises Gem::Ext::BuildError.
- #
- # TODO: Delete this for RubyGems 3. It remains for API compatibility
-
- def extension_build_error(build_dir, output, backtrace = nil) # :nodoc:
- builder = Gem::Ext::Builder.new spec, @build_args
-
- builder.build_error build_dir, output, backtrace
- end
-
- ##
- # Reads the file index and extracts each file into the gem directory.
- #
- # Ensures that files can't be installed outside the gem directory.
-
- def extract_files
- @package.extract_files gem_dir
- end
-
- ##
- # Extracts only the bin/ files from the gem into the gem directory.
- # This is used by default gems to allow a gem-aware stub to function
- # without the full gem installed.
-
- def extract_bin
- @package.extract_files gem_dir, "bin/*"
- end
-
- ##
- # Prefix and suffix the program filename the same as ruby.
-
- def formatted_program_filename(filename)
- if @format_executable then
- self.class.exec_format % File.basename(filename)
- else
- filename
- end
- end
-
- ##
- #
- # Return the target directory where the gem is to be installed. This
- # directory is not guaranteed to be populated.
- #
-
- def dir
- gem_dir.to_s
- end
-
- ##
- # Performs various checks before installing the gem such as the install
- # repository is writable and its directories exist, required Ruby and
- # rubygems versions are met and that dependencies are installed.
- #
- # Version and dependency checks are skipped if this install is forced.
- #
- # The dependent check will be skipped this install is ignoring dependencies.
-
- def pre_install_checks
- verify_gem_home options[:unpack]
-
- # If we're forcing the install then disable security unless the security
- # policy says that we only install signed gems.
- @security_policy = nil if
- @force and @security_policy and not @security_policy.only_signed
-
- ensure_loadable_spec
-
- verify_spec_name
-
- if options[:install_as_default]
- Gem.ensure_default_gem_subdirectories gem_home
- else
- Gem.ensure_gem_subdirectories gem_home
- end
-
- return true if @force
-
- ensure_required_ruby_version_met
- ensure_required_rubygems_version_met
- ensure_dependencies_met unless @ignore_dependencies
-
- true
- end
-
- ##
- # Writes the file containing the arguments for building this gem's
- # extensions.
-
- def write_build_info_file
- return if @build_args.empty?
-
- build_info_dir = File.join gem_home, 'build_info'
-
- FileUtils.mkdir_p build_info_dir
-
- build_info_file = File.join build_info_dir, "#{spec.full_name}.info"
-
- open build_info_file, 'w' do |io|
- @build_args.each do |arg|
- io.puts arg
- end
- end
- end
-
- ##
- # Writes the .gem file to the cache directory
-
- def write_cache_file
- cache_file = File.join gem_home, 'cache', spec.file_name
-
- FileUtils.cp @gem, cache_file unless File.exist? cache_file
- end
-
-end
-