Merge pull request #10651 from nandahkrishna/formula-cask-disambiguation

livecheck and bump: formula/cask disambiguation
This commit is contained in:
Mike McQuaid 2021-03-15 11:37:34 +00:00 committed by GitHub
commit 3afa9b078e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 126 additions and 61 deletions

View File

@ -16,6 +16,8 @@ module Homebrew
Display out-of-date brew formulae and the latest version available. Display out-of-date brew formulae and the latest version available.
Also displays whether a pull request has been opened with the URL. Also displays whether a pull request has been opened with the URL.
EOS EOS
switch "--full-name",
description: "Print formulae/casks with fully-qualified names."
switch "--no-pull-requests", switch "--no-pull-requests",
description: "Do not retrieve pull requests from GitHub." description: "Do not retrieve pull requests from GitHub."
switch "--formula", "--formulae", switch "--formula", "--formulae",
@ -39,11 +41,14 @@ module Homebrew
end end
formulae_and_casks = if args.formula? formulae_and_casks = if args.formula?
args.named.to_formulae.presence args.named.to_formulae
elsif args.cask? elsif args.cask?
args.named.to_casks.presence args.named.to_casks
else 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 end
limit = args.limit.to_i if args.limit.present? limit = args.limit.to_i if args.limit.present?
@ -51,10 +56,29 @@ module Homebrew
if formulae_and_casks if formulae_and_casks
Livecheck.load_other_tap_strategies(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| formulae_and_casks.each_with_index do |formula_or_cask, i|
puts if i.positive? 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) repository = if formula_or_cask.is_a?(Formula)
if formula_or_cask.head_only? if formula_or_cask.head_only?
ohai name ohai name
@ -68,7 +92,13 @@ module Homebrew
end end
package_data = Repology.single_package_query(name, repository: repository) 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 end
else else
api_response = {} api_response = {}
@ -105,9 +135,14 @@ module Homebrew
next next
end end
name = Livecheck.formula_or_cask_name(formula_or_cask) 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? 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 break if limit && i >= limit
end end
@ -145,7 +180,7 @@ module Homebrew
pull_requests pull_requests
end 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) current_version = if formula_or_cask.is_a?(Formula)
formula_or_cask.stable.version formula_or_cask.stable.version
else else
@ -161,6 +196,7 @@ module Homebrew
livecheck_latest = livecheck_result(formula_or_cask) livecheck_latest = livecheck_result(formula_or_cask)
pull_requests = retrieve_pull_requests(formula_or_cask, name) unless args.no_pull_requests? 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 && title = if current_version == repology_latest &&
current_version == livecheck_latest current_version == livecheck_latest
"#{name} is up to date!" "#{name} is up to date!"

View File

@ -61,8 +61,7 @@ module Homebrew
puts ENV["HOMEBREW_LIVECHECK_WATCHLIST"] if ENV["HOMEBREW_LIVECHECK_WATCHLIST"].present? puts ENV["HOMEBREW_LIVECHECK_WATCHLIST"] if ENV["HOMEBREW_LIVECHECK_WATCHLIST"].present?
end end
formulae_and_casks_to_check = formulae_and_casks_to_check = if args.tap
if args.tap
tap = Tap.fetch(args.tap) tap = Tap.fetch(args.tap)
formulae = args.cask? ? [] : tap.formula_files.map { |path| Formulary.factory(path) } formulae = args.cask? ? [] : tap.formula_files.map { |path| Formulary.factory(path) }
casks = args.formula? ? [] : tap.cask_files.map { |path| Cask::CaskLoader.load(path) } casks = args.formula? ? [] : tap.cask_files.map { |path| Cask::CaskLoader.load(path) }
@ -96,7 +95,8 @@ module Homebrew
end end
else else
raise UsageError, "A watchlist file is required when no arguments are given." raise UsageError, "A watchlist file is required when no arguments are given."
end&.sort_by do |formula_or_cask| 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 formula_or_cask.respond_to?(:token) ? formula_or_cask.token : formula_or_cask.name
end end
@ -105,6 +105,7 @@ module Homebrew
options = { options = {
json: args.json?, json: args.json?,
full_name: args.full_name?, full_name: args.full_name?,
handle_name_conflict: !args.formula? && !args.cask?,
newer_only: args.newer_only?, newer_only: args.newer_only?,
quiet: args.quiet?, quiet: args.quiet?,
debug: args.debug?, debug: args.debug?,

View File

@ -63,7 +63,7 @@ module Homebrew
# Uses `formulae_and_casks_to_check` to identify taps in use other than # Uses `formulae_and_casks_to_check` to identify taps in use other than
# homebrew/core and homebrew/cask and loads strategies from them. # 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) def load_other_tap_strategies(formulae_and_casks_to_check)
other_taps = {} other_taps = {}
formulae_and_casks_to_check.each do |formula_or_cask| 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. # `formulae_and_casks_to_check` array and prints the results.
sig { sig {
params( 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, full_name: T::Boolean,
handle_name_conflict: T::Boolean,
json: T::Boolean, json: T::Boolean,
newer_only: T::Boolean, newer_only: T::Boolean,
debug: T::Boolean, debug: T::Boolean,
@ -97,10 +98,29 @@ module Homebrew
} }
def run_checks( def run_checks(
formulae_and_casks_to_check, 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) 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) has_a_newer_upstream_version = T.let(false, T::Boolean)
if json && !quiet && $stderr.tty? 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| 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) formula = formula_or_cask if formula_or_cask.is_a?(Formula)
cask = formula_or_cask if formula_or_cask.is_a?(Cask::Cask) 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? if debug && i.positive?
puts <<~EOS puts <<~EOS
@ -130,9 +152,11 @@ module Homebrew
---------- ----------
EOS EOS
elsif debug
puts
end 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? if skip_info.present?
next skip_info if json next skip_info if json
@ -164,7 +188,7 @@ module Homebrew
else else
version_info = latest_version( version_info = latest_version(
formula_or_cask, 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? version_info[:latest] if version_info.present?
end end
@ -175,7 +199,7 @@ module Homebrew
next version_info if version_info.is_a?(Hash) && version_info[:status] && version_info[:messages] 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 end
if (m = latest.to_s.match(/(.*)-release$/)) && !current.to_s.match(/.*-release$/) if (m = latest.to_s.match(/(.*)-release$/)) && !current.to_s.match(/.*-release$/)
@ -220,15 +244,19 @@ module Homebrew
next info next info
end end
print_latest_version(info, verbose: verbose) print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask))
nil nil
rescue => e rescue => e
Homebrew.failed = true Homebrew.failed = true
use_full_name = full_name || ambiguous_names.include?(formula_or_cask)
if json if json
progress&.increment 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 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}" onoe "#{Tty.blue}#{name}#{Tty.reset}: #{e}"
$stderr.puts e.backtrace if debug && !e.is_a?(Livecheck::Error) $stderr.puts e.backtrace if debug && !e.is_a?(Livecheck::Error)
nil nil
@ -306,9 +334,10 @@ module Homebrew
end end
# Formats and prints the livecheck result for a formula. # Formats and prints the livecheck result for a formula.
sig { params(info: Hash, verbose: T::Boolean).void } sig { params(info: Hash, verbose: T::Boolean, ambiguous_cask: T::Boolean).void }
def print_latest_version(info, verbose:) 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 = "#{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 formula_or_cask_s += " (guessed)" if !info[:meta][:livecheckable] && verbose
current_s = if info[:version][:newer_than_upstream] current_s = if info[:version][:newer_than_upstream]
@ -438,7 +467,6 @@ module Homebrew
urls ||= checkable_urls(formula_or_cask) urls ||= checkable_urls(formula_or_cask)
if debug if debug
puts
if formula if formula
puts "Formula: #{formula_name(formula, full_name: full_name)}" puts "Formula: #{formula_name(formula, full_name: full_name)}"
puts "Head only?: true" if formula.head_only? puts "Head only?: true" if formula.head_only?