Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 45 additions & 13 deletions Library/Homebrew/cli/args.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,15 @@ def freeze_remaining_args!(remaining_args)
end

def freeze_named_args!(named_args, cask_options:)
options = {}
options[:force_bottle] = true if self[:force_bottle?]
options[:override_spec] = :head if self[:HEAD?]
options[:flags] = flags_only unless flags_only.empty?
self[:named] = NamedArgs.new(
*named_args.freeze,
override_spec: spec(nil),
force_bottle: self[:force_bottle?],
flags: flags_only,
cask_options: cask_options,
parent: self,
parent: self,
cask_options: cask_options,
**options,
)
end

Expand Down Expand Up @@ -98,6 +100,44 @@ def only_formula_or_cask
return :cask if cask? && !formula?
end

sig { returns(T::Array[[Symbol, Symbol]]) }
def os_arch_combinations
skip_invalid_combinations = false

oses = case (os_sym = os&.to_sym)
when nil
[SimulateSystem.current_os]
when :all
skip_invalid_combinations = true

[
*MacOSVersions::SYMBOLS.keys,
:linux,
]
else
[os_sym]
end

arches = case (arch_sym = arch&.to_sym)
when nil
[SimulateSystem.current_arch]
when :all
skip_invalid_combinations = true
OnSystem::ARCH_OPTIONS
else
[arch_sym]
end

oses.product(arches).select do |os, arch|
if skip_invalid_combinations
bottle_tag = Utils::Bottles::Tag.new(system: os, arch: arch)
bottle_tag.valid_combination?
else
true
end
end
end

private

def option_to_name(option)
Expand All @@ -124,14 +164,6 @@ def cli_args
@cli_args.freeze
end

def spec(default = :stable)
if self[:HEAD?]
:head
else
default
end
end

def respond_to_missing?(method_name, *)
@table.key?(method_name)
end
Expand Down
6 changes: 6 additions & 0 deletions Library/Homebrew/cli/args.rbi
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,9 @@ module Homebrew
sig { returns(T.nilable(T::Array[String])) }
def only; end

sig { returns(T.nilable(String)) }
def os; end

sig { returns(T.nilable(T::Array[String])) }
def except; end

Expand Down Expand Up @@ -270,6 +273,9 @@ module Homebrew
sig { returns(T::Boolean) }
def s?; end

sig { returns(T.nilable(String)) }
def arch; end

sig { returns(T.nilable(String)) }
def appdir; end

Expand Down
46 changes: 33 additions & 13 deletions Library/Homebrew/cli/named_args.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,24 @@ module CLI
#
# @api private
class NamedArgs < Array
def initialize(*args, parent: Args.new, override_spec: nil, force_bottle: false, flags: [], cask_options: false)
sig {
params(
args: String,
parent: Args,
override_spec: Symbol,
force_bottle: T::Boolean,
flags: T::Array[String],
cask_options: T::Boolean,
).void
}
def initialize(
*args,
parent: Args.new,
override_spec: T.unsafe(nil),
force_bottle: T.unsafe(nil),
flags: T.unsafe(nil),
cask_options: false
)
require "cask/cask"
require "cask/cask_loader"
require "formulary"
Expand Down Expand Up @@ -50,11 +67,17 @@ def to_formulae
warn: T::Boolean,
).returns(T::Array[T.any(Formula, Keg, Cask::Cask)])
}
def to_formulae_and_casks(only: parent&.only_formula_or_cask, ignore_unavailable: nil, method: nil, uniq: true,
warn: true)
def to_formulae_and_casks(
only: parent&.only_formula_or_cask,
ignore_unavailable: nil,
method: T.unsafe(nil),
uniq: true,
warn: T.unsafe(nil)
)
@to_formulae_and_casks ||= {}
@to_formulae_and_casks[only] ||= downcased_unique_named.flat_map do |name|
load_formula_or_cask(name, only: only, method: method, warn: warn)
options = { warn: warn }.compact
load_formula_or_cask(name, only: only, method: method, **options)
rescue FormulaUnreadableError, FormulaClassUnavailableError,
TapFormulaUnreadableError, TapFormulaClassUnavailableError,
Cask::CaskUnreadableError
Expand Down Expand Up @@ -88,14 +111,15 @@ def to_formulae_and_casks_and_unavailable(only: parent&.only_formula_or_cask, me
end.uniq.freeze
end

def load_formula_or_cask(name, only: nil, method: nil, warn: true)
def load_formula_or_cask(name, only: nil, method: nil, warn: nil)
unreadable_error = nil

if only != :cask
begin
formula = case method
when nil, :factory
Formulary.factory(name, *spec, force_bottle: @force_bottle, flags: @flags, warn: warn)
options = { warn: warn, force_bottle: @force_bottle, flags: @flags }.compact
Formulary.factory(name, *@override_spec, **options)
when :resolve
resolve_formula(name)
when :latest_kegs
Expand Down Expand Up @@ -126,7 +150,8 @@ def load_formula_or_cask(name, only: nil, method: nil, warn: true)

begin
config = Cask::Config.from_args(@parent) if @cask_options
cask = Cask::CaskLoader.load(name, config: config, warn: warn)
options = { warn: warn }.compact
cask = Cask::CaskLoader.load(name, config: config, **options)

if unreadable_error.present?
onoe <<~EOS
Expand Down Expand Up @@ -177,7 +202,7 @@ def load_formula_or_cask(name, only: nil, method: nil, warn: true)
private :load_formula_or_cask

def resolve_formula(name)
Formulary.resolve(name, spec: spec, force_bottle: @force_bottle, flags: @flags)
Formulary.resolve(name, **{ spec: @override_spec, force_bottle: @force_bottle, flags: @flags }.compact)
end
private :resolve_formula

Expand Down Expand Up @@ -306,11 +331,6 @@ def downcased_unique_named
end.uniq
end

def spec
@override_spec
end
private :spec

def resolve_kegs(name)
raise UsageError if name.blank?

Expand Down
65 changes: 57 additions & 8 deletions Library/Homebrew/cmd/--cache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ def self.__cache_args

If <formula> is provided, display the file or directory used to cache <formula>.
EOS
flag "--os=",
description: "Show cache file for the given operating system." \
"(Pass `all` to show cache files for all operating systems.)"
flag "--arch=",
description: "Show cache file for the given CPU architecture." \
"(Pass `all` to show cache files for all architectures.)"
switch "-s", "--build-from-source",
description: "Show the cache file used when building from source."
switch "--force-bottle",
Expand All @@ -31,6 +37,8 @@ def self.__cache_args

conflicts "--build-from-source", "--force-bottle", "--bottle-tag", "--HEAD", "--cask"
conflicts "--formula", "--cask"
conflicts "--os", "--bottle-tag"
conflicts "--arch", "--bottle-tag"

named_args [:formula, :cask]
end
Expand All @@ -46,21 +54,62 @@ def self.__cache
end

formulae_or_casks = args.named.to_formulae_and_casks
os_arch_combinations = args.os_arch_combinations

formulae_or_casks.each do |formula_or_cask|
if formula_or_cask.is_a? Formula
print_formula_cache formula_or_cask, args: args
case formula_or_cask
when Formula
formula = T.cast(formula_or_cask, Formula)
ref = formula.loaded_from_api? ? formula.full_name : formula.path

os_arch_combinations.each do |os, arch|
SimulateSystem.with os: os, arch: arch do
Formulary.clear_cache
formula = Formulary.factory(ref)
print_formula_cache(formula, os: os, arch: arch, args: args)
end
end
else
print_cask_cache formula_or_cask
cask = formula_or_cask
ref = cask.loaded_from_api? ? cask.full_token : cask.sourcefile_path

os_arch_combinations.each do |os, arch|
next if os == :linux

SimulateSystem.with os: os, arch: arch do
cask = Cask::CaskLoader.load(ref)
print_cask_cache(cask)
end
end
end
end
end

sig { params(formula: Formula, args: CLI::Args).void }
def self.print_formula_cache(formula, args:)
if fetch_bottle?(formula, force_bottle: args.force_bottle?, bottle_tag: args.bottle_tag&.to_sym,
build_from_source_formulae: args.build_from_source_formulae)
puts formula.bottle_for_tag(args.bottle_tag&.to_sym)&.cached_download
sig { params(formula: Formula, os: Symbol, arch: Symbol, args: CLI::Args).void }
def self.print_formula_cache(formula, os:, arch:, args:)
if fetch_bottle?(
formula,
force_bottle: args.force_bottle?,
bottle_tag: args.bottle_tag&.to_sym,
build_from_source_formulae: args.build_from_source_formulae,
os: args.os&.to_sym,
arch: args.arch&.to_sym,
)
bottle_tag = if (bottle_tag = args.bottle_tag&.to_sym)
# TODO: odeprecate "--bottle-tag"
Utils::Bottles::Tag.from_symbol(bottle_tag)
else
Utils::Bottles::Tag.new(system: os, arch: arch)
end

bottle = formula.bottle_for_tag(bottle_tag)

if bottle.nil?
opoo "Bottle for tag #{bottle_tag.to_sym.inspect} is unavailable."
return
end

puts bottle.cached_download
elsif args.HEAD?
puts formula.head.cached_download
else
Expand Down
Loading