def disable &block
return self if not enabled?
fire :disabling
ENV.replace @old_env
$LOAD_PATH.replace @old_load_path
@enabled = false
Isolate.refresh
fire :disabled
begin; return yield ensure enable end if block_given?
self
end
def enable
return self if enabled?
fire :enabling
@old_env = ENV.to_hash
@old_load_path = $LOAD_PATH.dup
path = self.path
FileUtils.mkdir_p path
ENV["GEM_HOME"] = path
unless system?
isolate_lib = File.expand_path "../..", __FILE__
$LOAD_PATH.reject! do |p|
p != isolate_lib && Gem.path.any? { |gp| p.include?(gp) }
end
unless ENV["RUBYOPT"] =~ /\s+-I\s*#{Regexp.escape isolate_lib}\b/
ENV["RUBYOPT"] = "#{ENV['RUBYOPT']} -I#{isolate_lib}"
end
ENV["GEM_PATH"] = path
end
bin = File.join path, "bin"
unless ENV["PATH"].split(File::PATH_SEPARATOR).include? bin
ENV["PATH"] = [bin, ENV["PATH"]].join File::PATH_SEPARATOR
end
ENV["ISOLATED"] = path
if system? then
Gem.path.unshift path
Gem.path.uniq!
end
Isolate.refresh
@enabled = true
fire :enabled
self
end
def enabled?
@enabled
end
def environment *environments, &block
old = @environments
@environments = @environments.dup.concat environments.map { |e| e.to_s }
instance_eval(&block)
ensure
@environments = old
end
alias_method :env, :environment
def gem name, *requirements
entry = entries.find { |e| e.name == name }
return entry.update(*requirements) if entry
entries << entry = Entry.new(self, name, *requirements)
entry
end
def index
@index ||= Gem::SourceIndex.from_gems_in File.join(path, "specifications")
end
def install environment
fire :installing
installable = entries.select do |e|
!e.specification && e.matches?(environment)
end
unless installable.empty?
padding = Math.log10(installable.size).to_i + 1
format = "[%0#{padding}d/%s] Isolating %s (%s)."
installable.each_with_index do |entry, i|
log format % [i + 1, installable.size, entry.name, entry.requirement]
entry.install
end
Gem::Specification.reset
end
fire :installed
self
end
def install?
@options.fetch :install, true
end
def load file
files << file
instance_eval IO.read(file), file, 1
end
def log s
$stderr.puts s if verbose?
end
def multiruby?
@options.fetch :multiruby, true
end
def options options = nil
@options.merge! options if options
@options
end
def path
base = @options.fetch :path, DEFAULT_PATH
unless @options.key?(:multiruby) && @options[:multiruby] == false
suffix = "#{Gem.ruby_engine}-#{RbConfig::CONFIG['ruby_version']}"
base = File.join(base, suffix) unless base =~ /#{suffix}/
end
File.expand_path base
end
def remove(*extra)
unless extra.empty?
padding = Math.log10(extra.size).to_i + 1
format = "[%0#{padding}d/%s] Nuking %s."
extra.each_with_index do |e, i|
log format % [i + 1, extra.size, e.full_name]
Gem::DefaultUserInteraction.use_ui Gem::SilentUI.new do
uninstaller =
Gem::Uninstaller.new(e.name,
:version => e.version,
:ignore => true,
:executables => true,
:install_dir => e.base_dir)
uninstaller.uninstall
end
end
end
end
def system?
@options.fetch :system, true
end
def verbose?
@options.fetch :verbose, true
end
private
def legitimize! deps = entries
specs = []
deps.flatten.each do |dep|
spec = case dep
when Gem::Dependency then
begin
dep.to_spec
rescue Gem::LoadError
nil
end
when Isolate::Entry then
dep.specification
else
raise "unknown dep: #{dep.inspect}"
end
if spec then
specs.concat legitimize!(spec.runtime_dependencies)
specs << spec
end
end
specs.uniq
end
dep_module = defined?(Gem::Deprecate) ? Gem::Deprecate : Deprecate
extend dep_module
deprecate :index, :none, 2011, 11
end