Parent

Class Index [+]

Quicksearch

Gem::Installer

The installer class processes RubyGem .gem files and installs the files contained in the .gem into the Gem.path.

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.

Constants

ENV_PATHS

Paths where env(1) might live. Some systems are broken and have it in /bin

Attributes

gem_dir[W]

Available through requiring rubygems/installer_test_case

format[W]

Available through requiring rubygems/installer_test_case

gem_home[W]

Available through requiring rubygems/installer_test_case

env_shebang[W]

Available through requiring rubygems/installer_test_case

ignore_dependencies[W]

Available through requiring rubygems/installer_test_case

format_executable[W]

Available through requiring rubygems/installer_test_case

security_policy[W]

Available through requiring rubygems/installer_test_case

spec[W]

Available through requiring rubygems/installer_test_case

wrappers[W]

Available through requiring rubygems/installer_test_case

gem[R]
bin_dir[R]

The directory a gem’s executables will be installed into

gem_home[R]

The gem repository the gem will be installed into

options[R]

The options passed when the Gem::Installer was instantiated.

path_warning[RW]

True if we’ve warned about PATH not including Gem.bindir

exec_format[W]

Public Class Methods

exec_format() click to toggle source

Defaults to use Ruby’s program prefix and suffix.

    # File lib/rubygems/installer.rb, line 73
73:     def exec_format
74:       @exec_format ||= Gem.default_exec_format
75:     end
new(gem, options={}) click to toggle source

Constructs an Installer instance that will install the gem located at gem. options is a Hash with the following keys:

: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.

:ignore_dependencies

Don’t raise if a dependency is missing.

:install_dir

The directory to install the gem into.

:format_executable

Format the executable the same as the ruby executable. If your ruby is ruby18, foo_exec will be installed as foo_exec18.

:security_policy

Use the specified security policy. See Gem::Security

:wrappers

Install wrappers if true, symlinks if false.

     # File lib/rubygems/installer.rb, line 94
 94:   def initialize(gem, options={})
 95:     require 'fileutils'
 96: 
 97:     @gem = gem
 98:     @options = options
 99:     process_options
100: 
101:     if options[:user_install] and not options[:unpack] then
102:       @gem_home = Gem.user_dir
103:       check_that_user_bin_dir_is_in_path
104:     end
105:   end

Public Instance Methods

app_script_text(bin_file_name) click to toggle source

Return the text for an application file.

     # File lib/rubygems/installer.rb, line 455
455:   def app_script_text(bin_file_name)
456:     return #{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 =~ /^_(.*)_$/ and Gem::Version.correct? $1 then  version = $1  ARGV.shiftendgem '#{spec.name}', versionload Gem.bin_path('#{spec.name}', '#{bin_file_name}', version)
457:   end
build_extensions() click to toggle source

Builds extensions. Valid types of extensions are extconf.rb files, configure scripts and rakefiles or mkrf_conf files.

     # File lib/rubygems/installer.rb, line 499
499:   def build_extensions
500:     return if spec.extensions.empty?
501:     say "Building native extensions.  This could take a while..."
502:     dest_path = File.join gem_dir, spec.require_paths.first
503:     ran_rake = false # only run rake once
504: 
505:     spec.extensions.each do |extension|
506:       break if ran_rake
507:       results = []
508: 
509:       builder = case extension
510:                 when /extconf/ then
511:                   Gem::Ext::ExtConfBuilder
512:                 when /configure/ then
513:                   Gem::Ext::ConfigureBuilder
514:                 when /rakefile/, /mkrf_conf/ then
515:                   ran_rake = true
516:                   Gem::Ext::RakeBuilder
517:                 else
518:                   results = ["No builder for extension '#{extension}'"]
519:                   nil
520:                 end
521: 
522: 
523:       extension_dir = begin
524:                         File.join gem_dir, File.dirname(extension)
525:                       rescue TypeError # extension == nil
526:                         gem_dir
527:                       end
528: 
529: 
530:       begin
531:         Dir.chdir extension_dir do
532:           results = builder.build(extension, gem_dir, dest_path, results)
533: 
534:           say results.join("\n") if Gem.configuration.really_verbose
535:         end
536:       rescue
537:         results = results.join "\n"
538: 
539:         gem_make_out = File.join extension_dir, 'gem_make.out'
540: 
541:         open gem_make_out, 'wb' do |io| io.puts results end
542: 
543:         message = ERROR: Failed to build gem native extension.        #{results}Gem files will remain installed in #{gem_dir} for inspection.Results logged to #{gem_make_out}
544: 
545:         raise ExtensionBuildError, message
546:       end
547:     end
548:   end
check_that_user_bin_dir_is_in_path() click to toggle source
     # File lib/rubygems/installer.rb, line 435
435:   def check_that_user_bin_dir_is_in_path
436:     user_bin_dir = @bin_dir || Gem.bindir(gem_home)
437:     user_bin_dir.gsub!(File::SEPARATOR, File::ALT_SEPARATOR) if File::ALT_SEPARATOR
438:     unless ENV['PATH'].split(File::PATH_SEPARATOR).include? user_bin_dir then
439:       unless self.class.path_warning then
440:         alert_warning "You don't have #{user_bin_dir} in your PATH,\n\t  gem executables will not run."
441:         self.class.path_warning = true
442:       end
443:     end
444:   end
dir() click to toggle source

Return the target directory where the gem is to be installed. This directory is not guaranteed to be populated.

     # File lib/rubygems/installer.rb, line 612
612:   def dir
613:     gem_dir.to_s
614:   end
ensure_dependencies_met() click to toggle source
     # File lib/rubygems/installer.rb, line 403
403:   def ensure_dependencies_met
404:     deps = spec.runtime_dependencies
405:     deps |= spec.development_dependencies if @development
406: 
407:     deps.each do |dep_gem|
408:       ensure_dependency spec, dep_gem
409:     end
410:   end
ensure_dependency(spec, dependency) click to toggle source

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

     # File lib/rubygems/installer.rb, line 230
230:   def ensure_dependency(spec, dependency)
231:     unless installation_satisfies_dependency? dependency then
232:       raise Gem::InstallError, "#{spec.name} requires #{dependency}"
233:     end
234:     true
235:   end
ensure_required_ruby_version_met() click to toggle source
     # File lib/rubygems/installer.rb, line 385
385:   def ensure_required_ruby_version_met
386:     if rrv = spec.required_ruby_version then
387:       unless rrv.satisfied_by? Gem.ruby_version then
388:         raise Gem::InstallError, "#{spec.name} requires Ruby version #{rrv}."
389:       end
390:     end
391:   end
ensure_required_rubygems_version_met() click to toggle source
     # File lib/rubygems/installer.rb, line 393
393:   def ensure_required_rubygems_version_met
394:     if rrgv = spec.required_rubygems_version then
395:       unless rrgv.satisfied_by? Gem::Version.new(Gem::VERSION) then
396:         raise Gem::InstallError,
397:           "#{spec.name} requires RubyGems version #{rrgv}. " +
398:           "Try 'gem update --system' to update RubyGems itself."
399:       end
400:     end
401:   end
extract_files() click to toggle source

Reads the file index and extracts each file into the gem directory.

Ensures that files can’t be installed outside the gem directory.

     # File lib/rubygems/installer.rb, line 562
562:   def extract_files
563:     raise ArgumentError, "format required to extract from" if @format.nil?
564: 
565:     @format.file_entries.each do |entry, file_data|
566:       path = entry['path'].untaint
567: 
568:       if path.start_with? "/" then # for extra sanity
569:         raise Gem::InstallError, "attempt to install file into #{entry['path']}"
570:       end
571: 
572:       path = File.expand_path File.join(gem_dir, path)
573: 
574:       unless path.start_with? gem_dir then
575:         msg = "attempt to install file into %p under %s" %
576:                 [entry['path'], gem_dir]
577:         raise Gem::InstallError, msg
578:       end
579: 
580:       FileUtils.rm_rf(path) if File.exist? path
581: 
582:       dir = File.dirname path
583:       FileUtils.mkdir_p dir unless File.exist? dir
584: 
585:       File.open(path, "wb") do |out|
586:         out.write file_data
587:       end
588: 
589:       FileUtils.chmod entry['mode'], path
590: 
591:       say path if Gem.configuration.really_verbose
592:     end
593:   end
format() click to toggle source

Lazy accessor for the installer’s Gem::Format instance.

     # File lib/rubygems/installer.rb, line 117
117:   def format
118:     begin
119:       @format ||= Gem::Format.from_file_by_path gem, @security_policy
120:     rescue Gem::Package::FormatError
121:       raise Gem::InstallError, "invalid gem format for #{gem}"
122:     end
123:   end
formatted_program_filename(filename) click to toggle source

Prefix and suffix the program filename the same as ruby.

     # File lib/rubygems/installer.rb, line 598
598:   def formatted_program_filename(filename)
599:     if @format_executable then
600:       self.class.exec_format % File.basename(filename)
601:     else
602:       filename
603:     end
604:   end
gem_dir() click to toggle source

Lazy accessor for the spec’s gem directory.

     # File lib/rubygems/installer.rb, line 110
110:   def gem_dir
111:     @gem_dir ||= spec.gem_dir.dup.untaint
112:   end
generate_bin() click to toggle source
     # File lib/rubygems/installer.rb, line 280
280:   def generate_bin
281:     return if spec.executables.nil? or spec.executables.empty?
282: 
283:     # If the user has asked for the gem to be installed in a directory that is
284:     # the system gem directory, then use the system bin directory, else create
285:     # (or use) a new bin dir under the gem_home.
286:     bindir = @bin_dir || Gem.bindir(gem_home)
287: 
288:     Dir.mkdir bindir unless File.exist? bindir
289:     raise Gem::FilePermissionError.new(bindir) unless File.writable? bindir
290: 
291:     spec.executables.each do |filename|
292:       filename.untaint
293:       bin_path = File.expand_path File.join(gem_dir, spec.bindir, filename)
294: 
295:       unless File.exist? bin_path
296:         warn "Hey?!?! Where did #{bin_path} go??"
297:         next
298:       end
299: 
300:       mode = File.stat(bin_path).mode | 0111
301:       FileUtils.chmod mode, bin_path
302: 
303:       if @wrappers then
304:         generate_bin_script filename, bindir
305:       else
306:         generate_bin_symlink filename, bindir
307:       end
308:     end
309:   end
generate_bin_script(filename, bindir) click to toggle source

Creates the scripts to run the applications in the gem.

     # File lib/rubygems/installer.rb, line 318
318:   def generate_bin_script(filename, bindir)
319:     bin_script_path = File.join bindir, formatted_program_filename(filename)
320: 
321:     FileUtils.rm_f bin_script_path # prior install may have been --no-wrappers
322: 
323:     File.open bin_script_path, 'wb', 0755 do |file|
324:       file.print app_script_text(filename)
325:     end
326: 
327:     say bin_script_path if Gem.configuration.really_verbose
328: 
329:     generate_windows_script filename, bindir
330:   end
generate_windows_script(filename, bindir) click to toggle source

Creates windows .bat files for easy running of commands

     # File lib/rubygems/installer.rb, line 268
268:   def generate_windows_script(filename, bindir)
269:     if Gem.win_platform? then
270:       script_name = filename + ".bat"
271:       script_path = File.join bindir, File.basename(script_name)
272:       File.open script_path, 'w' do |file|
273:         file.puts windows_stub_script(bindir, filename)
274:       end
275: 
276:       say script_path if Gem.configuration.really_verbose
277:     end
278:   end
install() click to toggle source

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
     # File lib/rubygems/installer.rb, line 143
143:   def install
144:     current_home = Gem.dir
145:     current_path = Gem.paths.path
146: 
147:     verify_gem_home(options[:unpack])
148:     Gem.use_paths gem_home, current_path # HACK: shouldn't need Gem.paths.path
149: 
150:     # If we're forcing the install then disable security unless the security
151:     # policy says that we only install signed gems.
152:     @security_policy = nil if @force and @security_policy and
153:                               not @security_policy.only_signed
154: 
155:     unless @force
156:       ensure_required_ruby_version_met
157:       ensure_required_rubygems_version_met
158:       ensure_dependencies_met unless @ignore_dependencies
159:     end
160: 
161:     Gem.pre_install_hooks.each do |hook|
162:       result = hook.call self
163: 
164:       if result == false then
165:         location = " at #{$1}" if hook.inspect =~ /@(.*:\d+)/
166: 
167:         message = "pre-install hook#{location} failed for #{spec.full_name}"
168:         raise Gem::InstallError, message
169:       end
170:     end
171: 
172:     Gem.ensure_gem_subdirectories gem_home
173: 
174:     # Completely remove any previous gem files
175:     FileUtils.rm_rf(gem_dir) if File.exist? gem_dir
176: 
177:     FileUtils.mkdir_p gem_dir
178: 
179:     extract_files
180:     build_extensions
181: 
182:     Gem.post_build_hooks.each do |hook|
183:       result = hook.call self
184: 
185:       if result == false then
186:         FileUtils.rm_rf gem_dir
187: 
188:         location = " at #{$1}" if hook.inspect =~ /@(.*:\d+)/
189: 
190:         message = "post-build hook#{location} failed for #{spec.full_name}"
191:         raise Gem::InstallError, message
192:       end
193:     end
194: 
195:     generate_bin
196:     write_spec
197: 
198:     write_require_paths_file_if_needed if Gem::QUICKLOADER_SUCKAGE
199: 
200:     cache_file = spec.cache_file
201:     FileUtils.cp gem, cache_file unless File.exist? cache_file
202: 
203:     say spec.post_install_message unless spec.post_install_message.nil?
204: 
205:     spec.loaded_from = spec.spec_file
206: 
207:     Gem::Specification.add_spec spec unless Gem::Specification.include? spec
208: 
209:     Gem.post_install_hooks.each do |hook|
210:       hook.call self
211:     end
212: 
213:     return spec
214:   rescue Zlib::GzipFile::Error
215:     raise Gem::InstallError, "gzip error installing #{gem}"
216:   ensure
217:     # conditional since we might be here because we're erroring out early.
218:     if current_path
219:       Gem.use_paths current_home, current_path
220:     end
221:   end
installation_satisfies_dependency?(dependency) click to toggle source

True if the gems in the source_index satisfy dependency.

     # File lib/rubygems/installer.rb, line 240
240:   def installation_satisfies_dependency?(dependency)
241:     not dependency.matching_specs.empty?
242:   end
process_options() click to toggle source
     # File lib/rubygems/installer.rb, line 412
412:   def process_options
413:     @options = {
414:       :bin_dir      => nil,
415:       :env_shebang  => false,
416:       :exec_format  => false,
417:       :force        => false,
418:       :install_dir  => Gem.dir,
419:     }.merge options
420: 
421:     @env_shebang         = options[:env_shebang]
422:     @force               = options[:force]
423:     @gem_home            = options[:install_dir]
424:     @ignore_dependencies = options[:ignore_dependencies]
425:     @format_executable   = options[:format_executable]
426:     @security_policy     = options[:security_policy]
427:     @wrappers            = options[:wrappers]
428:     @bin_dir             = options[:bin_dir]
429:     @development         = options[:development]
430: 
431:     raise "NOTE: Installer option :source_index is dead" if
432:       options[:source_index]
433:   end
shebang(bin_file_name) click to toggle source

Generates a #! line for bin_file_name’s wrapper copying arguments if necessary.

     # File lib/rubygems/installer.rb, line 362
362:   def shebang(bin_file_name)
363:     ruby_name = Gem::ConfigMap[:ruby_install_name] if @env_shebang
364:     path = spec.bin_file bin_file_name
365:     first_line = File.open(path, "rb") {|file| file.gets}
366: 
367:     if /\A#!/ =~ first_line then
368:       # Preserve extra words on shebang line, like "-w".  Thanks RPA.
369:       shebang = first_line.sub(/\A\#!.*?ruby\S*(?=(\s+\S+))/, "#!#{Gem.ruby}")
370:       opts = $1
371:       shebang.strip! # Avoid nasty ^M issues.
372:     end
373: 
374:     if not ruby_name then
375:       "#!#{Gem.ruby}#{opts}"
376:     elsif opts then
377:       "#!/bin/sh\n'exec' #{ruby_name.dump} '-x' \"$0\" \"$@\"\n#{shebang}"
378:     else
379:       # Create a plain shebang line.
380:       @env_path ||= ENV_PATHS.find {|env_path| File.executable? env_path }
381:       "#!#{@env_path} #{ruby_name}"
382:     end
383:   end
spec() click to toggle source

Lazy accessor for the installer’s spec.

     # File lib/rubygems/installer.rb, line 128
128:   def spec
129:     @spec ||= format.spec
130:   end
unpack(directory) click to toggle source

Unpacks the gem into the given directory.

     # File lib/rubygems/installer.rb, line 247
247:   def unpack(directory)
248:     @gem_dir = directory
249:     @format = Gem::Format.from_file_by_path gem, @security_policy
250:     extract_files
251:   end
verify_gem_home(unpack = false) click to toggle source
     # File lib/rubygems/installer.rb, line 446
446:   def verify_gem_home(unpack = false)
447:     FileUtils.mkdir_p gem_home
448:     raise Gem::FilePermissionError, gem_home unless
449:       unpack or File.writable?(gem_home)
450:   end
windows_stub_script(bindir, bin_file_name) click to toggle source

return the stub script text used to launch the true ruby script

     # File lib/rubygems/installer.rb, line 482
482:   def windows_stub_script(bindir, bin_file_name)
483:     ruby = File.basename(Gem.ruby).chomp('"')
484:     return @ECHO OFFIF NOT "%~f0" == "~f0" GOTO :WinNT@"#{ruby}" "#{File.join(bindir, bin_file_name)}" %1 %2 %3 %4 %5 %6 %7 %8 %9GOTO :EOF:WinNT@"#{ruby}" "%~dpn0" %*
485: 
486:   end
write_spec() click to toggle source

Writes the .gemspec specification (in Ruby) to the gem home’s specifications directory.

     # File lib/rubygems/installer.rb, line 257
257:   def write_spec
258:     file_name = spec.spec_file.untaint
259: 
260:     File.open(file_name, "w") do |file|
261:       file.puts spec.to_ruby_for_cache
262:     end
263:   end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.