def install(*packages)
return _install_helper(*packages) do |list, opts|
gem = opts[:gem] || self.gem
cmd = "#{gem} install -y"
cmd << " --no-ri" if opts[:ri] == false or opts[:docs] == false
cmd << " --no-rdoc" if opts[:rdoc] == false or opts[:docs] == false
cmd << " --source #{opts[:source]}" if opts[:source]
cmd << " "+list.join(" ")
cmd << " " << opts[:args] if opts[:args]
cmd << " 2>&1"
log.info(PNOTE+"Installing Gems, this will take a while...") if writing? and not opts[:quiet]
log.info(PEXEC+cmd)
return true if preview?
uninstall_needed = false
begin
require 'expect'
require 'open4'
exitstruct = Open4::popen4(cmd) do |pid, sin, sout, serr|
$expect_verbose = opts[:quiet] ? false : true
re_missing=/Could not find.+in any repository/m
re_select=/Select which gem to install.+>/m
re_failed=/Gem files will remain.+for inspection/m
re_refused=/Errno::ECONNREFUSED reading .+?\.gem/m
re_all=/#{re_missing}|#{re_select}|#{re_failed}|#{re_refused}/m
while true
begin
captureded = sout.expect(re_all)
rescue NoMethodError
log.debug(PNOTE+"Gem seems to be done")
break
end
captured = captureded.first
if captured.match(re_failed)
log.warn(PERROR+"Gem install failed mid-process")
uninstall_needed = true
break
elsif captured.match(re_refused)
log.warn(PERROR+"Gem install refused by server!\n#{captured}")
break
elsif captured.match(re_select)
choice = captured.match(/^ (\d+)\. .+?\(ruby\)\s*$/)[1]
log.info(PNOTE+"Guessing: #{choice}")
sin.puts(choice)
end
end
end
rescue Errno::ENOENT => e
raise NotImplementedError.new("can't find gem command: #{e}")
end
if uninstall_needed or not exitstruct.exitstatus.zero?
log.error(PERROR+"Gem install failed, trying to uninstall broken pieces: #{list.inspect}")
uninstall(list, opts)
raise ArgumentError.new("Gem install failed because it's invalid, missing a dependency, or can't talk with Gem server: #{list.inspect}")
end
end
end