aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew/cask/lib/hbc/installer.rb
diff options
context:
space:
mode:
authorMarkus Reiter2016-09-24 13:52:43 +0200
committerMarkus Reiter2016-09-24 16:00:58 +0200
commitb86c8efb79b3ed835d552c4d7416640ef10caf21 (patch)
tree7e1edc8a8f339e4d2781f43576d40c9c79aebcdc /Library/Homebrew/cask/lib/hbc/installer.rb
parent687f0fcf721c8e36f32570ed72d0988a6eaf986f (diff)
downloadbrew-b86c8efb79b3ed835d552c4d7416640ef10caf21.tar.bz2
Cask: Use nested classes and modules.
Diffstat (limited to 'Library/Homebrew/cask/lib/hbc/installer.rb')
-rw-r--r--Library/Homebrew/cask/lib/hbc/installer.rb574
1 files changed, 288 insertions, 286 deletions
diff --git a/Library/Homebrew/cask/lib/hbc/installer.rb b/Library/Homebrew/cask/lib/hbc/installer.rb
index ea67078f5..f0cc0d1a9 100644
--- a/Library/Homebrew/cask/lib/hbc/installer.rb
+++ b/Library/Homebrew/cask/lib/hbc/installer.rb
@@ -4,344 +4,346 @@ require "hbc/cask_dependencies"
require "hbc/staged"
require "hbc/verify"
-class Hbc::Installer
- # TODO: it is unwise for Hbc::Staged to be a module, when we are
- # dealing with both staged and unstaged Casks here. This should
- # either be a class which is only sometimes instantiated, or there
- # should be explicit checks on whether staged state is valid in
- # every method.
- include Hbc::Staged
- include Hbc::Verify
-
- attr_reader :force, :skip_cask_deps
-
- PERSISTENT_METADATA_SUBDIRS = ["gpg"].freeze
-
- def initialize(cask, command: Hbc::SystemCommand, force: false, skip_cask_deps: false, require_sha: false)
- @cask = cask
- @command = command
- @force = force
- @skip_cask_deps = skip_cask_deps
- @require_sha = require_sha
- end
+module Hbc
+ class Installer
+ # TODO: it is unwise for Hbc::Staged to be a module, when we are
+ # dealing with both staged and unstaged Casks here. This should
+ # either be a class which is only sometimes instantiated, or there
+ # should be explicit checks on whether staged state is valid in
+ # every method.
+ include Staged
+ include Verify
+
+ attr_reader :force, :skip_cask_deps
+
+ PERSISTENT_METADATA_SUBDIRS = ["gpg"].freeze
+
+ def initialize(cask, command: SystemCommand, force: false, skip_cask_deps: false, require_sha: false)
+ @cask = cask
+ @command = command
+ @force = force
+ @skip_cask_deps = skip_cask_deps
+ @require_sha = require_sha
+ 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
+ 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
- end
- unless output.empty?
- ohai "Caveats"
- puts output
+ unless output.empty?
+ ohai "Caveats"
+ puts output
+ end
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 self.capture_output(&block)
+ old_stdout = $stdout
+ $stdout = Buffer.new($stdout.tty?)
+ block.call
+ output = $stdout.string
+ $stdout = old_stdout
+ output
+ end
- def install
- odebug "Hbc::Installer.install"
+ def install
+ odebug "Hbc::Installer.install"
- if @cask.installed? && @cask.auto_updates && !force
- raise Hbc::CaskAutoUpdatesError, @cask
- end
+ if @cask.installed? && @cask.auto_updates && !force
+ raise CaskAutoUpdatesError, @cask
+ end
- raise Hbc::CaskAlreadyInstalledError, @cask if @cask.installed? && !force
+ raise CaskAlreadyInstalledError, @cask if @cask.installed? && !force
+
+ print_caveats
+
+ begin
+ satisfy_dependencies
+ verify_has_sha if @require_sha && !@force
+ download
+ verify
+ extract_primary_container
+ install_artifacts
+ save_caskfile
+ enable_accessibility_access
+ rescue StandardError => e
+ purge_versioned_files
+ raise e
+ end
- print_caveats
+ puts summary
+ end
- begin
- satisfy_dependencies
- verify_has_sha if @require_sha && !@force
- download
- verify
- extract_primary_container
- install_artifacts
- save_caskfile
- enable_accessibility_access
- rescue StandardError => e
- purge_versioned_files
- raise e
+ def summary
+ s = if MacOS.version >= :lion && !ENV["HOMEBREW_NO_EMOJI"]
+ (ENV["HOMEBREW_INSTALL_BADGE"] || "\xf0\x9f\x8d\xba") + " "
+ else
+ "#{Tty.blue}==>#{Tty.reset} #{Tty.white}Success!#{Tty.reset} "
+ end
+ s << "#{@cask} was successfully installed!"
end
- puts summary
- end
+ def download
+ odebug "Downloading"
+ download = Download.new(@cask, force: false)
+ @downloaded_path = download.perform
+ odebug "Downloaded to -> #{@downloaded_path}"
+ @downloaded_path
+ end
- def summary
- s = if MacOS.version >= :lion && !ENV["HOMEBREW_NO_EMOJI"]
- (ENV["HOMEBREW_INSTALL_BADGE"] || "\xf0\x9f\x8d\xba") + " "
- else
- "#{Tty.blue}==>#{Tty.reset} #{Tty.white}Success!#{Tty.reset} "
- end
- s << "#{@cask} was successfully installed!"
- end
+ def verify_has_sha
+ odebug "Checking cask has checksum"
+ return unless @cask.sha256 == :no_check
+ raise CaskNoShasumError, @cask
+ end
- def download
- odebug "Downloading"
- download = Hbc::Download.new(@cask, force: false)
- @downloaded_path = download.perform
- odebug "Downloaded to -> #{@downloaded_path}"
- @downloaded_path
- end
+ def verify
+ Verify.all(@cask, @downloaded_path)
+ end
- def verify_has_sha
- odebug "Checking cask has checksum"
- return unless @cask.sha256 == :no_check
- raise Hbc::CaskNoShasumError, @cask
- end
+ def extract_primary_container
+ odebug "Extracting primary container"
+ FileUtils.mkdir_p @cask.staged_path
+ container = if @cask.container && @cask.container.type
+ Container.from_type(@cask.container.type)
+ else
+ Container.for_path(@downloaded_path, @command)
+ end
+ unless container
+ raise CaskError, "Uh oh, could not figure out how to unpack '#{@downloaded_path}'"
+ end
+ odebug "Using container class #{container} for #{@downloaded_path}"
+ container.new(@cask, @downloaded_path, @command).extract
+ end
- def verify
- Hbc::Verify.all(@cask, @downloaded_path)
- end
+ def install_artifacts
+ odebug "Installing artifacts"
+ artifacts = Artifact.for_cask(@cask)
+ odebug "#{artifacts.length} artifact/s defined", artifacts
+ artifacts.each do |artifact|
+ odebug "Installing artifact of class #{artifact}"
+ options = { command: @command, force: force }
+ artifact.new(@cask, options).install_phase
+ end
+ end
- def extract_primary_container
- odebug "Extracting primary container"
- FileUtils.mkdir_p @cask.staged_path
- container = if @cask.container && @cask.container.type
- Hbc::Container.from_type(@cask.container.type)
- else
- Hbc::Container.for_path(@downloaded_path, @command)
- end
- unless container
- raise Hbc::CaskError, "Uh oh, could not figure out how to unpack '#{@downloaded_path}'"
+ # TODO: move dependencies to a separate class
+ # dependencies should also apply for "brew cask stage"
+ # override dependencies with --force or perhaps --force-deps
+ def satisfy_dependencies
+ return unless @cask.depends_on
+
+ ohai "Satisfying dependencies"
+ macos_dependencies
+ arch_dependencies
+ x11_dependencies
+ formula_dependencies
+ cask_dependencies unless skip_cask_deps
+ puts "complete"
end
- odebug "Using container class #{container} for #{@downloaded_path}"
- container.new(@cask, @downloaded_path, @command).extract
- end
- def install_artifacts
- odebug "Installing artifacts"
- artifacts = Hbc::Artifact.for_cask(@cask)
- odebug "#{artifacts.length} artifact/s defined", artifacts
- artifacts.each do |artifact|
- odebug "Installing artifact of class #{artifact}"
- options = { command: @command, force: force }
- artifact.new(@cask, options).install_phase
+ def macos_dependencies
+ return unless @cask.depends_on.macos
+ if @cask.depends_on.macos.first.is_a?(Array)
+ operator, release = @cask.depends_on.macos.first
+ unless MacOS.version.send(operator, release)
+ raise CaskError, "Cask #{@cask} depends on macOS release #{operator} #{release}, but you are running release #{MacOS.version}."
+ end
+ elsif @cask.depends_on.macos.length > 1
+ unless @cask.depends_on.macos.include?(Gem::Version.new(MacOS.version.to_s))
+ raise CaskError, "Cask #{@cask} depends on macOS release being one of [#{@cask.depends_on.macos.map(&:to_s).join(", ")}], but you are running release #{MacOS.version}."
+ end
+ else
+ unless MacOS.version == @cask.depends_on.macos.first
+ raise CaskError, "Cask #{@cask} depends on macOS release #{@cask.depends_on.macos.first}, but you are running release #{MacOS.version}."
+ end
+ end
end
- end
- # TODO: move dependencies to a separate class
- # dependencies should also apply for "brew cask stage"
- # override dependencies with --force or perhaps --force-deps
- def satisfy_dependencies
- return unless @cask.depends_on
-
- ohai "Satisfying dependencies"
- macos_dependencies
- arch_dependencies
- x11_dependencies
- formula_dependencies
- cask_dependencies unless skip_cask_deps
- puts "complete"
- end
+ def arch_dependencies
+ return if @cask.depends_on.arch.nil?
+ @current_arch ||= { type: Hardware::CPU.type, bits: Hardware::CPU.bits }
+ return if @cask.depends_on.arch.any? { |arch|
+ arch[:type] == @current_arch[:type] &&
+ Array(arch[:bits]).include?(@current_arch[:bits])
+ }
+ raise CaskError, "Cask #{@cask} depends on hardware architecture being one of [#{@cask.depends_on.arch.map(&:to_s).join(", ")}], but you are running #{@current_arch}"
+ end
- def macos_dependencies
- return unless @cask.depends_on.macos
- if @cask.depends_on.macos.first.is_a?(Array)
- operator, release = @cask.depends_on.macos.first
- unless MacOS.version.send(operator, release)
- raise Hbc::CaskError, "Cask #{@cask} depends on macOS release #{operator} #{release}, but you are running release #{MacOS.version}."
- end
- elsif @cask.depends_on.macos.length > 1
- unless @cask.depends_on.macos.include?(Gem::Version.new(MacOS.version.to_s))
- raise Hbc::CaskError, "Cask #{@cask} depends on macOS release being one of [#{@cask.depends_on.macos.map(&:to_s).join(", ")}], but you are running release #{MacOS.version}."
- end
- else
- unless MacOS.version == @cask.depends_on.macos.first
- raise Hbc::CaskError, "Cask #{@cask} depends on macOS release #{@cask.depends_on.macos.first}, but you are running release #{MacOS.version}."
+ def x11_dependencies
+ return unless @cask.depends_on.x11
+ raise CaskX11DependencyError, @cask.token if Hbc.x11_libpng.select(&:exist?).empty?
+ end
+
+ def formula_dependencies
+ return unless @cask.depends_on.formula && !@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(Hbc.homebrew_executable,
+ args: ["list", "--versions", dep_name],
+ print_stderr: false).stdout.include?(dep_name)
+ if installed
+ puts "already installed"
+ else
+ @command.run!(Hbc.homebrew_executable,
+ args: ["install", dep_name])
+ puts "done"
+ end
end
end
- end
- def arch_dependencies
- return if @cask.depends_on.arch.nil?
- @current_arch ||= { type: Hardware::CPU.type, bits: Hardware::CPU.bits }
- return if @cask.depends_on.arch.any? { |arch|
- arch[:type] == @current_arch[:type] &&
- Array(arch[:bits]).include?(@current_arch[:bits])
- }
- raise Hbc::CaskError, "Cask #{@cask} depends on hardware architecture being one of [#{@cask.depends_on.arch.map(&:to_s).join(", ")}], but you are running #{@current_arch}"
- end
+ def cask_dependencies
+ return unless @cask.depends_on.cask && !@cask.depends_on.cask.empty?
+ ohai "Installing Cask dependencies: #{@cask.depends_on.cask.join(", ")}"
+ deps = CaskDependencies.new(@cask)
+ deps.sorted.each do |dep_token|
+ puts "#{dep_token} ..."
+ dep = Hbc.load(dep_token)
+ if dep.installed?
+ puts "already installed"
+ else
+ Installer.new(dep, force: false, skip_cask_deps: true).install
+ puts "done"
+ end
+ end
+ end
- def x11_dependencies
- return unless @cask.depends_on.x11
- raise Hbc::CaskX11DependencyError, @cask.token if Hbc.x11_libpng.select(&:exist?).empty?
- end
+ def print_caveats
+ self.class.print_caveats(@cask)
+ end
- def formula_dependencies
- return unless @cask.depends_on.formula && !@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(Hbc.homebrew_executable,
- args: ["list", "--versions", dep_name],
- print_stderr: false).stdout.include?(dep_name)
- if installed
- puts "already installed"
+ # TODO: logically could be in a separate class
+ def enable_accessibility_access
+ return unless @cask.accessibility_access
+ ohai "Enabling accessibility access"
+ if MacOS.version <= :mountain_lion
+ @command.run!("/usr/bin/touch",
+ args: [Hbc.pre_mavericks_accessibility_dotfile],
+ sudo: true)
+ elsif MacOS.version <= :yosemite
+ @command.run!("/usr/bin/sqlite3",
+ args: [
+ Hbc.tcc_db,
+ "INSERT OR REPLACE INTO access VALUES('kTCCServiceAccessibility','#{bundle_identifier}',0,1,1,NULL);",
+ ],
+ sudo: true)
+ elsif MacOS.version <= :el_capitan
+ @command.run!("/usr/bin/sqlite3",
+ args: [
+ Hbc.tcc_db,
+ "INSERT OR REPLACE INTO access VALUES('kTCCServiceAccessibility','#{bundle_identifier}',0,1,1,NULL,NULL);",
+ ],
+ sudo: true)
else
- @command.run!(Hbc.homebrew_executable,
- args: ["install", dep_name])
- puts "done"
+ opoo <<-EOS.undent
+ Accessibility access cannot be enabled automatically on this version of macOS.
+ See System Preferences to enable it manually.
+ EOS
end
end
- end
- def cask_dependencies
- return unless @cask.depends_on.cask && !@cask.depends_on.cask.empty?
- ohai "Installing Cask dependencies: #{@cask.depends_on.cask.join(", ")}"
- deps = Hbc::CaskDependencies.new(@cask)
- deps.sorted.each do |dep_token|
- puts "#{dep_token} ..."
- dep = Hbc.load(dep_token)
- if dep.installed?
- puts "already installed"
+ def disable_accessibility_access
+ return unless @cask.accessibility_access
+ if MacOS.version >= :mavericks && MacOS.version <= :el_capitan
+ ohai "Disabling accessibility access"
+ @command.run!("/usr/bin/sqlite3",
+ args: [
+ Hbc.tcc_db,
+ "DELETE FROM access WHERE client='#{bundle_identifier}';",
+ ],
+ sudo: true)
else
- Hbc::Installer.new(dep, force: false, skip_cask_deps: true).install
- puts "done"
+ opoo <<-EOS.undent
+ Accessibility access cannot be disabled automatically on this version of macOS.
+ See System Preferences to disable it manually.
+ EOS
end
end
- end
-
- def print_caveats
- self.class.print_caveats(@cask)
- end
- # TODO: logically could be in a separate class
- def enable_accessibility_access
- return unless @cask.accessibility_access
- ohai "Enabling accessibility access"
- if MacOS.version <= :mountain_lion
- @command.run!("/usr/bin/touch",
- args: [Hbc.pre_mavericks_accessibility_dotfile],
- sudo: true)
- elsif MacOS.version <= :yosemite
- @command.run!("/usr/bin/sqlite3",
- args: [
- Hbc.tcc_db,
- "INSERT OR REPLACE INTO access VALUES('kTCCServiceAccessibility','#{bundle_identifier}',0,1,1,NULL);",
- ],
- sudo: true)
- elsif MacOS.version <= :el_capitan
- @command.run!("/usr/bin/sqlite3",
- args: [
- Hbc.tcc_db,
- "INSERT OR REPLACE INTO access VALUES('kTCCServiceAccessibility','#{bundle_identifier}',0,1,1,NULL,NULL);",
- ],
- sudo: true)
- else
- opoo <<-EOS.undent
- Accessibility access cannot be enabled automatically on this version of macOS.
- See System Preferences to enable it manually.
- EOS
+ def save_caskfile
+ timestamp = :now
+ create = true
+ savedir = @cask.metadata_subdir("Casks", timestamp, create)
+ if Dir.entries(savedir).size > 2
+ # should not happen
+ raise CaskAlreadyInstalledError, @cask unless force
+ savedir.rmtree
+ FileUtils.mkdir_p savedir
+ end
+ FileUtils.copy(@cask.sourcefile_path, savedir) if @cask.sourcefile_path
end
- end
- def disable_accessibility_access
- return unless @cask.accessibility_access
- if MacOS.version >= :mavericks && MacOS.version <= :el_capitan
- ohai "Disabling accessibility access"
- @command.run!("/usr/bin/sqlite3",
- args: [
- Hbc.tcc_db,
- "DELETE FROM access WHERE client='#{bundle_identifier}';",
- ],
- sudo: true)
- else
- opoo <<-EOS.undent
- Accessibility access cannot be disabled automatically on this version of macOS.
- See System Preferences to disable it manually.
- EOS
+ def uninstall
+ odebug "Hbc::Installer.uninstall"
+ disable_accessibility_access
+ uninstall_artifacts
+ purge_versioned_files
+ purge_caskroom_path if force
end
- end
- def save_caskfile
- timestamp = :now
- create = true
- savedir = @cask.metadata_subdir("Casks", timestamp, create)
- if Dir.entries(savedir).size > 2
- # should not happen
- raise Hbc::CaskAlreadyInstalledError, @cask unless force
- savedir.rmtree
- FileUtils.mkdir_p savedir
+ def uninstall_artifacts
+ odebug "Un-installing artifacts"
+ artifacts = Artifact.for_cask(@cask)
+ odebug "#{artifacts.length} artifact/s defined", artifacts
+ artifacts.each do |artifact|
+ odebug "Un-installing artifact of class #{artifact}"
+ options = { command: @command, force: force }
+ artifact.new(@cask, options).uninstall_phase
+ end
end
- FileUtils.copy(@cask.sourcefile_path, savedir) if @cask.sourcefile_path
- end
- def uninstall
- odebug "Hbc::Installer.uninstall"
- disable_accessibility_access
- uninstall_artifacts
- purge_versioned_files
- purge_caskroom_path if force
- end
-
- def uninstall_artifacts
- odebug "Un-installing artifacts"
- artifacts = Hbc::Artifact.for_cask(@cask)
- odebug "#{artifacts.length} artifact/s defined", artifacts
- artifacts.each do |artifact|
- odebug "Un-installing artifact of class #{artifact}"
- options = { command: @command, force: force }
- artifact.new(@cask, options).uninstall_phase
+ def zap
+ ohai %Q{Implied "brew cask uninstall #{@cask}"}
+ uninstall_artifacts
+ if Artifact::Zap.me?(@cask)
+ ohai "Dispatching zap stanza"
+ Artifact::Zap.new(@cask, command: @command).zap_phase
+ else
+ opoo "No zap stanza present for Cask '#{@cask}'"
+ end
+ ohai "Removing all staged versions of Cask '#{@cask}'"
+ purge_caskroom_path
end
- end
- def zap
- ohai %Q{Implied "brew cask uninstall #{@cask}"}
- uninstall_artifacts
- if Hbc::Artifact::Zap.me?(@cask)
- ohai "Dispatching zap stanza"
- Hbc::Artifact::Zap.new(@cask, command: @command).zap_phase
- else
- opoo "No zap stanza present for Cask '#{@cask}'"
+ def gain_permissions_remove(path)
+ Utils.gain_permissions_remove(path, command: @command)
end
- ohai "Removing all staged versions of Cask '#{@cask}'"
- purge_caskroom_path
- end
- def gain_permissions_remove(path)
- Hbc::Utils.gain_permissions_remove(path, command: @command)
- end
+ def purge_versioned_files
+ odebug "Purging files for version #{@cask.version} of Cask #{@cask}"
- def purge_versioned_files
- odebug "Purging files for version #{@cask.version} of Cask #{@cask}"
+ # versioned staged distribution
+ gain_permissions_remove(@cask.staged_path) if !@cask.staged_path.nil? && @cask.staged_path.exist?
- # versioned staged distribution
- gain_permissions_remove(@cask.staged_path) if !@cask.staged_path.nil? && @cask.staged_path.exist?
-
- # Homebrew-Cask metadata
- if @cask.metadata_versioned_container_path.respond_to?(:children) &&
- @cask.metadata_versioned_container_path.exist?
- @cask.metadata_versioned_container_path.children.each do |subdir|
- unless PERSISTENT_METADATA_SUBDIRS.include?(subdir.basename)
- gain_permissions_remove(subdir)
+ # Homebrew-Cask metadata
+ if @cask.metadata_versioned_container_path.respond_to?(:children) &&
+ @cask.metadata_versioned_container_path.exist?
+ @cask.metadata_versioned_container_path.children.each do |subdir|
+ unless PERSISTENT_METADATA_SUBDIRS.include?(subdir.basename)
+ gain_permissions_remove(subdir)
+ end
end
end
- end
- @cask.metadata_versioned_container_path.rmdir_if_possible
- @cask.metadata_master_container_path.rmdir_if_possible
+ @cask.metadata_versioned_container_path.rmdir_if_possible
+ @cask.metadata_master_container_path.rmdir_if_possible
- # toplevel staged distribution
- @cask.caskroom_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}"
- gain_permissions_remove(@cask.caskroom_path)
+ def purge_caskroom_path
+ odebug "Purging all staged versions of Cask #{@cask}"
+ gain_permissions_remove(@cask.caskroom_path)
+ end
end
end