29
28
class Gem::Installer
31
# Paths where env(1) might live. Some systems are broken and have it in
34
ENV_PATHS = %w[/usr/bin/env /bin/env]
32
37
# Raised when there is an error while building extensions.
34
39
class ExtensionBuildError < Gem::InstallError; end
55
@home_install_warning = false
56
60
@path_warning = false
61
# True if we've warned about ~/.gems install
63
attr_accessor :home_install_warning
66
65
# True if we've warned about PATH not including Gem.bindir
68
67
attr_accessor :path_warning
106
105
@env_shebang = options[:env_shebang]
107
106
@force = options[:force]
108
107
gem_home = options[:install_dir]
109
@gem_home = Pathname.new(gem_home).expand_path
108
@gem_home = File.expand_path(gem_home)
110
109
@ignore_dependencies = options[:ignore_dependencies]
111
110
@format_executable = options[:format_executable]
112
111
@security_policy = options[:security_policy]
121
120
raise Gem::InstallError, "invalid gem format for #{@gem}"
125
FileUtils.mkdir_p @gem_home
126
rescue Errno::EACCES, Errno::ENOTDIR
127
# We'll divert to ~/.gems below
130
if not File.writable? @gem_home or
131
# TODO: Shouldn't have to test for existence of bindir; tests need it.
132
(@gem_home.to_s == Gem.dir and File.exist? Gem.bindir and
133
not File.writable? Gem.bindir) then
134
if options[:user_install] == false then # You don't want to use ~
135
raise Gem::FilePermissionError, @gem_home
136
elsif options[:user_install].nil? then
137
unless self.class.home_install_warning or options[:unpack] then
138
alert_warning "Installing to ~/.gem since #{@gem_home} and\n\t #{Gem.bindir} aren't both writable."
139
self.class.home_install_warning = true
142
options[:user_install] = true
145
123
if options[:user_install] and not options[:unpack] then
146
124
@gem_home = Gem.user_dir
152
130
self.class.path_warning = true
156
FileUtils.mkdir_p @gem_home unless File.directory? @gem_home
157
# If it's still not writable, you've got issues.
158
raise Gem::FilePermissionError, @gem_home unless File.writable? @gem_home
135
FileUtils.mkdir_p @gem_home
136
raise Gem::FilePermissionError, @gem_home unless File.writable? @gem_home
161
138
@spec = @format.spec
163
140
@gem_dir = File.join(@gem_home, "gems", @spec.full_name).untaint
183
160
unless @force then
184
161
if rrv = @spec.required_ruby_version then
185
162
unless rrv.satisfied_by? Gem.ruby_version then
186
raise Gem::InstallError, "#{@spec.name} requires Ruby version #{rrv}"
163
raise Gem::InstallError, "#{@spec.name} requires Ruby version #{rrv}."
190
167
if rrgv = @spec.required_rubygems_version then
191
168
unless rrgv.satisfied_by? Gem::Version.new(Gem::RubyGemsVersion) then
192
169
raise Gem::InstallError,
193
"#{@spec.name} requires RubyGems version #{rrgv}"
170
"#{@spec.name} requires RubyGems version #{rrgv}. " +
171
"Try 'gem update --system' to update RubyGems itself."
230
208
say @spec.post_install_message unless @spec.post_install_message.nil?
232
@spec.loaded_from = File.join(@gem_home, 'specifications',
233
"#{@spec.full_name}.gemspec")
210
@spec.loaded_from = File.join(@gem_home, 'specifications', @spec.spec_name)
235
212
@source_index.add_spec @spec
262
239
# True if the gems in the source_index satisfy +dependency+.
264
241
def installation_satisfies_dependency?(dependency)
265
@source_index.find_name(dependency.name, dependency.version_requirements).size > 0
242
@source_index.find_name(dependency.name, dependency.requirement).size > 0
282
259
rubycode = @spec.to_ruby
284
file_name = File.join @gem_home, 'specifications',
285
"#{@spec.full_name}.gemspec"
261
file_name = File.join @gem_home, 'specifications', @spec.spec_name
287
263
file_name.untaint
394
370
def shebang(bin_file_name)
396
"#!/usr/bin/env " + Gem::ConfigMap[:ruby_install_name]
371
ruby_name = Gem::ConfigMap[:ruby_install_name] if @env_shebang
372
path = File.join @gem_dir, @spec.bindir, bin_file_name
373
first_line = File.open(path, "rb") {|file| file.gets}
375
if /\A#!/ =~ first_line then
376
# Preserve extra words on shebang line, like "-w". Thanks RPA.
377
shebang = first_line.sub(/\A\#!.*?ruby\S*(?=(\s+\S+))/, "#!#{Gem.ruby}")
379
shebang.strip! # Avoid nasty ^M issues.
382
if not ruby_name then
383
"#!#{Gem.ruby}#{opts}"
385
"#!/bin/sh\n'exec' #{ruby_name.dump} '-x' \"$0\" \"$@\"\n#{shebang}"
398
path = File.join @gem_dir, @spec.bindir, bin_file_name
400
File.open(path, "rb") do |file|
401
first_line = file.gets
402
if first_line =~ /^#!/ then
403
# Preserve extra words on shebang line, like "-w". Thanks RPA.
404
shebang = first_line.sub(/\A\#!.*?ruby\S*/, "#!#{Gem.ruby}")
406
# Create a plain shebang line.
407
shebang = "#!#{Gem.ruby}"
410
shebang.strip # Avoid nasty ^M issues.
387
# Create a plain shebang line.
388
@env_path ||= ENV_PATHS.find {|env_path| File.executable? env_path }
389
"#!#{@env_path} #{ruby_name}"
514
492
# Ensures that files can't be installed outside the gem directory.
516
494
def extract_files
517
expand_and_validate_gem_dir
495
@gem_dir = File.expand_path @gem_dir
519
497
raise ArgumentError, "format required to extract from" if @format.nil?
564
# HACK Pathname is broken on windows.
566
def absolute_path? pathname
567
pathname.absolute? or (Gem.win_platform? and pathname.to_s =~ /\A[a-z]:/i)
570
def expand_and_validate_gem_dir
571
@gem_dir = Pathname.new(@gem_dir).expand_path
573
unless absolute_path?(@gem_dir) then # HACK is this possible after #expand_path?
574
raise ArgumentError, "install directory %p not absolute" % @gem_dir
577
@gem_dir = @gem_dir.to_s