installer.rb

来自「Amarok是一款在LINUX或其他类UNIX操作系统中运行的音频播放器软件。 」· RB 代码 · 共 614 行 · 第 1/2 页

RB
614
字号
#--# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.# All rights reserved.# See LICENSE.txt for permissions.#++$TESTING = false unless defined? $TESTINGrequire 'pathname'require 'rbconfig'require 'rubygems/format'require 'rubygems/dependency_list'module Gem  class DependencyRemovalException < Gem::Exception; end  ##  # The installer class processes RubyGem .gem files and installs the  # files contained in the .gem into the Gem.path.  #  class Installer    include UserInteraction      ##    # Constructs an Installer instance    #    # gem:: [String] The file name of the gem    #    def initialize(gem, options={})      @gem = gem      @options = options    end        ##    # Installs the gem in the Gem.path.  This will fail (unless    # force=true) if a Gem has a requirement on another Gem that is    # not installed.  The installation will install in the following    # structure:    #    #  Gem.path/    #      specifications/<gem-version>.gemspec #=> the extracted YAML gemspec    #      gems/<gem-version>/... #=> the extracted Gem files    #      cache/<gem-version>.gem #=> a cached copy of the installed Gem    #    # force:: [default = false] if false will fail if a required Gem is not installed,    #         or if the Ruby version is too low for the gem    # install_dir:: [default = Gem.dir] directory that Gem is to be installed in    #    # return:: [Gem::Specification] The specification for the newly installed Gem.    #    def install(force=false, install_dir=Gem.dir, ignore_this_parameter=false)      require 'fileutils'      # if we're forcing the install, then disable security, _unless_       # the security policy says that we only install singed gems      # (this includes Gem::Security::HighSecurity)      security_policy = @options[:security_policy]      security_policy = nil if force && security_policy && security_policy.only_signed != true            format = Gem::Format.from_file_by_path(@gem, security_policy)      unless force        spec = format.spec        # Check the Ruby version.        if (rrv = spec.required_ruby_version)          unless rrv.satisfied_by?(Gem::Version.new(RUBY_VERSION))            raise "#{spec.name} requires Ruby version #{rrv}"          end        end 	unless @options[:ignore_dependencies] 	  spec.dependencies.each do |dep_gem|	    ensure_dependency!(spec, dep_gem) 	  end 	end      end            raise Gem::FilePermissionError.new(install_dir) unless File.writable?(install_dir)      # Build spec dir.      @directory = File.join(install_dir, "gems", format.spec.full_name).untaint      FileUtils.mkdir_p @directory      extract_files(@directory, format)      generate_bin(format.spec, install_dir)      build_extensions(@directory, format.spec)            # Build spec/cache/doc dir.      build_support_directories(install_dir)            # Write the spec and cache files.      write_spec(format.spec, File.join(install_dir, "specifications"))      unless File.exist? File.join(install_dir, "cache", @gem.split(/\//).pop)        FileUtils.cp @gem, File.join(install_dir, "cache")      end      puts format.spec.post_install_message unless format.spec.post_install_message.nil?      format.spec.loaded_from = File.join(install_dir, 'specifications', format.spec.full_name+".gemspec")      return format.spec    end    ##    # Ensure that the dependency is satisfied by the current    # installation of gem.  If it is not, then fail (i.e. throw and    # exception).    #    # spec       :: Gem::Specification    # dependency :: Gem::Dependency    def ensure_dependency!(spec, dependency)      raise "#{spec.name} requires #{dependency.name} #{dependency.version_requirements} " unless	installation_satisfies_dependency?(dependency)    end    ##    # True if the current installed gems satisfy the given dependency.    #    # dependency :: Gem::Dependency    def installation_satisfies_dependency?(dependency)      current_index = SourceIndex.from_installed_gems      current_index.find_name(dependency.name, dependency.version_requirements).size > 0    end    ##    # Unpacks the gem into the given directory.    #    def unpack(directory)      format = Gem::Format.from_file_by_path(@gem, @options[:security_policy])      extract_files(directory, format)    end    ##    # Given a root gem directory, build supporting directories for gem    # if they do not already exist    def build_support_directories(install_dir)       unless File.exist? File.join(install_dir, "specifications")         FileUtils.mkdir_p File.join(install_dir, "specifications")       end       unless File.exist? File.join(install_dir, "cache")         FileUtils.mkdir_p File.join(install_dir, "cache")       end       unless File.exist? File.join(install_dir, "doc")         FileUtils.mkdir_p File.join(install_dir, "doc")       end    end        ##    # Writes the .gemspec specification (in Ruby) to the supplied    # spec_path.    #    # spec:: [Gem::Specification] The Gem specification to output    # spec_path:: [String] The location (path) to write the gemspec to    #    def write_spec(spec, spec_path)      rubycode = spec.to_ruby      file_name = File.join(spec_path, spec.full_name+".gemspec").untaint      File.open(file_name, "w") do |file|        file.puts rubycode      end    end    ##    # Creates windows .cmd files for easy running of commands    #    def generate_windows_script(bindir, filename)      if Config::CONFIG["arch"] =~ /dos|win32/i        script_name = filename + ".cmd"        File.open(File.join(bindir, File.basename(script_name)), "w") do |file|          file.puts "@#{Gem.ruby} \"#{File.join(bindir,filename)}\" %*"        end      end    end    ##    # Determines the directory for binaries    #    def bindir(install_dir=Gem.dir)      if(install_dir == Gem.default_dir)        # mac framework support        if defined? RUBY_FRAMEWORK_VERSION          File.join(File.dirname(Config::CONFIG["sitedir"]), File.basename(Config::CONFIG["bindir"]))        else # generic install          Config::CONFIG['bindir']        end      else        File.join(install_dir, "bin")      end    end    def generate_bin(spec, install_dir=Gem.dir)      return unless spec.executables && ! spec.executables.empty?            # 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 install_dir.      bindir = bindir(install_dir)      Dir.mkdir bindir unless File.exist? bindir      raise Gem::FilePermissionError.new(bindir) unless File.writable?(bindir)      spec.executables.each do |filename|        if @options[:wrappers] then          generate_bin_script spec, filename, bindir, install_dir        else          generate_bin_symlink spec, filename, bindir, install_dir        end      end    end    ##    # Creates the scripts to run the applications in the gem.    #    def generate_bin_script(spec, filename, bindir, install_dir)      File.open(File.join(bindir, File.basename(filename)), "w", 0755) do |file|        file.print app_script_text(spec, install_dir, filename)      end      generate_windows_script bindir, filename    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(spec, filename, bindir, install_dir)      if Config::CONFIG["arch"] =~ /dos|win32/i then        warn "Unable to use symlinks on win32, installing wrapper" unless $TESTING # HACK        generate_bin_script spec, filename, bindir, install_dir        return      end      src = File.join @directory, 'bin', filename      dst = File.join bindir, File.basename(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      File.symlink src, dst    end    def shebang(spec, install_dir, bin_file_name)      path = File.join(install_dir, "gems", spec.full_name, spec.bindir, bin_file_name)      File.open(path, "rb") do |file|        first_line = file.readlines("\n").first         path_to_ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])        if first_line =~ /^#!/          # Preserve extra words on shebang line, like "-w".  Thanks RPA.          shebang = first_line.sub(/\A\#!\s*\S*ruby\S*/, "#!" + path_to_ruby)        else          # Create a plain shebang line.          shebang = "#!" + path_to_ruby        end        return shebang.strip  # Avoid nasty ^M issues.      end    end    ##    # Returns the text for an application file.    #    def app_script_text(spec, install_dir, filename)      text = <<-TEXT#{shebang(spec, install_dir, filename)}## 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 = "> 0"if ARGV.size > 0 && ARGV[0][0]==95 && ARGV[0][-1]==95  if Gem::Version.correct?(ARGV[0][1..-2])    version = ARGV[0][1..-2]     ARGV.shift  endendrequire_gem '#{spec.name}', versionload '#{filename}'  TEXT      text    end    def build_extensions(directory, spec)      return unless spec.extensions.size > 0      say "Building native extensions.  This could take a while..."      start_dir = Dir.pwd      dest_path = File.join(directory, spec.require_paths[0])      results = []      spec.extensions.each do |extension|        case extension        when /extconf/ then          builder = ExtExtConfBuilder        when /configure/ then          builder = ExtConfigureBuilder        when /rakefile/i then          builder = ExtRakeBuilder        else          builder = nil          results = ["No builder for extension '#{extension}'"]

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?