Merge pull request #11555 from Rylan12/remove-homebrew-core

Allow for homebrew/core to be untapped
This commit is contained in:
Rylan Polster 2021-06-18 16:05:24 -04:00 committed by GitHub
commit 46164a3054
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 44 additions and 21 deletions

View File

@ -15,8 +15,8 @@ class CaskDependent
@cask.full_name @cask.full_name
end end
def runtime_dependencies def runtime_dependencies(ignore_missing: false)
recursive_dependencies recursive_dependencies ignore_missing: ignore_missing
end end
def deps def deps
@ -43,8 +43,8 @@ class CaskDependent
end end
end end
def recursive_dependencies(&block) def recursive_dependencies(ignore_missing: false, &block)
Dependency.expand(self, &block) Dependency.expand(self, ignore_missing: ignore_missing, &block)
end end
def recursive_requirements(&block) def recursive_requirements(&block)

View File

@ -25,7 +25,7 @@ module Homebrew
args = untap_args.parse args = untap_args.parse
args.named.to_installed_taps.each do |tap| args.named.to_installed_taps.each do |tap|
odie "Untapping #{tap} is not allowed" if tap.core_tap? odie "Untapping #{tap} is not allowed" if tap.core_tap? && ENV["HOMEBREW_JSON_CORE"].blank?
installed_tap_formulae = Formula.installed.select { |formula| formula.tap == tap } installed_tap_formulae = Formula.installed.select { |formula| formula.tap == tap }
installed_tap_casks = Cask::Caskroom.casks.select { |cask| cask.tap == tap } installed_tap_casks = Cask::Caskroom.casks.select { |cask| cask.tap == tap }

View File

@ -207,6 +207,7 @@ module Homebrew
def install_core_tap_if_necessary def install_core_tap_if_necessary
return if ENV["HOMEBREW_UPDATE_TEST"] return if ENV["HOMEBREW_UPDATE_TEST"]
return if ENV["HOMEBREW_JSON_CORE"].present?
core_tap = CoreTap.instance core_tap = CoreTap.instance
return if core_tap.installed? return if core_tap.installed?

View File

@ -46,6 +46,15 @@ class Dependency
formula formula
end end
def unavailable_core_formula?
to_formula
false
rescue CoreTapFormulaUnavailableError
true
rescue
false
end
def installed? def installed?
to_formula.latest_version_installed? to_formula.latest_version_installed?
end end
@ -89,7 +98,7 @@ class Dependency
# the list. # the list.
# The default filter, which is applied when a block is not given, omits # The default filter, which is applied when a block is not given, omits
# optionals and recommendeds based on what the dependent has asked for # optionals and recommendeds based on what the dependent has asked for
def expand(dependent, deps = dependent.deps, cache_key: nil, &block) def expand(dependent, deps = dependent.deps, cache_key: nil, ignore_missing: false, &block)
# Keep track dependencies to avoid infinite cyclic dependency recursion. # Keep track dependencies to avoid infinite cyclic dependency recursion.
@expand_stack ||= [] @expand_stack ||= []
@expand_stack.push dependent.name @expand_stack.push dependent.name
@ -104,19 +113,19 @@ class Dependency
deps.each do |dep| deps.each do |dep|
next if dependent.name == dep.name next if dependent.name == dep.name
case action(dependent, dep, &block) case action(dependent, dep, ignore_missing: ignore_missing, &block)
when :prune when :prune
next next
when :skip when :skip
next if @expand_stack.include? dep.name next if @expand_stack.include? dep.name
expanded_deps.concat(expand(dep.to_formula, cache_key: cache_key, &block)) expanded_deps.concat(expand(dep.to_formula, cache_key: cache_key, ignore_missing: ignore_missing, &block))
when :keep_but_prune_recursive_deps when :keep_but_prune_recursive_deps
expanded_deps << dep expanded_deps << dep
else else
next if @expand_stack.include? dep.name next if @expand_stack.include? dep.name
expanded_deps.concat(expand(dep.to_formula, cache_key: cache_key, &block)) expanded_deps.concat(expand(dep.to_formula, cache_key: cache_key, ignore_missing: ignore_missing, &block))
expanded_deps << dep expanded_deps << dep
end end
end end
@ -128,8 +137,10 @@ class Dependency
@expand_stack.pop @expand_stack.pop
end end
def action(dependent, dep, &block) def action(dependent, dep, ignore_missing: false, &block)
catch(:action) do catch(:action) do
prune if ignore_missing && dep.unavailable_core_formula?
if block if block
yield dependent, dep yield dependent, dep
elsif dep.optional? || dep.recommended? elsif dep.optional? || dep.recommended?

View File

@ -221,6 +221,13 @@ class TapFormulaUnavailableError < FormulaUnavailableError
end end
end end
# Raised when a formula in a the core tap is unavailable.
class CoreTapFormulaUnavailableError < TapFormulaUnavailableError
def initialize(name)
super CoreTap.instance, name
end
end
# Raised when a formula in a specific tap does not contain a formula class. # Raised when a formula in a specific tap does not contain a formula class.
class TapFormulaClassUnavailableError < TapFormulaUnavailableError class TapFormulaClassUnavailableError < TapFormulaUnavailableError
include FormulaClassUnavailableErrorModule include FormulaClassUnavailableErrorModule

View File

@ -361,6 +361,8 @@ module Formulary
end end
def get_formula(*) def get_formula(*)
raise CoreTapFormulaUnavailableError, name if !CoreTap.instance.installed? && ENV["HOMEBREW_JSON_CORE"].present?
raise FormulaUnavailableError, name raise FormulaUnavailableError, name
end end
end end
@ -395,7 +397,7 @@ module Formulary
) )
raise ArgumentError, "Formulae must have a ref!" unless ref raise ArgumentError, "Formulae must have a ref!" unless ref
if ENV["HOMEBREW_BOTTLE_JSON"].present? && if ENV["HOMEBREW_JSON_CORE"].present? &&
@formula_name_local_bottle_path_map.present? && @formula_name_local_bottle_path_map.present? &&
@formula_name_local_bottle_path_map.key?(ref) @formula_name_local_bottle_path_map.key?(ref)
ref = @formula_name_local_bottle_path_map[ref] ref = @formula_name_local_bottle_path_map[ref]
@ -427,9 +429,7 @@ module Formulary
# @param formula_name the formula name string to map. # @param formula_name the formula name string to map.
# @param local_bottle_path a path pointing to the target bottle archive. # @param local_bottle_path a path pointing to the target bottle archive.
def self.map_formula_name_to_local_bottle_path(formula_name, local_bottle_path) def self.map_formula_name_to_local_bottle_path(formula_name, local_bottle_path)
if ENV["HOMEBREW_BOTTLE_JSON"].blank? raise UsageError, "HOMEBREW_JSON_CORE not set but required for #{__method__}!" if ENV["HOMEBREW_JSON_CORE"].blank?
raise UsageError, "HOMEBREW_BOTTLE_JSON not set but required for #{__method__}!"
end
@formula_name_local_bottle_path_map ||= {} @formula_name_local_bottle_path_map ||= {}
@formula_name_local_bottle_path_map[formula_name] = Pathname(local_bottle_path).realpath @formula_name_local_bottle_path_map[formula_name] = Pathname(local_bottle_path).realpath

View File

@ -50,7 +50,8 @@ module InstalledDependents
when Formula when Formula
dependent.missing_dependencies(hide: keg_names) dependent.missing_dependencies(hide: keg_names)
when Cask::Cask when Cask::Cask
CaskDependent.new(dependent).runtime_dependencies.map(&:to_formula) # When checking for cask dependents, we don't care about missing dependencies
CaskDependent.new(dependent).runtime_dependencies(ignore_missing: true).map(&:to_formula)
end end
required_kegs = required.map do |f| required_kegs = required.map do |f|

View File

@ -734,6 +734,7 @@ class CoreTap < Tap
def self.ensure_installed! def self.ensure_installed!
return if instance.installed? return if instance.installed?
return if ENV["HOMEBREW_JSON_CORE"].present?
safe_system HOMEBREW_BREW_FILE, "tap", instance.name safe_system HOMEBREW_BREW_FILE, "tap", instance.name
end end
@ -748,9 +749,11 @@ class CoreTap < Tap
end end
# @private # @private
sig { void } sig { params(manual: T::Boolean).void }
def uninstall def uninstall(manual: false)
raise "Tap#uninstall is not available for CoreTap" raise "Tap#uninstall is not available for CoreTap" if ENV["HOMEBREW_JSON_CORE"].blank?
super
end end
# @private # @private

View File

@ -216,12 +216,12 @@ describe Formulary do
described_class.factory("formula-to-map") described_class.factory("formula-to-map")
}.to raise_error(FormulaUnavailableError) }.to raise_error(FormulaUnavailableError)
ENV["HOMEBREW_BOTTLE_JSON"] = nil ENV["HOMEBREW_JSON_CORE"] = nil
expect { expect {
described_class.map_formula_name_to_local_bottle_path "formula-to-map", formula_path described_class.map_formula_name_to_local_bottle_path "formula-to-map", formula_path
}.to raise_error(UsageError, /HOMEBREW_BOTTLE_JSON not set/) }.to raise_error(UsageError, /HOMEBREW_JSON_CORE not set/)
ENV["HOMEBREW_BOTTLE_JSON"] = "1" ENV["HOMEBREW_JSON_CORE"] = "1"
described_class.map_formula_name_to_local_bottle_path "formula-to-map", formula_path described_class.map_formula_name_to_local_bottle_path "formula-to-map", formula_path
expect(described_class.factory("formula-to-map")).to be_kind_of(Formula) expect(described_class.factory("formula-to-map")).to be_kind_of(Formula)