Class: Cask::Artifact::AbstractUninstall Private
- Inherits:
-
AbstractArtifact
- Object
- AbstractArtifact
- Cask::Artifact::AbstractUninstall
- Defined in:
- cask/artifact/abstract_uninstall.rb
Overview
This class is part of a private API. This class may only be used in the Homebrew/brew repository. Third parties should avoid using this class if possible, as it may be removed or changed without warning.
Abstract superclass for uninstall artifacts.
Constant Summary collapse
- ORDERED_DIRECTIVES =
This constant is part of a private API. This constant may only be used in the Homebrew/brew repository. Third parties should avoid using this constant if possible, as it may be removed or changed without warning.
[ :early_script, :launchctl, :quit, :signal, :login_item, :kext, :script, :pkgutil, :delete, :trash, :rmdir, ].freeze
- METADATA_KEYS =
This constant is part of a private API. This constant may only be used in the Homebrew/brew repository. Third parties should avoid using this constant if possible, as it may be removed or changed without warning.
[ :on_upgrade, ].freeze
Constants inherited from AbstractArtifact
Cask::Artifact::AbstractArtifact::DirectivesType
Class Attribute Summary collapse
-
.ancestor_bundle_ids ⇒ Array<String>
private
Bundle IDs of the applications this
brewprocess is running inside.
Instance Attribute Summary collapse
- #directives ⇒ Hash{Symbol => DirectivesType} readonly private
Attributes inherited from AbstractArtifact
Class Method Summary collapse
- .bundle_identifier_for_pid(_pid) ⇒ String? private
- .from_args(cask, **directives) ⇒ AbstractUninstall private
- .parent_pid(_pid) ⇒ Integer? private
Instance Method Summary collapse
- #bundle_ids_to_reopen ⇒ Array<String> private
-
#each_resolved_path(action, paths, &_block) ⇒ T.untyped
private
This returns T::Enumerable[[Pathname, T::Array[Pathname]]] when called without a block, but sorbet doesn't support overloads.
- #find_launchctl_with_wildcard(search) ⇒ Array<String> private
- #initialize(cask, **directives) ⇒ void constructor private
- #summarize ⇒ String private
- #to_h ⇒ Hash{Symbol => DirectivesType} private
-
#uninstall_quit(*bundle_ids, command: nil, upgrade: false, **_kwargs) ⇒ void
private
:quit/:signal must come before :kext so the kext will not be in use by a running process.
Methods included from SystemCommand::Mixin
#system_command, #system_command!
Methods inherited from AbstractArtifact
#cask_sandbox, #config, dirmethod, dsl_key, english_article, english_name, read_script_arguments, #run_cask_sandbox, #sort_order, #staged_path_join_executable, #to_args
Methods included from Utils::Output::Mixin
#issue_reporting_message, #odebug, #odeprecated, #odie, #odisabled, #ofail, #oh1, #oh1_title, #ohai, #ohai_title, #onoe, #opoo, #opoo_outside_github_actions, #opoo_without_github_actions_annotation, #pretty_cannot_install, #pretty_deprecated, #pretty_disabled, #pretty_duration, #pretty_install_status, #pretty_installed, #pretty_uninstalled, #pretty_unmarked, #pretty_upgradable, #pretty_warning
Constructor Details
#initialize(cask, **directives) ⇒ void
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'cask/artifact/abstract_uninstall.rb', line 50 def initialize(cask, **directives) ::Utils::Data.assert_valid_keys(directives, *ORDERED_DIRECTIVES, *METADATA_KEYS) super directives[:signal] = Array(directives[:signal]).flatten.each_slice(2).to_a @directives = directives # This is already included when loading from the API. return if cask.loaded_from_api? return unless directives.key?(:kext) cask.caveats do T.bind(self, ::Cask::DSL::Caveats) kext end end |
Class Attribute Details
.ancestor_bundle_ids ⇒ Array<String>
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
Bundle IDs of the applications this brew process is running inside.
The ancestry of the brew process cannot change while it runs, so the
lookup is shared by every artifact of every cask in the same invocation.
380 381 382 383 384 385 386 387 388 389 390 |
# File 'cask/artifact/abstract_uninstall.rb', line 380 def ancestor_bundle_ids @ancestor_bundle_ids ||= begin pids = [Process.pid] # `launchd` (PID 1) reports a parent of `0` rather than failing. while (ppid = parent_pid(pids.last)) && ppid > 1 && pids.exclude?(ppid) pids << ppid end pids.filter_map { |pid| bundle_identifier_for_pid(pid) } end end |
Instance Attribute Details
#directives ⇒ Hash{Symbol => DirectivesType} (readonly)
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
47 48 49 |
# File 'cask/artifact/abstract_uninstall.rb', line 47 def directives @directives end |
Class Method Details
.bundle_identifier_for_pid(_pid) ⇒ String?
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
399 |
# File 'cask/artifact/abstract_uninstall.rb', line 399 def bundle_identifier_for_pid(_pid) = nil |
.from_args(cask, **directives) ⇒ AbstractUninstall
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
42 43 44 |
# File 'cask/artifact/abstract_uninstall.rb', line 42 def self.from_args(cask, **directives) new(cask, **directives) end |
.parent_pid(_pid) ⇒ Integer?
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
396 |
# File 'cask/artifact/abstract_uninstall.rb', line 396 def parent_pid(_pid) = nil |
Instance Method Details
#bundle_ids_to_reopen ⇒ Array<String>
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
78 79 80 |
# File 'cask/artifact/abstract_uninstall.rb', line 78 def bundle_ids_to_reopen @bundle_ids_to_reopen ||= T.let([], T.nilable(T::Array[String])) end |
#each_resolved_path(action, paths, &_block) ⇒ T.untyped
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
This returns T::Enumerable[[Pathname, T::Array[Pathname]]] when called without a block, but sorbet doesn't support overloads.
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'cask/artifact/abstract_uninstall.rb', line 139 def each_resolved_path(action, paths, &_block) return enum_for(:each_resolved_path, action, paths) unless block_given? paths.each do |path| resolved_path = Pathname.new(path.to_s.sub(%r{^~(?=(?:/|$))}, Dir.home)) if resolved_path.relative? opoo "Skipping #{Formatter.identifier(action)} for relative path '#{path}'." next end if resolved_path.each_filename.to_a.intersect?([".", ".."]) opoo "Skipping #{Formatter.identifier(action)} for path with relative segments '#{path}'." next end begin resolved_paths = Pathname.glob(resolved_path).reject do |target| next false unless undeletable?(target) opoo "Skipping #{Formatter.identifier(action)} for undeletable path '#{target}'." true end yield path, resolved_paths rescue Errno::EPERM raise if ::Cask::Utils.full_disk_access_enabled? odie "Unable to remove some files. Please enable Full Disk Access for your terminal under " \ "#{::Cask::Utils.privacy_security_preference_pane("Full Disk Access")}." end end end |
#find_launchctl_with_wildcard(search) ⇒ Array<String>
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
173 174 175 176 177 178 179 180 181 |
# File 'cask/artifact/abstract_uninstall.rb', line 173 def find_launchctl_with_wildcard(search) regex = wildcard_pattern(search) system_command!("/bin/launchctl", args: ["list"]) .stdout.lines.drop(1) # skip stdout column headers .filter_map do |line| pid, _state, id = line.chomp.split(/\s+/) id if pid.to_i.nonzero? && id&.match?(regex) end end |
#summarize ⇒ String
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
73 74 75 |
# File 'cask/artifact/abstract_uninstall.rb', line 73 def summarize to_h.flat_map { |key, val| Array(val).map { |v| "#{key.inspect} => #{v.inspect}" } }.join(", ") end |
#to_h ⇒ Hash{Symbol => DirectivesType}
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
68 69 70 |
# File 'cask/artifact/abstract_uninstall.rb', line 68 def to_h directives.to_h end |
#uninstall_quit(*bundle_ids, command: nil, upgrade: false, **_kwargs) ⇒ void
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
This method returns an undefined value.
:quit/:signal must come before :kext so the kext will not be in use by a running process
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'cask/artifact/abstract_uninstall.rb', line 91 def uninstall_quit(*bundle_ids, command: nil, upgrade: false, **_kwargs) bundle_ids = bundle_ids.flat_map { |bundle_id| (bundle_id) } bundle_ids.each do |bundle_id| next unless running?(bundle_id) unless User.current&.gui? opoo "Not logged into a GUI; skipping quitting application ID '#{bundle_id}'." next end if hosting_brew?(bundle_id) opoo "Skipping quitting application '#{bundle_id}' as `brew` is running inside it." next end ohai "Quitting application '#{bundle_id}'..." quit_succeeded = T.let(false, T::Boolean) begin Timeout.timeout(10) do Kernel.loop do next unless quit(bundle_id).success? next if running?(bundle_id) puts "Application '#{bundle_id}' quit successfully." quit_succeeded = true break end end rescue Timeout::Error opoo "Application '#{bundle_id}' did not quit. #{automation_access_instructions}" end bundle_ids_to_reopen << bundle_id if upgrade && quit_succeeded end end |