
This wasn't working before for a few reasons. 1. It never got past the installed name check because the installed name sets had short names and the tap names were long names including the tap namespace too. Now we just trim the long name before comparing it to the installed name set. Before: ``` ["name"].include?("tap/full/name") # always false ``` After: ``` ["name"].include("tap/full/name".split("/").last) # sometimes true ``` 2. The names we were trying to load formulae and casks with were incorrect. Before: ``` tap = Tap.fetch("homebrew/cask-versions") token = "homebrew/cask-versions/token" cask = Cask::CaskLoader.load("#{tap}/#{token}") ``` After: ``` token = "homebrew/cask-versions/token" cask = CaskCaskLoader.load(token) ```
84 lines
2.7 KiB
Ruby
84 lines
2.7 KiB
Ruby
# typed: strict
|
|
# frozen_string_literal: true
|
|
|
|
require "cli/parser"
|
|
|
|
module Homebrew
|
|
module_function
|
|
|
|
sig { returns(CLI::Parser) }
|
|
def untap_args
|
|
Homebrew::CLI::Parser.new do
|
|
description <<~EOS
|
|
Remove a tapped formula repository.
|
|
EOS
|
|
switch "-f", "--force",
|
|
description: "Untap even if formulae or casks from this tap are currently installed."
|
|
|
|
named_args :tap, min: 1
|
|
end
|
|
end
|
|
|
|
sig { void }
|
|
def untap
|
|
args = untap_args.parse
|
|
|
|
args.named.to_installed_taps.each do |tap|
|
|
odie "Untapping #{tap} is not allowed" if tap.core_tap? && Homebrew::EnvConfig.no_install_from_api?
|
|
|
|
if Homebrew::EnvConfig.no_install_from_api? || (!tap.core_tap? && !tap.core_cask_tap?)
|
|
installed_formula_names = T.let(nil, T.nilable(T::Set[String]))
|
|
installed_tap_formulae = tap.formula_names.filter_map do |formula_name|
|
|
# initialise lazily in case there's no formulae in this tap
|
|
installed_formula_names ||= Set.new(Formula.installed_formula_names)
|
|
next unless installed_formula_names.include?(formula_name.split("/").last)
|
|
|
|
formula = begin
|
|
Formulary.factory(formula_name)
|
|
rescue
|
|
# Don't blow up because of a single unavailable formula.
|
|
next
|
|
end
|
|
|
|
# Can't use Formula#any_version_installed? because it doesn't consider
|
|
# taps correctly.
|
|
formula if formula.installed_kegs.any? { |keg| keg.tab.tap == tap }
|
|
end
|
|
|
|
installed_cask_tokens = T.let(nil, T.nilable(T::Set[String]))
|
|
installed_tap_casks = tap.cask_tokens.filter_map do |cask_token|
|
|
# initialise lazily in case there's no casks in this tap
|
|
installed_cask_tokens ||= Set.new(Cask::Caskroom.tokens)
|
|
next unless installed_cask_tokens.include?(cask_token.split("/").last)
|
|
|
|
cask = begin
|
|
Cask::CaskLoader.load(cask_token)
|
|
rescue
|
|
# Don't blow up because of a single unavailable cask.
|
|
next
|
|
end
|
|
|
|
cask if cask.installed?
|
|
end
|
|
|
|
if installed_tap_formulae.present? || installed_tap_casks.present?
|
|
installed_names = (installed_tap_formulae + installed_tap_casks.map(&:token)).join("\n")
|
|
if args.force? || Homebrew::EnvConfig.developer?
|
|
opoo <<~EOS
|
|
Untapping #{tap} even though it contains the following installed formulae or casks:
|
|
#{installed_names}
|
|
EOS
|
|
else
|
|
odie <<~EOS
|
|
Refusing to untap #{tap} because it contains the following installed formulae or casks:
|
|
#{installed_names}
|
|
EOS
|
|
end
|
|
end
|
|
end
|
|
|
|
tap.uninstall manual: true
|
|
end
|
|
end
|
|
end
|