diff options
| author | Markus Reiter | 2016-09-24 13:52:43 +0200 |
|---|---|---|
| committer | Markus Reiter | 2016-09-24 16:00:58 +0200 |
| commit | b86c8efb79b3ed835d552c4d7416640ef10caf21 (patch) | |
| tree | 7e1edc8a8f339e4d2781f43576d40c9c79aebcdc /Library/Homebrew/cask/lib/hbc/artifact | |
| parent | 687f0fcf721c8e36f32570ed72d0988a6eaf986f (diff) | |
| download | brew-b86c8efb79b3ed835d552c4d7416640ef10caf21.tar.bz2 | |
Cask: Use nested classes and modules.
Diffstat (limited to 'Library/Homebrew/cask/lib/hbc/artifact')
29 files changed, 765 insertions, 649 deletions
diff --git a/Library/Homebrew/cask/lib/hbc/artifact/abstract_flight_block.rb b/Library/Homebrew/cask/lib/hbc/artifact/abstract_flight_block.rb index c879fc2be..30709a0b5 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/abstract_flight_block.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/abstract_flight_block.rb @@ -1,36 +1,40 @@ require "hbc/artifact/base" -class Hbc::Artifact::AbstractFlightBlock < Hbc::Artifact::Base - def self.artifact_dsl_key - super.to_s.sub(%r{_block$}, "").to_sym - end - - def self.uninstall_artifact_dsl_key - artifact_dsl_key.to_s.prepend("uninstall_").to_sym - end - - def self.class_for_dsl_key(dsl_key) - Object.const_get("Hbc::DSL::#{dsl_key.to_s.split("_").collect(&:capitalize).join}") - end - - def self.me?(cask) - cask.artifacts[artifact_dsl_key].any? || - cask.artifacts[uninstall_artifact_dsl_key].any? - end - - def install_phase - abstract_phase(self.class.artifact_dsl_key) - end - - def uninstall_phase - abstract_phase(self.class.uninstall_artifact_dsl_key) - end - - private - - def abstract_phase(dsl_key) - @cask.artifacts[dsl_key].each do |block| - self.class.class_for_dsl_key(dsl_key).new(@cask).instance_eval(&block) +module Hbc + module Artifact + class AbstractFlightBlock < Base + def self.artifact_dsl_key + super.to_s.sub(%r{_block$}, "").to_sym + end + + def self.uninstall_artifact_dsl_key + artifact_dsl_key.to_s.prepend("uninstall_").to_sym + end + + def self.class_for_dsl_key(dsl_key) + Object.const_get("Hbc::DSL::#{dsl_key.to_s.split("_").collect(&:capitalize).join}") + end + + def self.me?(cask) + cask.artifacts[artifact_dsl_key].any? || + cask.artifacts[uninstall_artifact_dsl_key].any? + end + + def install_phase + abstract_phase(self.class.artifact_dsl_key) + end + + def uninstall_phase + abstract_phase(self.class.uninstall_artifact_dsl_key) + end + + private + + def abstract_phase(dsl_key) + @cask.artifacts[dsl_key].each do |block| + self.class.class_for_dsl_key(dsl_key).new(@cask).instance_eval(&block) + end + end end end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/app.rb b/Library/Homebrew/cask/lib/hbc/artifact/app.rb index bbda16f74..cc6ef61a7 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/app.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/app.rb @@ -1,4 +1,8 @@ require "hbc/artifact/moved" -class Hbc::Artifact::App < Hbc::Artifact::Moved +module Hbc + module Artifact + class App < Moved + end + end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/artifact.rb b/Library/Homebrew/cask/lib/hbc/artifact/artifact.rb index e2c06eb70..cb35821cc 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/artifact.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/artifact.rb @@ -1,20 +1,24 @@ require "hbc/artifact/moved" -class Hbc::Artifact::Artifact < Hbc::Artifact::Moved - def self.artifact_english_name - "Generic Artifact" - end +module Hbc + module Artifact + class Artifact < Moved + def self.artifact_english_name + "Generic Artifact" + end - def self.artifact_dirmethod - :appdir - end + def self.artifact_dirmethod + :appdir + end - def load_specification(artifact_spec) - source_string, target_hash = artifact_spec - raise Hbc::CaskInvalidError.new(@cask.token, "no source given for artifact") if source_string.nil? - @source = @cask.staged_path.join(source_string) - raise Hbc::CaskInvalidError.new(@cask.token, "target required for generic artifact #{source_string}") unless target_hash.is_a?(Hash) - target_hash.assert_valid_keys(:target) - @target = Pathname.new(target_hash[:target]) + def load_specification(artifact_spec) + source_string, target_hash = artifact_spec + raise CaskInvalidError.new(@cask.token, "no source given for artifact") if source_string.nil? + @source = @cask.staged_path.join(source_string) + raise CaskInvalidError.new(@cask.token, "target required for generic artifact #{source_string}") unless target_hash.is_a?(Hash) + target_hash.assert_valid_keys(:target) + @target = Pathname.new(target_hash[:target]) + end + end end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/audio_unit_plugin.rb b/Library/Homebrew/cask/lib/hbc/artifact/audio_unit_plugin.rb index 7f3999306..3bad78073 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/audio_unit_plugin.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/audio_unit_plugin.rb @@ -1,4 +1,8 @@ require "hbc/artifact/moved" -class Hbc::Artifact::AudioUnitPlugin < Hbc::Artifact::Moved +module Hbc + module Artifact + class AudioUnitPlugin < Moved + end + end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/base.rb b/Library/Homebrew/cask/lib/hbc/artifact/base.rb index 9a07cc906..141ab6881 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/base.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/base.rb @@ -1,79 +1,83 @@ -class Hbc::Artifact::Base - def self.artifact_name - @artifact_name ||= name.sub(%r{^.*:}, "").gsub(%r{(.)([A-Z])}, '\1_\2').downcase - end - - def self.artifact_english_name - @artifact_english_name ||= name.sub(%r{^.*:}, "").gsub(%r{(.)([A-Z])}, '\1 \2') - end - - def self.artifact_english_article - @artifact_english_article ||= artifact_english_name =~ %r{^[aeiou]}i ? "an" : "a" - end - - def self.artifact_dsl_key - @artifact_dsl_key ||= artifact_name.to_sym - end - - def self.artifact_dirmethod - @artifact_dirmethod ||= "#{artifact_name}dir".to_sym - end - - def self.me?(cask) - cask.artifacts[artifact_dsl_key].any? - end - - attr_reader :force - - def zap_phase - odebug "Nothing to do. The #{self.class.artifact_name} artifact has no zap phase." - end - - # TODO: this sort of logic would make more sense in dsl.rb, or a - # constructor called from dsl.rb, so long as that isn't slow. - def self.read_script_arguments(arguments, stanza, default_arguments = {}, override_arguments = {}, key = nil) - # TODO: when stanza names are harmonized with class names, - # stanza may not be needed as an explicit argument - description = stanza.to_s - if key - arguments = arguments[key] - description.concat(" #{key.inspect}") - end - - # backward-compatible string value - arguments = { executable: arguments } if arguments.is_a?(String) - - # key sanity - permitted_keys = [:args, :input, :executable, :must_succeed, :sudo, :bsexec, :print_stdout, :print_stderr] - unknown_keys = arguments.keys - permitted_keys - unless unknown_keys.empty? - opoo %Q{Unknown arguments to #{description} -- #{unknown_keys.inspect} (ignored). Running "brew update; brew cleanup; brew cask cleanup" will likely fix it.} +module Hbc + module Artifact + class Base + def self.artifact_name + @artifact_name ||= name.sub(%r{^.*:}, "").gsub(%r{(.)([A-Z])}, '\1_\2').downcase + end + + def self.artifact_english_name + @artifact_english_name ||= name.sub(%r{^.*:}, "").gsub(%r{(.)([A-Z])}, '\1 \2') + end + + def self.artifact_english_article + @artifact_english_article ||= artifact_english_name =~ %r{^[aeiou]}i ? "an" : "a" + end + + def self.artifact_dsl_key + @artifact_dsl_key ||= artifact_name.to_sym + end + + def self.artifact_dirmethod + @artifact_dirmethod ||= "#{artifact_name}dir".to_sym + end + + def self.me?(cask) + cask.artifacts[artifact_dsl_key].any? + end + + attr_reader :force + + def zap_phase + odebug "Nothing to do. The #{self.class.artifact_name} artifact has no zap phase." + end + + # TODO: this sort of logic would make more sense in dsl.rb, or a + # constructor called from dsl.rb, so long as that isn't slow. + def self.read_script_arguments(arguments, stanza, default_arguments = {}, override_arguments = {}, key = nil) + # TODO: when stanza names are harmonized with class names, + # stanza may not be needed as an explicit argument + description = stanza.to_s + if key + arguments = arguments[key] + description.concat(" #{key.inspect}") + end + + # backward-compatible string value + arguments = { executable: arguments } if arguments.is_a?(String) + + # key sanity + permitted_keys = [:args, :input, :executable, :must_succeed, :sudo, :bsexec, :print_stdout, :print_stderr] + unknown_keys = arguments.keys - permitted_keys + unless unknown_keys.empty? + opoo %Q{Unknown arguments to #{description} -- #{unknown_keys.inspect} (ignored). Running "brew update; brew cleanup; brew cask cleanup" will likely fix it.} + end + arguments.reject! { |k| !permitted_keys.include?(k) } + + # key warnings + override_keys = override_arguments.keys + ignored_keys = arguments.keys & override_keys + unless ignored_keys.empty? + onoe "Some arguments to #{description} will be ignored -- :#{unknown_keys.inspect} (overridden)." + end + + # extract executable + executable = arguments.key?(:executable) ? arguments.delete(:executable) : nil + + arguments = default_arguments.merge arguments + arguments.merge! override_arguments + + [executable, arguments] + end + + def summary + {} + end + + def initialize(cask, command: SystemCommand, force: false) + @cask = cask + @command = command + @force = force + end end - arguments.reject! { |k| !permitted_keys.include?(k) } - - # key warnings - override_keys = override_arguments.keys - ignored_keys = arguments.keys & override_keys - unless ignored_keys.empty? - onoe "Some arguments to #{description} will be ignored -- :#{unknown_keys.inspect} (overridden)." - end - - # extract executable - executable = arguments.key?(:executable) ? arguments.delete(:executable) : nil - - arguments = default_arguments.merge arguments - arguments.merge! override_arguments - - [executable, arguments] - end - - def summary - {} - end - - def initialize(cask, command: Hbc::SystemCommand, force: false) - @cask = cask - @command = command - @force = force end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/binary.rb b/Library/Homebrew/cask/lib/hbc/artifact/binary.rb index ccaebe0c8..646e5c3ad 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/binary.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/binary.rb @@ -1,7 +1,11 @@ require "hbc/artifact/symlinked" -class Hbc::Artifact::Binary < Hbc::Artifact::Symlinked - def install_phase - super unless Hbc.no_binaries +module Hbc + module Artifact + class Binary < Symlinked + def install_phase + super unless Hbc.no_binaries + end + end end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/colorpicker.rb b/Library/Homebrew/cask/lib/hbc/artifact/colorpicker.rb index 7b56d0ffc..a866e64a5 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/colorpicker.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/colorpicker.rb @@ -1,4 +1,8 @@ require "hbc/artifact/moved" -class Hbc::Artifact::Colorpicker < Hbc::Artifact::Moved +module Hbc + module Artifact + class Colorpicker < Moved + end + end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/font.rb b/Library/Homebrew/cask/lib/hbc/artifact/font.rb index 9697d9e13..5c64869b6 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/font.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/font.rb @@ -1,4 +1,8 @@ require "hbc/artifact/moved" -class Hbc::Artifact::Font < Hbc::Artifact::Moved +module Hbc + module Artifact + class Font < Moved + end + end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/input_method.rb b/Library/Homebrew/cask/lib/hbc/artifact/input_method.rb index 3c7f3d990..0eb75a6c0 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/input_method.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/input_method.rb @@ -1,4 +1,8 @@ require "hbc/artifact/moved" -class Hbc::Artifact::InputMethod < Hbc::Artifact::Moved +module Hbc + module Artifact + class InputMethod < Moved + end + end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/installer.rb b/Library/Homebrew/cask/lib/hbc/artifact/installer.rb index 2f66397e9..b64b00fe3 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/installer.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/installer.rb @@ -1,41 +1,45 @@ require "hbc/artifact/base" -class Hbc::Artifact::Installer < Hbc::Artifact::Base - # TODO: for backward compatibility, removeme - def install - install_phase - end +module Hbc + module Artifact + class Installer < Base + # TODO: for backward compatibility, removeme + def install + install_phase + end - # TODO: for backward compatibility, removeme - def uninstall - uninstall_phase - end + # TODO: for backward compatibility, removeme + def uninstall + uninstall_phase + end - def install_phase - @cask.artifacts[self.class.artifact_dsl_key].each do |artifact| - if artifact.manual - puts <<-EOS.undent - To complete the installation of Cask #{@cask}, you must also - run the installer at + def install_phase + @cask.artifacts[self.class.artifact_dsl_key].each do |artifact| + if artifact.manual + puts <<-EOS.undent + To complete the installation of Cask #{@cask}, you must also + run the installer at - '#{@cask.staged_path.join(artifact.manual)}' + '#{@cask.staged_path.join(artifact.manual)}' - EOS - else - executable, script_arguments = self.class.read_script_arguments(artifact.script, - self.class.artifact_dsl_key.to_s, - { must_succeed: true, sudo: true }, - print_stdout: true) - ohai "Running #{self.class.artifact_dsl_key} script #{executable}" - raise Hbc::CaskInvalidError.new(@cask, "#{self.class.artifact_dsl_key} missing executable") if executable.nil? - executable_path = @cask.staged_path.join(executable) - @command.run("/bin/chmod", args: ["--", "+x", executable_path]) if File.exist?(executable_path) - @command.run(executable_path, script_arguments) + EOS + else + executable, script_arguments = self.class.read_script_arguments(artifact.script, + self.class.artifact_dsl_key.to_s, + { must_succeed: true, sudo: true }, + print_stdout: true) + ohai "Running #{self.class.artifact_dsl_key} script #{executable}" + raise CaskInvalidError.new(@cask, "#{self.class.artifact_dsl_key} missing executable") if executable.nil? + executable_path = @cask.staged_path.join(executable) + @command.run("/bin/chmod", args: ["--", "+x", executable_path]) if File.exist?(executable_path) + @command.run(executable_path, script_arguments) + end + end end - end - end - def uninstall_phase - odebug "Nothing to do. The #{self.class.artifact_dsl_key} artifact has no uninstall phase." + def uninstall_phase + odebug "Nothing to do. The #{self.class.artifact_dsl_key} artifact has no uninstall phase." + end + end end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/internet_plugin.rb b/Library/Homebrew/cask/lib/hbc/artifact/internet_plugin.rb index a44418274..ab8586d69 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/internet_plugin.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/internet_plugin.rb @@ -1,4 +1,8 @@ require "hbc/artifact/moved" -class Hbc::Artifact::InternetPlugin < Hbc::Artifact::Moved +module Hbc + module Artifact + class InternetPlugin < Moved + end + end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/moved.rb b/Library/Homebrew/cask/lib/hbc/artifact/moved.rb index 8f41e9fd5..6095887e3 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/moved.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/moved.rb @@ -1,88 +1,92 @@ require "hbc/artifact/relocated" -class Hbc::Artifact::Moved < Hbc::Artifact::Relocated - def self.english_description - "#{artifact_english_name}s" - end +module Hbc + module Artifact + class Moved < Relocated + def self.english_description + "#{artifact_english_name}s" + end - def install_phase - each_artifact do |artifact| - load_specification(artifact) - next unless preflight_checks - delete if Hbc::Utils.path_occupied?(target) && force - move - end - end + def install_phase + each_artifact do |artifact| + load_specification(artifact) + next unless preflight_checks + delete if Utils.path_occupied?(target) && force + move + end + end - def uninstall_phase - each_artifact do |artifact| - load_specification(artifact) - next unless File.exist?(target) - delete - end - end + def uninstall_phase + each_artifact do |artifact| + load_specification(artifact) + next unless File.exist?(target) + delete + end + end - private + private - def each_artifact - # the sort is for predictability between Ruby versions - @cask.artifacts[self.class.artifact_dsl_key].sort.each do |artifact| - yield artifact - end - end + def each_artifact + # the sort is for predictability between Ruby versions + @cask.artifacts[self.class.artifact_dsl_key].sort.each do |artifact| + yield artifact + end + end - def move - ohai "Moving #{self.class.artifact_english_name} '#{source.basename}' to '#{target}'" - target.dirname.mkpath - FileUtils.move(source, target) - add_altname_metadata target, source.basename.to_s - end + def move + ohai "Moving #{self.class.artifact_english_name} '#{source.basename}' to '#{target}'" + target.dirname.mkpath + FileUtils.move(source, target) + add_altname_metadata target, source.basename.to_s + end - def preflight_checks - if Hbc::Utils.path_occupied?(target) - if force - ohai(warning_target_exists { |s| s << "overwriting." }) - else - ohai(warning_target_exists { |s| s << "not moving." }) - return false + def preflight_checks + if Utils.path_occupied?(target) + if force + ohai(warning_target_exists { |s| s << "overwriting." }) + else + ohai(warning_target_exists { |s| s << "not moving." }) + return false + end + end + unless source.exist? + message = "It seems the #{self.class.artifact_english_name} source is not there: '#{source}'" + raise CaskError, message + end + true end - end - unless source.exist? - message = "It seems the #{self.class.artifact_english_name} source is not there: '#{source}'" - raise Hbc::CaskError, message - end - true - end - def warning_target_exists - message_parts = [ - "It seems there is already #{self.class.artifact_english_article} #{self.class.artifact_english_name} at '#{target}'", - ] - yield(message_parts) if block_given? - message_parts.join("; ") - end + def warning_target_exists + message_parts = [ + "It seems there is already #{self.class.artifact_english_article} #{self.class.artifact_english_name} at '#{target}'", + ] + yield(message_parts) if block_given? + message_parts.join("; ") + end - def delete - ohai "Removing #{self.class.artifact_english_name}: '#{target}'" - raise Hbc::CaskError, "Cannot remove undeletable #{self.class.artifact_english_name}" if MacOS.undeletable?(target) + def delete + ohai "Removing #{self.class.artifact_english_name}: '#{target}'" + raise CaskError, "Cannot remove undeletable #{self.class.artifact_english_name}" if MacOS.undeletable?(target) - if force - Hbc::Utils.gain_permissions_remove(target, command: @command) - else - target.rmtree - end - end + if force + Utils.gain_permissions_remove(target, command: @command) + else + target.rmtree + end + end - def summarize_artifact(artifact_spec) - load_specification artifact_spec + def summarize_artifact(artifact_spec) + load_specification artifact_spec - if target.exist? - target_abv = " (#{target.abv})" - else - warning = "Missing #{self.class.artifact_english_name}" - warning = "#{Tty.red}#{warning}#{Tty.reset}: " - end + if target.exist? + target_abv = " (#{target.abv})" + else + warning = "Missing #{self.class.artifact_english_name}" + warning = "#{Tty.red}#{warning}#{Tty.reset}: " + end - "#{warning}#{printable_target}#{target_abv}" + "#{warning}#{printable_target}#{target_abv}" + end + end end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/nested_container.rb b/Library/Homebrew/cask/lib/hbc/artifact/nested_container.rb index 68e4a552c..107640797 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/nested_container.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/nested_container.rb @@ -1,24 +1,28 @@ require "hbc/artifact/base" -class Hbc::Artifact::NestedContainer < Hbc::Artifact::Base - def install_phase - @cask.artifacts[:nested_container].each { |container| extract(container) } - end +module Hbc + module Artifact + class NestedContainer < Base + def install_phase + @cask.artifacts[:nested_container].each { |container| extract(container) } + end - def uninstall_phase - # no need to take action; is removed after extraction - end + def uninstall_phase + # no need to take action; is removed after extraction + end - def extract(container_relative_path) - source = @cask.staged_path.join(container_relative_path) - container = Hbc::Container.for_path(source, @command) + def extract(container_relative_path) + source = @cask.staged_path.join(container_relative_path) + container = Container.for_path(source, @command) - unless container - raise Hbc::CaskError, "Aw dang, could not identify nested container at '#{source}'" - end + unless container + raise CaskError, "Aw dang, could not identify nested container at '#{source}'" + end - ohai "Extracting nested container #{source.basename}" - container.new(@cask, source, @command).extract - FileUtils.remove_entry_secure(source) + ohai "Extracting nested container #{source.basename}" + container.new(@cask, source, @command).extract + FileUtils.remove_entry_secure(source) + end + end end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/pkg.rb b/Library/Homebrew/cask/lib/hbc/artifact/pkg.rb index fb27308d7..e590a9082 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/pkg.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/pkg.rb @@ -1,53 +1,57 @@ require "hbc/artifact/base" -class Hbc::Artifact::Pkg < Hbc::Artifact::Base - attr_reader :pkg_relative_path +module Hbc + module Artifact + class Pkg < Base + attr_reader :pkg_relative_path - def self.artifact_dsl_key - :pkg - end + def self.artifact_dsl_key + :pkg + end - def load_pkg_description(pkg_description) - @pkg_relative_path = pkg_description.shift - @pkg_install_opts = pkg_description.shift - begin - if @pkg_install_opts.respond_to?(:keys) - @pkg_install_opts.assert_valid_keys(:allow_untrusted) - elsif @pkg_install_opts - raise + def load_pkg_description(pkg_description) + @pkg_relative_path = pkg_description.shift + @pkg_install_opts = pkg_description.shift + begin + if @pkg_install_opts.respond_to?(:keys) + @pkg_install_opts.assert_valid_keys(:allow_untrusted) + elsif @pkg_install_opts + raise + end + raise if pkg_description.nil? + rescue StandardError + raise CaskInvalidError.new(@cask, "Bad pkg stanza") + end end - raise if pkg_description.nil? - rescue StandardError - raise Hbc::CaskInvalidError.new(@cask, "Bad pkg stanza") - end - end - def pkg_install_opts(opt) - @pkg_install_opts[opt] if @pkg_install_opts.respond_to?(:keys) - end + def pkg_install_opts(opt) + @pkg_install_opts[opt] if @pkg_install_opts.respond_to?(:keys) + end - def install_phase - @cask.artifacts[:pkg].each { |pkg_description| run_installer(pkg_description) } - end + def install_phase + @cask.artifacts[:pkg].each { |pkg_description| run_installer(pkg_description) } + end - def uninstall_phase - # Do nothing. Must be handled explicitly by a separate :uninstall stanza. - end + def uninstall_phase + # Do nothing. Must be handled explicitly by a separate :uninstall stanza. + end - def run_installer(pkg_description) - load_pkg_description pkg_description - ohai "Running installer for #{@cask}; your password may be necessary." - ohai "Package installers may write to any location; options such as --appdir are ignored." - source = @cask.staged_path.join(pkg_relative_path) - unless source.exist? - raise Hbc::CaskError, "pkg source file not found: '#{source}'" + def run_installer(pkg_description) + load_pkg_description pkg_description + ohai "Running installer for #{@cask}; your password may be necessary." + ohai "Package installers may write to any location; options such as --appdir are ignored." + source = @cask.staged_path.join(pkg_relative_path) + unless source.exist? + raise CaskError, "pkg source file not found: '#{source}'" + end + args = [ + "-pkg", source, + "-target", "/" + ] + args << "-verboseR" if Hbc.verbose + args << "-allowUntrusted" if pkg_install_opts :allow_untrusted + @command.run!("/usr/sbin/installer", sudo: true, args: args, print_stdout: true) + end end - args = [ - "-pkg", source, - "-target", "/" - ] - args << "-verboseR" if Hbc.verbose - args << "-allowUntrusted" if pkg_install_opts :allow_untrusted - @command.run!("/usr/sbin/installer", sudo: true, args: args, print_stdout: true) end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/postflight_block.rb b/Library/Homebrew/cask/lib/hbc/artifact/postflight_block.rb index 92b21a83f..bfe218f95 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/postflight_block.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/postflight_block.rb @@ -1,4 +1,8 @@ require "hbc/artifact/abstract_flight_block" -class Hbc::Artifact::PostflightBlock < Hbc::Artifact::AbstractFlightBlock +module Hbc + module Artifact + class PostflightBlock < AbstractFlightBlock + end + end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/preflight_block.rb b/Library/Homebrew/cask/lib/hbc/artifact/preflight_block.rb index 772a88016..35142df47 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/preflight_block.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/preflight_block.rb @@ -1,4 +1,8 @@ require "hbc/artifact/abstract_flight_block" -class Hbc::Artifact::PreflightBlock < Hbc::Artifact::AbstractFlightBlock +module Hbc + module Artifact + class PreflightBlock < AbstractFlightBlock + end + end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/prefpane.rb b/Library/Homebrew/cask/lib/hbc/artifact/prefpane.rb index e45cc0b19..a44f8ae3a 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/prefpane.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/prefpane.rb @@ -1,7 +1,11 @@ require "hbc/artifact/moved" -class Hbc::Artifact::Prefpane < Hbc::Artifact::Moved - def self.artifact_english_name - "Preference Pane" +module Hbc + module Artifact + class Prefpane < Moved + def self.artifact_english_name + "Preference Pane" + end + end end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/qlplugin.rb b/Library/Homebrew/cask/lib/hbc/artifact/qlplugin.rb index 6702aa5ef..ee41de2fe 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/qlplugin.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/qlplugin.rb @@ -1,21 +1,25 @@ require "hbc/artifact/moved" -class Hbc::Artifact::Qlplugin < Hbc::Artifact::Moved - def self.artifact_english_name - "QuickLook Plugin" - end +module Hbc + module Artifact + class Qlplugin < Moved + def self.artifact_english_name + "QuickLook Plugin" + end - def install_phase - super - reload_quicklook - end + def install_phase + super + reload_quicklook + end - def uninstall_phase - super - reload_quicklook - end + def uninstall_phase + super + reload_quicklook + end - def reload_quicklook - @command.run!("/usr/bin/qlmanage", args: ["-r"]) + def reload_quicklook + @command.run!("/usr/bin/qlmanage", args: ["-r"]) + end + end end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/relocated.rb b/Library/Homebrew/cask/lib/hbc/artifact/relocated.rb index cd0054188..953045b32 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/relocated.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/relocated.rb @@ -1,53 +1,57 @@ require "hbc/artifact/base" -class Hbc::Artifact::Relocated < Hbc::Artifact::Base - def summary - { - english_description: self.class.english_description, - contents: @cask.artifacts[self.class.artifact_dsl_key].map(&method(:summarize_artifact)).compact, - } - end - - attr_reader :source, :target - - def printable_target - target.to_s.sub(%r{^#{ENV['HOME']}(#{File::SEPARATOR}|$)}, "~/") - end - - ALT_NAME_ATTRIBUTE = "com.apple.metadata:kMDItemAlternateNames".freeze - - # Try to make the asset searchable under the target name. Spotlight - # respects this attribute for many filetypes, but ignores it for App - # bundles. Alfred 2.2 respects it even for App bundles. - def add_altname_metadata(file, altname) - return if altname.casecmp(file.basename).zero? - odebug "Adding #{ALT_NAME_ATTRIBUTE} metadata" - altnames = @command.run("/usr/bin/xattr", - args: ["-p", ALT_NAME_ATTRIBUTE, file.to_s], - print_stderr: false).stdout.sub(%r{\A\((.*)\)\Z}, '\1') - odebug "Existing metadata is: '#{altnames}'" - altnames.concat(", ") unless altnames.empty? - altnames.concat(%Q{"#{altname}"}) - altnames = "(#{altnames})" - - # Some packges are shipped as u=rx (e.g. Bitcoin Core) - @command.run!("/bin/chmod", args: ["--", "u=rwx", file.to_s, file.realpath.to_s]) - - @command.run!("/usr/bin/xattr", - args: ["-w", ALT_NAME_ATTRIBUTE, altnames, file.to_s], - print_stderr: false) - end - - def load_specification(artifact_spec) - source_string, target_hash = artifact_spec - raise Hbc::CaskInvalidError if source_string.nil? - @source = @cask.staged_path.join(source_string) - if target_hash - raise Hbc::CaskInvalidError unless target_hash.respond_to?(:keys) - target_hash.assert_valid_keys(:target) - @target = Hbc.send(self.class.artifact_dirmethod).join(target_hash[:target]) - else - @target = Hbc.send(self.class.artifact_dirmethod).join(source.basename) +module Hbc + module Artifact + class Relocated < Base + def summary + { + english_description: self.class.english_description, + contents: @cask.artifacts[self.class.artifact_dsl_key].map(&method(:summarize_artifact)).compact, + } + end + + attr_reader :source, :target + + def printable_target + target.to_s.sub(%r{^#{ENV['HOME']}(#{File::SEPARATOR}|$)}, "~/") + end + + ALT_NAME_ATTRIBUTE = "com.apple.metadata:kMDItemAlternateNames".freeze + + # Try to make the asset searchable under the target name. Spotlight + # respects this attribute for many filetypes, but ignores it for App + # bundles. Alfred 2.2 respects it even for App bundles. + def add_altname_metadata(file, altname) + return if altname.casecmp(file.basename).zero? + odebug "Adding #{ALT_NAME_ATTRIBUTE} metadata" + altnames = @command.run("/usr/bin/xattr", + args: ["-p", ALT_NAME_ATTRIBUTE, file.to_s], + print_stderr: false).stdout.sub(%r{\A\((.*)\)\Z}, '\1') + odebug "Existing metadata is: '#{altnames}'" + altnames.concat(", ") unless altnames.empty? + altnames.concat(%Q{"#{altname}"}) + altnames = "(#{altnames})" + + # Some packges are shipped as u=rx (e.g. Bitcoin Core) + @command.run!("/bin/chmod", args: ["--", "u=rwx", file.to_s, file.realpath.to_s]) + + @command.run!("/usr/bin/xattr", + args: ["-w", ALT_NAME_ATTRIBUTE, altnames, file.to_s], + print_stderr: false) + end + + def load_specification(artifact_spec) + source_string, target_hash = artifact_spec + raise CaskInvalidError if source_string.nil? + @source = @cask.staged_path.join(source_string) + if target_hash + raise CaskInvalidError unless target_hash.respond_to?(:keys) + target_hash.assert_valid_keys(:target) + @target = Hbc.send(self.class.artifact_dirmethod).join(target_hash[:target]) + else + @target = Hbc.send(self.class.artifact_dirmethod).join(source.basename) + end + end end end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/screen_saver.rb b/Library/Homebrew/cask/lib/hbc/artifact/screen_saver.rb index bbd929152..4cdc6037c 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/screen_saver.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/screen_saver.rb @@ -1,4 +1,8 @@ require "hbc/artifact/moved" -class Hbc::Artifact::ScreenSaver < Hbc::Artifact::Moved +module Hbc + module Artifact + class ScreenSaver < Moved + end + end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/service.rb b/Library/Homebrew/cask/lib/hbc/artifact/service.rb index d5a00e4fe..1af93c533 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/service.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/service.rb @@ -1,4 +1,8 @@ require "hbc/artifact/moved" -class Hbc::Artifact::Service < Hbc::Artifact::Moved +module Hbc + module Artifact + class Service < Moved + end + end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/stage_only.rb b/Library/Homebrew/cask/lib/hbc/artifact/stage_only.rb index 7a48b19aa..594c5bef9 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/stage_only.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/stage_only.rb @@ -1,15 +1,19 @@ require "hbc/artifact/base" -class Hbc::Artifact::StageOnly < Hbc::Artifact::Base - def self.artifact_dsl_key - :stage_only - end +module Hbc + module Artifact + class StageOnly < Base + def self.artifact_dsl_key + :stage_only + end - def install_phase - # do nothing - end + def install_phase + # do nothing + end - def uninstall_phase - # do nothing + def uninstall_phase + # do nothing + end + end end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/suite.rb b/Library/Homebrew/cask/lib/hbc/artifact/suite.rb index cdfb757dd..35251f70c 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/suite.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/suite.rb @@ -1,11 +1,15 @@ require "hbc/artifact/moved" -class Hbc::Artifact::Suite < Hbc::Artifact::Moved - def self.artifact_english_name - "App Suite" - end +module Hbc + module Artifact + class Suite < Moved + def self.artifact_english_name + "App Suite" + end - def self.artifact_dirmethod - :appdir + def self.artifact_dirmethod + :appdir + end + end end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/symlinked.rb b/Library/Homebrew/cask/lib/hbc/artifact/symlinked.rb index 7432df577..3ab45cccc 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/symlinked.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/symlinked.rb @@ -1,65 +1,69 @@ require "hbc/artifact/relocated" -class Hbc::Artifact::Symlinked < Hbc::Artifact::Relocated - def self.link_type_english_name - "Symlink" - end +module Hbc + module Artifact + class Symlinked < Relocated + def self.link_type_english_name + "Symlink" + end - def self.english_description - "#{artifact_english_name} #{link_type_english_name}s" - end + def self.english_description + "#{artifact_english_name} #{link_type_english_name}s" + end - def self.islink?(path) - path.symlink? - end + def self.islink?(path) + path.symlink? + end - def link(artifact_spec) - load_specification artifact_spec - return unless preflight_checks(source, target) - ohai "#{self.class.link_type_english_name}ing #{self.class.artifact_english_name} '#{source.basename}' to '#{target}'" - create_filesystem_link(source, target) - end + def link(artifact_spec) + load_specification artifact_spec + return unless preflight_checks(source, target) + ohai "#{self.class.link_type_english_name}ing #{self.class.artifact_english_name} '#{source.basename}' to '#{target}'" + create_filesystem_link(source, target) + end - def unlink(artifact_spec) - load_specification artifact_spec - return unless self.class.islink?(target) - ohai "Removing #{self.class.artifact_english_name} #{self.class.link_type_english_name.downcase}: '#{target}'" - target.delete - end + def unlink(artifact_spec) + load_specification artifact_spec + return unless self.class.islink?(target) + ohai "Removing #{self.class.artifact_english_name} #{self.class.link_type_english_name.downcase}: '#{target}'" + target.delete + end - def install_phase - @cask.artifacts[self.class.artifact_dsl_key].each(&method(:link)) - end + def install_phase + @cask.artifacts[self.class.artifact_dsl_key].each(&method(:link)) + end - def uninstall_phase - @cask.artifacts[self.class.artifact_dsl_key].each(&method(:unlink)) - end + def uninstall_phase + @cask.artifacts[self.class.artifact_dsl_key].each(&method(:unlink)) + end - def preflight_checks(source, target) - if target.exist? && !self.class.islink?(target) - ohai "It seems there is already #{self.class.artifact_english_article} #{self.class.artifact_english_name} at '#{target}'; not linking." - return false - end - unless source.exist? - raise Hbc::CaskError, "It seems the #{self.class.link_type_english_name.downcase} source is not there: '#{source}'" - end - true - end + def preflight_checks(source, target) + if target.exist? && !self.class.islink?(target) + ohai "It seems there is already #{self.class.artifact_english_article} #{self.class.artifact_english_name} at '#{target}'; not linking." + return false + end + unless source.exist? + raise CaskError, "It seems the #{self.class.link_type_english_name.downcase} source is not there: '#{source}'" + end + true + end - def create_filesystem_link(source, target) - Pathname.new(target).dirname.mkpath - @command.run!("/bin/ln", args: ["-hfs", "--", source, target]) - add_altname_metadata source, target.basename.to_s - end + def create_filesystem_link(source, target) + Pathname.new(target).dirname.mkpath + @command.run!("/bin/ln", args: ["-hfs", "--", source, target]) + add_altname_metadata source, target.basename.to_s + end - def summarize_artifact(artifact_spec) - load_specification artifact_spec + def summarize_artifact(artifact_spec) + load_specification artifact_spec - return unless self.class.islink?(target) + return unless self.class.islink?(target) - link_description = "#{Tty.red}Broken Link#{Tty.reset}: " unless target.exist? - target_readlink_abv = " (#{target.readlink.abv})" if target.readlink.exist? + link_description = "#{Tty.red}Broken Link#{Tty.reset}: " unless target.exist? + target_readlink_abv = " (#{target.readlink.abv})" if target.readlink.exist? - "#{link_description}#{printable_target} -> #{target.readlink}#{target_readlink_abv}" + "#{link_description}#{printable_target} -> #{target.readlink}#{target_readlink_abv}" + end + end end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/uninstall.rb b/Library/Homebrew/cask/lib/hbc/artifact/uninstall.rb index 12010aeb8..8b5603064 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/uninstall.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/uninstall.rb @@ -1,4 +1,8 @@ require "hbc/artifact/uninstall_base" -class Hbc::Artifact::Uninstall < Hbc::Artifact::UninstallBase +module Hbc + module Artifact + class Uninstall < UninstallBase + end + end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/uninstall_base.rb b/Library/Homebrew/cask/lib/hbc/artifact/uninstall_base.rb index f92e09a89..63ffd18c9 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/uninstall_base.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/uninstall_base.rb @@ -2,248 +2,252 @@ require "pathname" require "hbc/artifact/base" -class Hbc::Artifact::UninstallBase < Hbc::Artifact::Base - # TODO: 500 is also hardcoded in cask/pkg.rb, but much of - # that logic is probably in the wrong location - - PATH_ARG_SLICE_SIZE = 500 - - ORDERED_DIRECTIVES = [ - :early_script, - :launchctl, - :quit, - :signal, - :login_item, - :kext, - :script, - :pkgutil, - :delete, - :trash, - :rmdir, - ].freeze - - # TODO: these methods were consolidated here from separate - # sources and should be refactored for consistency - - def self.expand_path_strings(path_strings) - path_strings.map { |path_string| - path_string.start_with?("~") ? Pathname.new(path_string).expand_path : Pathname.new(path_string) - } - end +module Hbc + module Artifact + class UninstallBase < Base + # TODO: 500 is also hardcoded in cask/pkg.rb, but much of + # that logic is probably in the wrong location + + PATH_ARG_SLICE_SIZE = 500 + + ORDERED_DIRECTIVES = [ + :early_script, + :launchctl, + :quit, + :signal, + :login_item, + :kext, + :script, + :pkgutil, + :delete, + :trash, + :rmdir, + ].freeze + + # TODO: these methods were consolidated here from separate + # sources and should be refactored for consistency + + def self.expand_path_strings(path_strings) + path_strings.map { |path_string| + path_string.start_with?("~") ? Pathname.new(path_string).expand_path : Pathname.new(path_string) + } + end - def self.remove_relative_path_strings(action, path_strings) - relative = path_strings.map { |path_string| - path_string if %r{/\.\.(?:/|\Z)}.match(path_string) || !%r{\A/}.match(path_string) - }.compact - relative.each do |path_string| - opoo "Skipping #{action} for relative path #{path_string}" - end - path_strings - relative - end + def self.remove_relative_path_strings(action, path_strings) + relative = path_strings.map { |path_string| + path_string if %r{/\.\.(?:/|\Z)}.match(path_string) || !%r{\A/}.match(path_string) + }.compact + relative.each do |path_string| + opoo "Skipping #{action} for relative path #{path_string}" + end + path_strings - relative + end - def self.remove_undeletable_path_strings(action, path_strings) - undeletable = path_strings.map { |path_string| - path_string if MacOS.undeletable?(Pathname.new(path_string)) - }.compact - undeletable.each do |path_string| - opoo "Skipping #{action} for undeletable path #{path_string}" - end - path_strings - undeletable - end + def self.remove_undeletable_path_strings(action, path_strings) + undeletable = path_strings.map { |path_string| + path_string if MacOS.undeletable?(Pathname.new(path_string)) + }.compact + undeletable.each do |path_string| + opoo "Skipping #{action} for undeletable path #{path_string}" + end + path_strings - undeletable + end - def install_phase - odebug "Nothing to do. The uninstall artifact has no install phase." - end + def install_phase + odebug "Nothing to do. The uninstall artifact has no install phase." + end - def uninstall_phase - dispatch_uninstall_directives - end + def uninstall_phase + dispatch_uninstall_directives + end - def dispatch_uninstall_directives(expand_tilde = true) - directives_set = @cask.artifacts[stanza] - ohai "Running #{stanza} process for #{@cask}; your password may be necessary" + def dispatch_uninstall_directives(expand_tilde = true) + directives_set = @cask.artifacts[stanza] + ohai "Running #{stanza} process for #{@cask}; your password may be necessary" - directives_set.each do |directives| - warn_for_unknown_directives(directives) - end + directives_set.each do |directives| + warn_for_unknown_directives(directives) + end - ORDERED_DIRECTIVES.each do |directive_sym| - directives_set.select { |h| h.key?(directive_sym) }.each do |directives| - args = [directives] - args << expand_tilde if [:delete, :trash, :rmdir].include?(directive_sym) - send("uninstall_#{directive_sym}", *args) + ORDERED_DIRECTIVES.each do |directive_sym| + directives_set.select { |h| h.key?(directive_sym) }.each do |directives| + args = [directives] + args << expand_tilde if [:delete, :trash, :rmdir].include?(directive_sym) + send("uninstall_#{directive_sym}", *args) + end + end end - end - end - private + private - def stanza - self.class.artifact_dsl_key - end + def stanza + self.class.artifact_dsl_key + end - def warn_for_unknown_directives(directives) - unknown_keys = directives.keys - ORDERED_DIRECTIVES - return if unknown_keys.empty? - opoo %Q{Unknown arguments to #{stanza} -- #{unknown_keys.inspect}. Running "brew update; brew cleanup; brew cask cleanup" will likely fix it.} - end + def warn_for_unknown_directives(directives) + unknown_keys = directives.keys - ORDERED_DIRECTIVES + return if unknown_keys.empty? + opoo %Q{Unknown arguments to #{stanza} -- #{unknown_keys.inspect}. Running "brew update; brew cleanup; brew cask cleanup" will likely fix it.} + end - # Preserve prior functionality of script which runs first. Should rarely be needed. - # :early_script should not delete files, better defer that to :script. - # If Cask writers never need :early_script it may be removed in the future. - def uninstall_early_script(directives) - uninstall_script(directives, directive_name: :early_script) - end + # Preserve prior functionality of script which runs first. Should rarely be needed. + # :early_script should not delete files, better defer that to :script. + # If Cask writers never need :early_script it may be removed in the future. + def uninstall_early_script(directives) + uninstall_script(directives, directive_name: :early_script) + end - # :launchctl must come before :quit/:signal for cases where app would instantly re-launch - def uninstall_launchctl(directives) - Array(directives[:launchctl]).each do |service| - ohai "Removing launchctl service #{service}" - [false, true].each do |with_sudo| - plist_status = @command.run("/bin/launchctl", args: ["list", service], sudo: with_sudo, print_stderr: false).stdout - if plist_status =~ %r{^\{} - @command.run!("/bin/launchctl", args: ["remove", service], sudo: with_sudo) - sleep 1 + # :launchctl must come before :quit/:signal for cases where app would instantly re-launch + def uninstall_launchctl(directives) + Array(directives[:launchctl]).each do |service| + ohai "Removing launchctl service #{service}" + [false, true].each do |with_sudo| + plist_status = @command.run("/bin/launchctl", args: ["list", service], sudo: with_sudo, print_stderr: false).stdout + if plist_status =~ %r{^\{} + @command.run!("/bin/launchctl", args: ["remove", service], sudo: with_sudo) + sleep 1 + end + paths = ["/Library/LaunchAgents/#{service}.plist", + "/Library/LaunchDaemons/#{service}.plist"] + paths.each { |elt| elt.prepend(ENV["HOME"]) } unless with_sudo + paths = paths.map { |elt| Pathname(elt) }.select(&:exist?) + paths.each do |path| + @command.run!("/bin/rm", args: ["-f", "--", path], sudo: with_sudo) + end + # undocumented and untested: pass a path to uninstall :launchctl + next unless Pathname(service).exist? + @command.run!("/bin/launchctl", args: ["unload", "-w", "--", service], sudo: with_sudo) + @command.run!("/bin/rm", args: ["-f", "--", service], sudo: with_sudo) + sleep 1 + end end - paths = ["/Library/LaunchAgents/#{service}.plist", - "/Library/LaunchDaemons/#{service}.plist"] - paths.each { |elt| elt.prepend(ENV["HOME"]) } unless with_sudo - paths = paths.map { |elt| Pathname(elt) }.select(&:exist?) - paths.each do |path| - @command.run!("/bin/rm", args: ["-f", "--", path], sudo: with_sudo) + end + + # :quit/:signal must come before :kext so the kext will not be in use by a running process + def uninstall_quit(directives) + Array(directives[:quit]).each do |id| + ohai "Quitting application ID #{id}" + num_running = count_running_processes(id) + next unless num_running > 0 + @command.run!("/usr/bin/osascript", args: ["-e", %Q{tell application id "#{id}" to quit}], sudo: true) + sleep 3 end - # undocumented and untested: pass a path to uninstall :launchctl - next unless Pathname(service).exist? - @command.run!("/bin/launchctl", args: ["unload", "-w", "--", service], sudo: with_sudo) - @command.run!("/bin/rm", args: ["-f", "--", service], sudo: with_sudo) - sleep 1 end - end - end - # :quit/:signal must come before :kext so the kext will not be in use by a running process - def uninstall_quit(directives) - Array(directives[:quit]).each do |id| - ohai "Quitting application ID #{id}" - num_running = count_running_processes(id) - next unless num_running > 0 - @command.run!("/usr/bin/osascript", args: ["-e", %Q{tell application id "#{id}" to quit}], sudo: true) - sleep 3 - end - end + # :signal should come after :quit so it can be used as a backup when :quit fails + def uninstall_signal(directives) + Array(directives[:signal]).flatten.each_slice(2) do |pair| + raise CaskInvalidError.new(@cask, "Each #{stanza} :signal must have 2 elements.") unless pair.length == 2 + signal, id = pair + ohai "Signalling '#{signal}' to application ID '#{id}'" + pids = get_unix_pids(id) + next unless pids.any? + # Note that unlike :quit, signals are sent from the current user (not + # upgraded to the superuser). This is a todo item for the future, but + # there should be some additional thought/safety checks about that, as a + # misapplied "kill" by root could bring down the system. The fact that we + # learned the pid from AppleScript is already some degree of protection, + # though indirect. + odebug "Unix ids are #{pids.inspect} for processes with bundle identifier #{id}" + Process.kill(signal, *pids) + sleep 3 + end + end - # :signal should come after :quit so it can be used as a backup when :quit fails - def uninstall_signal(directives) - Array(directives[:signal]).flatten.each_slice(2) do |pair| - raise Hbc::CaskInvalidError.new(@cask, "Each #{stanza} :signal must have 2 elements.") unless pair.length == 2 - signal, id = pair - ohai "Signalling '#{signal}' to application ID '#{id}'" - pids = get_unix_pids(id) - next unless pids.any? - # Note that unlike :quit, signals are sent from the current user (not - # upgraded to the superuser). This is a todo item for the future, but - # there should be some additional thought/safety checks about that, as a - # misapplied "kill" by root could bring down the system. The fact that we - # learned the pid from AppleScript is already some degree of protection, - # though indirect. - odebug "Unix ids are #{pids.inspect} for processes with bundle identifier #{id}" - Process.kill(signal, *pids) - sleep 3 - end - end + def count_running_processes(bundle_id) + @command.run!("/usr/bin/osascript", + args: ["-e", %Q{tell application "System Events" to count processes whose bundle identifier is "#{bundle_id}"}], + sudo: true).stdout.to_i + end - def count_running_processes(bundle_id) - @command.run!("/usr/bin/osascript", - args: ["-e", %Q{tell application "System Events" to count processes whose bundle identifier is "#{bundle_id}"}], - sudo: true).stdout.to_i - end + def get_unix_pids(bundle_id) + pid_string = @command.run!("/usr/bin/osascript", + args: ["-e", %Q{tell application "System Events" to get the unix id of every process whose bundle identifier is "#{bundle_id}"}], + sudo: true).stdout.chomp + return [] unless pid_string =~ %r{\A\d+(?:\s*,\s*\d+)*\Z} # sanity check + pid_string.split(%r{\s*,\s*}).map(&:strip).map(&:to_i) + end - def get_unix_pids(bundle_id) - pid_string = @command.run!("/usr/bin/osascript", - args: ["-e", %Q{tell application "System Events" to get the unix id of every process whose bundle identifier is "#{bundle_id}"}], - sudo: true).stdout.chomp - return [] unless pid_string =~ %r{\A\d+(?:\s*,\s*\d+)*\Z} # sanity check - pid_string.split(%r{\s*,\s*}).map(&:strip).map(&:to_i) - end + def uninstall_login_item(directives) + Array(directives[:login_item]).each do |name| + ohai "Removing login item #{name}" + @command.run!("/usr/bin/osascript", + args: ["-e", %Q{tell application "System Events" to delete every login item whose name is "#{name}"}], + sudo: false) + sleep 1 + end + end - def uninstall_login_item(directives) - Array(directives[:login_item]).each do |name| - ohai "Removing login item #{name}" - @command.run!("/usr/bin/osascript", - args: ["-e", %Q{tell application "System Events" to delete every login item whose name is "#{name}"}], - sudo: false) - sleep 1 - end - end + # :kext should be unloaded before attempting to delete the relevant file + def uninstall_kext(directives) + Array(directives[:kext]).each do |kext| + ohai "Unloading kernel extension #{kext}" + is_loaded = @command.run!("/usr/sbin/kextstat", args: ["-l", "-b", kext], sudo: true).stdout + if is_loaded.length > 1 + @command.run!("/sbin/kextunload", args: ["-b", kext], sudo: true) + sleep 1 + end + end + end - # :kext should be unloaded before attempting to delete the relevant file - def uninstall_kext(directives) - Array(directives[:kext]).each do |kext| - ohai "Unloading kernel extension #{kext}" - is_loaded = @command.run!("/usr/sbin/kextstat", args: ["-l", "-b", kext], sudo: true).stdout - if is_loaded.length > 1 - @command.run!("/sbin/kextunload", args: ["-b", kext], sudo: true) + # :script must come before :pkgutil, :delete, or :trash so that the script file is not already deleted + def uninstall_script(directives, directive_name: :script) + executable, script_arguments = self.class.read_script_arguments(directives, + "uninstall", + { must_succeed: true, sudo: true }, + { print_stdout: true }, + directive_name) + ohai "Running uninstall script #{executable}" + raise CaskInvalidError.new(@cask, "#{stanza} :#{directive_name} without :executable.") if executable.nil? + executable_path = @cask.staged_path.join(executable) + @command.run("/bin/chmod", args: ["--", "+x", executable_path]) if File.exist?(executable_path) + @command.run(executable_path, script_arguments) sleep 1 end - end - end - - # :script must come before :pkgutil, :delete, or :trash so that the script file is not already deleted - def uninstall_script(directives, directive_name: :script) - executable, script_arguments = self.class.read_script_arguments(directives, - "uninstall", - { must_succeed: true, sudo: true }, - { print_stdout: true }, - directive_name) - ohai "Running uninstall script #{executable}" - raise Hbc::CaskInvalidError.new(@cask, "#{stanza} :#{directive_name} without :executable.") if executable.nil? - executable_path = @cask.staged_path.join(executable) - @command.run("/bin/chmod", args: ["--", "+x", executable_path]) if File.exist?(executable_path) - @command.run(executable_path, script_arguments) - sleep 1 - end - def uninstall_pkgutil(directives) - ohai "Removing files from pkgutil Bill-of-Materials" - Array(directives[:pkgutil]).each do |regexp| - pkgs = Hbc::Pkg.all_matching(regexp, @command) - pkgs.each(&:uninstall) - end - end + def uninstall_pkgutil(directives) + ohai "Removing files from pkgutil Bill-of-Materials" + Array(directives[:pkgutil]).each do |regexp| + pkgs = Hbc::Pkg.all_matching(regexp, @command) + pkgs.each(&:uninstall) + end + end - def uninstall_delete(directives, expand_tilde = true) - Array(directives[:delete]).concat(Array(directives[:trash])).flatten.each_slice(PATH_ARG_SLICE_SIZE) do |path_slice| - ohai "Removing files: #{path_slice.utf8_inspect}" - path_slice = self.class.expand_path_strings(path_slice) if expand_tilde - path_slice = self.class.remove_relative_path_strings(:delete, path_slice) - path_slice = self.class.remove_undeletable_path_strings(:delete, path_slice) - @command.run!("/bin/rm", args: path_slice.unshift("-rf", "--"), sudo: true) - end - end + def uninstall_delete(directives, expand_tilde = true) + Array(directives[:delete]).concat(Array(directives[:trash])).flatten.each_slice(PATH_ARG_SLICE_SIZE) do |path_slice| + ohai "Removing files: #{path_slice.utf8_inspect}" + path_slice = self.class.expand_path_strings(path_slice) if expand_tilde + path_slice = self.class.remove_relative_path_strings(:delete, path_slice) + path_slice = self.class.remove_undeletable_path_strings(:delete, path_slice) + @command.run!("/bin/rm", args: path_slice.unshift("-rf", "--"), sudo: true) + end + end - # :trash functionality is stubbed as a synonym for :delete - # TODO: make :trash work differently, moving files to the Trash - def uninstall_trash(directives, expand_tilde = true) - uninstall_delete(directives, expand_tilde) - end + # :trash functionality is stubbed as a synonym for :delete + # TODO: make :trash work differently, moving files to the Trash + def uninstall_trash(directives, expand_tilde = true) + uninstall_delete(directives, expand_tilde) + end - def uninstall_rmdir(directives, expand_tilde = true) - Array(directives[:rmdir]).flatten.each do |directory| - directory = self.class.expand_path_strings([directory]).first if expand_tilde - directory = self.class.remove_relative_path_strings(:rmdir, [directory]).first - directory = self.class.remove_undeletable_path_strings(:rmdir, [directory]).first - next if directory.to_s.empty? - ohai "Removing directory if empty: #{directory.to_s.utf8_inspect}" - directory = Pathname.new(directory) - next unless directory.exist? - @command.run!("/bin/rm", - args: ["-f", "--", directory.join(".DS_Store")], - sudo: true, - print_stderr: false) - @command.run("/bin/rmdir", - args: ["--", directory], - sudo: true, - print_stderr: false) + def uninstall_rmdir(directives, expand_tilde = true) + Array(directives[:rmdir]).flatten.each do |directory| + directory = self.class.expand_path_strings([directory]).first if expand_tilde + directory = self.class.remove_relative_path_strings(:rmdir, [directory]).first + directory = self.class.remove_undeletable_path_strings(:rmdir, [directory]).first + next if directory.to_s.empty? + ohai "Removing directory if empty: #{directory.to_s.utf8_inspect}" + directory = Pathname.new(directory) + next unless directory.exist? + @command.run!("/bin/rm", + args: ["-f", "--", directory.join(".DS_Store")], + sudo: true, + print_stderr: false) + @command.run("/bin/rmdir", + args: ["--", directory], + sudo: true, + print_stderr: false) + end + end end end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/vst3_plugin.rb b/Library/Homebrew/cask/lib/hbc/artifact/vst3_plugin.rb index 243884435..056fffc2a 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/vst3_plugin.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/vst3_plugin.rb @@ -1,4 +1,8 @@ require "hbc/artifact/moved" -class Hbc::Artifact::Vst3Plugin < Hbc::Artifact::Moved +module Hbc + module Artifact + class Vst3Plugin < Moved + end + end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/vst_plugin.rb b/Library/Homebrew/cask/lib/hbc/artifact/vst_plugin.rb index 8d0546480..f38804635 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/vst_plugin.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/vst_plugin.rb @@ -1,4 +1,8 @@ require "hbc/artifact/moved" -class Hbc::Artifact::VstPlugin < Hbc::Artifact::Moved +module Hbc + module Artifact + class VstPlugin < Moved + end + end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/zap.rb b/Library/Homebrew/cask/lib/hbc/artifact/zap.rb index 8bd8da63b..503ea35c4 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/zap.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/zap.rb @@ -1,16 +1,20 @@ require "hbc/artifact/uninstall_base" -class Hbc::Artifact::Zap < Hbc::Artifact::UninstallBase - def install_phase - odebug "Nothing to do. The zap artifact has no install phase." - end +module Hbc + module Artifact + class Zap < UninstallBase + def install_phase + odebug "Nothing to do. The zap artifact has no install phase." + end - def uninstall_phase - odebug "Nothing to do. The zap artifact has no uninstall phase." - end + def uninstall_phase + odebug "Nothing to do. The zap artifact has no uninstall phase." + end - def zap_phase - expand_tilde = true - dispatch_uninstall_directives(expand_tilde) + def zap_phase + expand_tilde = true + dispatch_uninstall_directives(expand_tilde) + end + end end end |
