homebrew-cask-versions/lib/cask/installer.rb
Roland Walker 0e7be245be Return Cask::SystemCommand::Result object
from Cask::SystemCommand.run

* stderr and stdout are now separated, though both are available
* :print_stderr is made the default, closer to previous behavior
* exit status can be read from the result object
* plist parsing is more naturally handled in the result object.
  The :plist argument to the run method was removed.
* whitespace
2014-09-27 08:59:08 -04:00

199 lines
5.5 KiB
Ruby

class Cask::Installer
PERSISTENT_METADATA_SUBDIRS = [ 'gpg' ]
def initialize(cask, command=Cask::SystemCommand)
@cask = cask
@command = command
end
def self.print_caveats(cask)
odebug "Printing caveats"
unless cask.caveats.empty?
output = capture_output do
cask.caveats.each do |caveat|
if caveat.respond_to?(:eval_and_print)
caveat.eval_and_print(cask)
else
puts caveat
end
end
end
unless output.empty?
ohai "Caveats"
puts output
end
end
end
def self.capture_output(&block)
old_stdout = $stdout
$stdout = Buffer.new($stdout.tty?)
block.call
output = $stdout.string
$stdout = old_stdout
output
end
def install(force=false)
odebug "Cask::Installer.install"
if @cask.installed? && !force
raise CaskAlreadyInstalledError.new(@cask)
end
print_caveats
begin
formula_dependencies
download
extract_primary_container
install_artifacts
rescue
purge_versioned_files
raise
end
puts summary
end
def summary
s = if MacOS.version >= :lion and not ENV['HOMEBREW_NO_EMOJI']
(ENV['HOMEBREW_INSTALL_BADGE'] || "\xf0\x9f\x8d\xba") + ' '
else
"#{Tty.blue}==>#{Tty.white} Success!#{Tty.reset} "
end
s << "#{@cask} installed to '#{@cask.destination_path}' (#{@cask.destination_path.cabv})"
end
def download
odebug "Downloading"
download = Cask::Download.new(@cask)
@downloaded_path = download.perform
odebug "Downloaded to -> #{@downloaded_path}"
@downloaded_path
end
def extract_primary_container
odebug "Extracting primary container"
FileUtils.mkdir_p @cask.destination_path
container = if @cask.container_type
Cask::Container.from_type(@cask.container_type)
else
Cask::Container.for_path(@downloaded_path, @command)
end
unless container
raise CaskError.new "Uh oh, could not identify primary container for '#{@downloaded_path}'"
end
odebug "Using container class #{container} for #{@downloaded_path}"
container.new(@cask, @downloaded_path, @command).extract
end
def install_artifacts
odebug "Installing artifacts"
artifacts = Cask::Artifact.for_cask(@cask)
odebug "#{artifacts.length} artifact/s defined", artifacts
artifacts.each do |artifact|
odebug "Installing artifact of class #{artifact}"
artifact.new(@cask, @command).install_phase
end
end
def formula_dependencies
unless @cask.depends_on_formula.empty?
ohai 'Installing Formula dependencies from Homebrew'
@cask.depends_on_formula.each do |dep_name|
print "#{dep_name} ... "
installed = @command.run(HOMEBREW_BREW_FILE,
:args => ['list', '--versions', dep_name],
:print_stderr => false).stdout.include?(dep_name)
if installed
puts "already installed"
else
@command.run!(HOMEBREW_BREW_FILE,
:args => ['install', dep_name])
puts "done"
end
end
end
end
def print_caveats
self.class.print_caveats(@cask)
end
def uninstall(force=false)
odebug "Cask::Installer.uninstall"
uninstall_artifacts
purge_versioned_files
purge_caskroom_path if force
end
def uninstall_artifacts
odebug "Un-installing artifacts"
artifacts = Cask::Artifact.for_cask(@cask)
odebug "#{artifacts.length} artifact/s defined", artifacts
artifacts.each do |artifact|
odebug "Un-installing artifact of class #{artifact}"
artifact.new(@cask, @command).uninstall_phase
end
end
def zap
ohai %Q{Implied "brew cask uninstall #{@cask}"}
uninstall_artifacts
if Cask::Artifact::Zap.me?(@cask)
ohai "Dispatching zap stanza"
Cask::Artifact::Zap.new(@cask, @command).zap_phase
else
opoo "No zap stanza present for Cask '#{@cask}'"
end
ohai %Q{Removing all staged versions of Cask '#{@cask}'}
purge_caskroom_path
end
# this feels like a class method, but uses @command
def permissions_rmtree(path)
if path.respond_to?(:rmtree) and path.exist?
begin
path.rmtree
rescue
# in case of permissions problems
if path.exist?
@command.run('/bin/chmod', :args => ['-R', '--', 'u+rwx', path])
@command.run('/bin/chmod', :args => ['-R', '-N', path])
path.rmtree
end
end
end
end
def purge_versioned_files
odebug "Purging files for version #{@cask.version} of Cask #{@cask}"
# versioned staged distribution
permissions_rmtree(@cask.destination_path)
# Homebrew-cask metadata
if @cask.metadata_versioned_container_path.respond_to?(:children) and
@cask.metadata_versioned_container_path.exist?
@cask.metadata_versioned_container_path.children.each do |subdir|
permissions_rmtree subdir unless PERSISTENT_METADATA_SUBDIRS.include?(subdir.basename)
end
end
if @cask.metadata_versioned_container_path.respond_to?(:rmdir_if_possible)
@cask.metadata_versioned_container_path.rmdir_if_possible
end
if @cask.metadata_master_container_path.respond_to?(:rmdir_if_possible)
@cask.metadata_master_container_path.rmdir_if_possible
end
# toplevel staged distribution
@cask.caskroom_path.rmdir_if_possible
end
def purge_caskroom_path
odebug "Purging all staged versions of Cask #{@cask}"
permissions_rmtree(@cask.caskroom_path)
end
end