Merge pull request #10651 from nandahkrishna/formula-cask-disambiguation
livecheck and bump: formula/cask disambiguation
This commit is contained in:
commit
3afa9b078e
@ -16,6 +16,8 @@ module Homebrew
|
||||
Display out-of-date brew formulae and the latest version available.
|
||||
Also displays whether a pull request has been opened with the URL.
|
||||
EOS
|
||||
switch "--full-name",
|
||||
description: "Print formulae/casks with fully-qualified names."
|
||||
switch "--no-pull-requests",
|
||||
description: "Do not retrieve pull requests from GitHub."
|
||||
switch "--formula", "--formulae",
|
||||
@ -39,11 +41,14 @@ module Homebrew
|
||||
end
|
||||
|
||||
formulae_and_casks = if args.formula?
|
||||
args.named.to_formulae.presence
|
||||
args.named.to_formulae
|
||||
elsif args.cask?
|
||||
args.named.to_casks.presence
|
||||
args.named.to_casks
|
||||
else
|
||||
args.named.to_formulae_and_casks.presence
|
||||
args.named.to_formulae_and_casks
|
||||
end
|
||||
formulae_and_casks = formulae_and_casks&.sort_by do |formula_or_cask|
|
||||
formula_or_cask.respond_to?(:token) ? formula_or_cask.token : formula_or_cask.name
|
||||
end
|
||||
|
||||
limit = args.limit.to_i if args.limit.present?
|
||||
@ -51,10 +56,29 @@ module Homebrew
|
||||
if formulae_and_casks
|
||||
Livecheck.load_other_tap_strategies(formulae_and_casks)
|
||||
|
||||
ambiguous_casks = []
|
||||
if !args.formula? && !args.cask?
|
||||
ambiguous_casks = formulae_and_casks.group_by { |item| Livecheck.formula_or_cask_name(item, full_name: true) }
|
||||
.values
|
||||
.select { |items| items.length > 1 }
|
||||
.flatten
|
||||
.select { |item| item.is_a?(Cask::Cask) }
|
||||
end
|
||||
|
||||
ambiguous_names = []
|
||||
unless args.full_name?
|
||||
ambiguous_names =
|
||||
(formulae_and_casks - ambiguous_casks).group_by { |item| Livecheck.formula_or_cask_name(item) }
|
||||
.values
|
||||
.select { |items| items.length > 1 }
|
||||
.flatten
|
||||
end
|
||||
|
||||
formulae_and_casks.each_with_index do |formula_or_cask, i|
|
||||
puts if i.positive?
|
||||
|
||||
name = Livecheck.formula_or_cask_name(formula_or_cask)
|
||||
use_full_name = args.full_name? || ambiguous_names.include?(formula_or_cask)
|
||||
name = Livecheck.formula_or_cask_name(formula_or_cask, full_name: use_full_name)
|
||||
repository = if formula_or_cask.is_a?(Formula)
|
||||
if formula_or_cask.head_only?
|
||||
ohai name
|
||||
@ -68,7 +92,13 @@ module Homebrew
|
||||
end
|
||||
|
||||
package_data = Repology.single_package_query(name, repository: repository)
|
||||
retrieve_and_display_info(formula_or_cask, name, package_data&.values&.first, args: args)
|
||||
retrieve_and_display_info(
|
||||
formula_or_cask,
|
||||
name,
|
||||
package_data&.values&.first,
|
||||
args: args,
|
||||
ambiguous_cask: ambiguous_casks.include?(formula_or_cask),
|
||||
)
|
||||
end
|
||||
else
|
||||
api_response = {}
|
||||
@ -105,9 +135,14 @@ module Homebrew
|
||||
next
|
||||
end
|
||||
name = Livecheck.formula_or_cask_name(formula_or_cask)
|
||||
ambiguous_cask = begin
|
||||
formula_or_cask.is_a?(Cask::Cask) && !args.cask? && Formula[name]
|
||||
rescue FormulaUnavailableError
|
||||
false
|
||||
end
|
||||
|
||||
puts if i.positive?
|
||||
retrieve_and_display_info(formula_or_cask, name, repositories, args: args)
|
||||
retrieve_and_display_info(formula_or_cask, name, repositories, args: args, ambiguous_cask: ambiguous_cask)
|
||||
|
||||
break if limit && i >= limit
|
||||
end
|
||||
@ -145,7 +180,7 @@ module Homebrew
|
||||
pull_requests
|
||||
end
|
||||
|
||||
def retrieve_and_display_info(formula_or_cask, name, repositories, args:)
|
||||
def retrieve_and_display_info(formula_or_cask, name, repositories, args:, ambiguous_cask: false)
|
||||
current_version = if formula_or_cask.is_a?(Formula)
|
||||
formula_or_cask.stable.version
|
||||
else
|
||||
@ -161,6 +196,7 @@ module Homebrew
|
||||
livecheck_latest = livecheck_result(formula_or_cask)
|
||||
pull_requests = retrieve_pull_requests(formula_or_cask, name) unless args.no_pull_requests?
|
||||
|
||||
name += " (cask)" if ambiguous_cask
|
||||
title = if current_version == repology_latest &&
|
||||
current_version == livecheck_latest
|
||||
"#{name} is up to date!"
|
||||
|
||||
@ -61,54 +61,55 @@ module Homebrew
|
||||
puts ENV["HOMEBREW_LIVECHECK_WATCHLIST"] if ENV["HOMEBREW_LIVECHECK_WATCHLIST"].present?
|
||||
end
|
||||
|
||||
formulae_and_casks_to_check =
|
||||
if args.tap
|
||||
tap = Tap.fetch(args.tap)
|
||||
formulae = args.cask? ? [] : tap.formula_files.map { |path| Formulary.factory(path) }
|
||||
casks = args.formula? ? [] : tap.cask_files.map { |path| Cask::CaskLoader.load(path) }
|
||||
formulae + casks
|
||||
elsif args.installed?
|
||||
formulae = args.cask? ? [] : Formula.installed
|
||||
casks = args.formula? ? [] : Cask::Caskroom.casks
|
||||
formulae + casks
|
||||
elsif args.all?
|
||||
formulae = args.cask? ? [] : Formula.to_a
|
||||
casks = args.formula? ? [] : Cask::Cask.to_a
|
||||
formulae + casks
|
||||
elsif args.named.present?
|
||||
if args.formula?
|
||||
args.named.to_formulae
|
||||
elsif args.cask?
|
||||
args.named.to_casks
|
||||
else
|
||||
args.named.to_formulae_and_casks
|
||||
end
|
||||
elsif File.exist?(WATCHLIST_PATH)
|
||||
begin
|
||||
names = Pathname.new(WATCHLIST_PATH).read.lines
|
||||
.reject { |line| line.start_with?("#") || line.blank? }
|
||||
.map(&:strip)
|
||||
|
||||
named_args = T.unsafe(CLI::NamedArgs).new(*names, parent: args)
|
||||
named_args.to_formulae_and_casks(ignore_unavailable: true)
|
||||
rescue Errno::ENOENT => e
|
||||
onoe e
|
||||
end
|
||||
formulae_and_casks_to_check = if args.tap
|
||||
tap = Tap.fetch(args.tap)
|
||||
formulae = args.cask? ? [] : tap.formula_files.map { |path| Formulary.factory(path) }
|
||||
casks = args.formula? ? [] : tap.cask_files.map { |path| Cask::CaskLoader.load(path) }
|
||||
formulae + casks
|
||||
elsif args.installed?
|
||||
formulae = args.cask? ? [] : Formula.installed
|
||||
casks = args.formula? ? [] : Cask::Caskroom.casks
|
||||
formulae + casks
|
||||
elsif args.all?
|
||||
formulae = args.cask? ? [] : Formula.to_a
|
||||
casks = args.formula? ? [] : Cask::Cask.to_a
|
||||
formulae + casks
|
||||
elsif args.named.present?
|
||||
if args.formula?
|
||||
args.named.to_formulae
|
||||
elsif args.cask?
|
||||
args.named.to_casks
|
||||
else
|
||||
raise UsageError, "A watchlist file is required when no arguments are given."
|
||||
end&.sort_by do |formula_or_cask|
|
||||
formula_or_cask.respond_to?(:token) ? formula_or_cask.token : formula_or_cask.name
|
||||
args.named.to_formulae_and_casks
|
||||
end
|
||||
elsif File.exist?(WATCHLIST_PATH)
|
||||
begin
|
||||
names = Pathname.new(WATCHLIST_PATH).read.lines
|
||||
.reject { |line| line.start_with?("#") || line.blank? }
|
||||
.map(&:strip)
|
||||
|
||||
named_args = T.unsafe(CLI::NamedArgs).new(*names, parent: args)
|
||||
named_args.to_formulae_and_casks(ignore_unavailable: true)
|
||||
rescue Errno::ENOENT => e
|
||||
onoe e
|
||||
end
|
||||
else
|
||||
raise UsageError, "A watchlist file is required when no arguments are given."
|
||||
end
|
||||
formulae_and_casks_to_check = formulae_and_casks_to_check.sort_by do |formula_or_cask|
|
||||
formula_or_cask.respond_to?(:token) ? formula_or_cask.token : formula_or_cask.name
|
||||
end
|
||||
|
||||
raise UsageError, "No formulae or casks to check." if formulae_and_casks_to_check.blank?
|
||||
|
||||
options = {
|
||||
json: args.json?,
|
||||
full_name: args.full_name?,
|
||||
newer_only: args.newer_only?,
|
||||
quiet: args.quiet?,
|
||||
debug: args.debug?,
|
||||
verbose: args.verbose?,
|
||||
json: args.json?,
|
||||
full_name: args.full_name?,
|
||||
handle_name_conflict: !args.formula? && !args.cask?,
|
||||
newer_only: args.newer_only?,
|
||||
quiet: args.quiet?,
|
||||
debug: args.debug?,
|
||||
verbose: args.verbose?,
|
||||
}.compact
|
||||
|
||||
Livecheck.run_checks(formulae_and_casks_to_check, **options)
|
||||
|
||||
@ -63,7 +63,7 @@ module Homebrew
|
||||
|
||||
# Uses `formulae_and_casks_to_check` to identify taps in use other than
|
||||
# homebrew/core and homebrew/cask and loads strategies from them.
|
||||
sig { params(formulae_and_casks_to_check: T::Enumerable[T.any(Formula, Cask::Cask)]).void }
|
||||
sig { params(formulae_and_casks_to_check: T::Array[T.any(Formula, Cask::Cask)]).void }
|
||||
def load_other_tap_strategies(formulae_and_casks_to_check)
|
||||
other_taps = {}
|
||||
formulae_and_casks_to_check.each do |formula_or_cask|
|
||||
@ -86,8 +86,9 @@ module Homebrew
|
||||
# `formulae_and_casks_to_check` array and prints the results.
|
||||
sig {
|
||||
params(
|
||||
formulae_and_casks_to_check: T::Enumerable[T.any(Formula, Cask::Cask)],
|
||||
formulae_and_casks_to_check: T::Array[T.any(Formula, Cask::Cask)],
|
||||
full_name: T::Boolean,
|
||||
handle_name_conflict: T::Boolean,
|
||||
json: T::Boolean,
|
||||
newer_only: T::Boolean,
|
||||
debug: T::Boolean,
|
||||
@ -97,10 +98,29 @@ module Homebrew
|
||||
}
|
||||
def run_checks(
|
||||
formulae_and_casks_to_check,
|
||||
full_name: false, json: false, newer_only: false, debug: false, quiet: false, verbose: false
|
||||
full_name: false, handle_name_conflict: false, json: false, newer_only: false,
|
||||
debug: false, quiet: false, verbose: false
|
||||
)
|
||||
load_other_tap_strategies(formulae_and_casks_to_check)
|
||||
|
||||
ambiguous_casks = []
|
||||
if handle_name_conflict
|
||||
ambiguous_casks = formulae_and_casks_to_check.group_by { |item| formula_or_cask_name(item, full_name: true) }
|
||||
.values
|
||||
.select { |items| items.length > 1 }
|
||||
.flatten
|
||||
.select { |item| item.is_a?(Cask::Cask) }
|
||||
end
|
||||
|
||||
ambiguous_names = []
|
||||
unless full_name
|
||||
ambiguous_names =
|
||||
(formulae_and_casks_to_check - ambiguous_casks).group_by { |item| formula_or_cask_name(item) }
|
||||
.values
|
||||
.select { |items| items.length > 1 }
|
||||
.flatten
|
||||
end
|
||||
|
||||
has_a_newer_upstream_version = T.let(false, T::Boolean)
|
||||
|
||||
if json && !quiet && $stderr.tty?
|
||||
@ -122,7 +142,9 @@ module Homebrew
|
||||
formulae_checked = formulae_and_casks_to_check.map.with_index do |formula_or_cask, i|
|
||||
formula = formula_or_cask if formula_or_cask.is_a?(Formula)
|
||||
cask = formula_or_cask if formula_or_cask.is_a?(Cask::Cask)
|
||||
name = formula_or_cask_name(formula_or_cask, full_name: full_name)
|
||||
|
||||
use_full_name = full_name || ambiguous_names.include?(formula_or_cask)
|
||||
name = formula_or_cask_name(formula_or_cask, full_name: use_full_name)
|
||||
|
||||
if debug && i.positive?
|
||||
puts <<~EOS
|
||||
@ -130,9 +152,11 @@ module Homebrew
|
||||
----------
|
||||
|
||||
EOS
|
||||
elsif debug
|
||||
puts
|
||||
end
|
||||
|
||||
skip_info = SkipConditions.skip_information(formula_or_cask, full_name: full_name, verbose: verbose)
|
||||
skip_info = SkipConditions.skip_information(formula_or_cask, full_name: use_full_name, verbose: verbose)
|
||||
if skip_info.present?
|
||||
next skip_info if json
|
||||
|
||||
@ -164,7 +188,7 @@ module Homebrew
|
||||
else
|
||||
version_info = latest_version(
|
||||
formula_or_cask,
|
||||
json: json, full_name: full_name, verbose: verbose, debug: debug,
|
||||
json: json, full_name: use_full_name, verbose: verbose, debug: debug,
|
||||
)
|
||||
version_info[:latest] if version_info.present?
|
||||
end
|
||||
@ -175,7 +199,7 @@ module Homebrew
|
||||
|
||||
next version_info if version_info.is_a?(Hash) && version_info[:status] && version_info[:messages]
|
||||
|
||||
next status_hash(formula_or_cask, "error", [no_versions_msg], full_name: full_name, verbose: verbose)
|
||||
next status_hash(formula_or_cask, "error", [no_versions_msg], full_name: use_full_name, verbose: verbose)
|
||||
end
|
||||
|
||||
if (m = latest.to_s.match(/(.*)-release$/)) && !current.to_s.match(/.*-release$/)
|
||||
@ -220,15 +244,19 @@ module Homebrew
|
||||
next info
|
||||
end
|
||||
|
||||
print_latest_version(info, verbose: verbose)
|
||||
print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask))
|
||||
nil
|
||||
rescue => e
|
||||
Homebrew.failed = true
|
||||
use_full_name = full_name || ambiguous_names.include?(formula_or_cask)
|
||||
|
||||
if json
|
||||
progress&.increment
|
||||
status_hash(formula_or_cask, "error", [e.to_s], full_name: full_name, verbose: verbose)
|
||||
status_hash(formula_or_cask, "error", [e.to_s], full_name: use_full_name, verbose: verbose)
|
||||
elsif !quiet
|
||||
name = formula_or_cask_name(formula_or_cask, full_name: use_full_name)
|
||||
name += " (cask)" if ambiguous_casks.include?(formula_or_cask)
|
||||
|
||||
onoe "#{Tty.blue}#{name}#{Tty.reset}: #{e}"
|
||||
$stderr.puts e.backtrace if debug && !e.is_a?(Livecheck::Error)
|
||||
nil
|
||||
@ -306,9 +334,10 @@ module Homebrew
|
||||
end
|
||||
|
||||
# Formats and prints the livecheck result for a formula.
|
||||
sig { params(info: Hash, verbose: T::Boolean).void }
|
||||
def print_latest_version(info, verbose:)
|
||||
sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean).void }
|
||||
def print_latest_version(info, verbose:, ambiguous_cask: false)
|
||||
formula_or_cask_s = "#{Tty.blue}#{info[:formula] || info[:cask]}#{Tty.reset}"
|
||||
formula_or_cask_s += " (cask)" if ambiguous_cask
|
||||
formula_or_cask_s += " (guessed)" if !info[:meta][:livecheckable] && verbose
|
||||
|
||||
current_s = if info[:version][:newer_than_upstream]
|
||||
@ -438,7 +467,6 @@ module Homebrew
|
||||
urls ||= checkable_urls(formula_or_cask)
|
||||
|
||||
if debug
|
||||
puts
|
||||
if formula
|
||||
puts "Formula: #{formula_name(formula, full_name: full_name)}"
|
||||
puts "Head only?: true" if formula.head_only?
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user