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 + -
显示快捷键?