Merge branch 'Homebrew:master' into info-json-time
This commit is contained in:
commit
316568e78d
@ -58,7 +58,7 @@ GEM
|
||||
mime-types-data (3.2022.0105)
|
||||
mini_portile2 (2.8.0)
|
||||
minitest (5.16.3)
|
||||
msgpack (1.5.6)
|
||||
msgpack (1.6.0)
|
||||
mustache (1.1.1)
|
||||
net-http-digest_auth (1.4.1)
|
||||
net-http-persistent (4.0.1)
|
||||
@ -122,7 +122,7 @@ GEM
|
||||
rspec-support (3.11.1)
|
||||
rspec-wait (0.0.9)
|
||||
rspec (>= 3, < 4)
|
||||
rspec_junit_formatter (0.5.1)
|
||||
rspec_junit_formatter (0.6.0)
|
||||
rspec-core (>= 2, < 4, != 2.12.0)
|
||||
rubocop (1.35.1)
|
||||
json (~> 2.3)
|
||||
|
@ -508,18 +508,9 @@ else
|
||||
: "${HOMEBREW_OS_VERSION:=$(uname -r)}"
|
||||
HOMEBREW_OS_USER_AGENT_VERSION="${HOMEBREW_OS_VERSION}"
|
||||
|
||||
# This is set by the user environment.
|
||||
# shellcheck disable=SC2154
|
||||
if [[ -n "${HOMEBREW_ON_DEBIAN7}" ]]
|
||||
then
|
||||
# Special version for our debian 7 docker container used to build binutils
|
||||
HOMEBREW_MINIMUM_CURL_VERSION="7.25.0"
|
||||
HOMEBREW_SYSTEM_CA_CERTIFICATES_TOO_OLD="1"
|
||||
HOMEBREW_FORCE_BREWED_CA_CERTIFICATES="1"
|
||||
else
|
||||
# Ensure the system Curl is a version that supports modern HTTPS certificates.
|
||||
HOMEBREW_MINIMUM_CURL_VERSION="7.41.0"
|
||||
fi
|
||||
# Ensure the system Curl is a version that supports modern HTTPS certificates.
|
||||
HOMEBREW_MINIMUM_CURL_VERSION="7.41.0"
|
||||
|
||||
curl_version_output="$(${HOMEBREW_CURL} --version 2>/dev/null)"
|
||||
curl_name_and_version="${curl_version_output%% (*}"
|
||||
# shellcheck disable=SC2248
|
||||
|
@ -56,7 +56,8 @@ module Cask
|
||||
require_sha: nil,
|
||||
quarantine: nil,
|
||||
quiet: nil,
|
||||
zap: nil
|
||||
zap: nil,
|
||||
dry_run: nil
|
||||
)
|
||||
odie "Installing casks is supported only on macOS" unless OS.mac?
|
||||
|
||||
@ -73,6 +74,27 @@ module Cask
|
||||
|
||||
options[:quarantine] = true if options[:quarantine].nil?
|
||||
|
||||
if dry_run
|
||||
if (casks_to_install = casks.reject(&:installed?).presence)
|
||||
plural = "cask".pluralize(casks_to_install.count)
|
||||
ohai "Would install #{casks_to_install.count} #{plural}:"
|
||||
puts casks_to_install.map(&:full_name).join(" ")
|
||||
end
|
||||
casks.each do |cask|
|
||||
dep_names = CaskDependent.new(cask)
|
||||
.runtime_dependencies
|
||||
.reject(&:installed?)
|
||||
.map(&:to_formula)
|
||||
.map(&:name)
|
||||
next if dep_names.blank?
|
||||
|
||||
plural = "dependency".pluralize(dep_names.count)
|
||||
ohai "Would install #{dep_names.count} #{plural} for #{cask.full_name}:"
|
||||
puts dep_names.join(" ")
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
require "cask/installer"
|
||||
|
||||
casks.each do |cask|
|
||||
|
@ -30,6 +30,9 @@ module Homebrew
|
||||
sig { returns(T::Boolean) }
|
||||
def newer_only?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def resources?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def full_name?; end
|
||||
|
||||
|
@ -45,6 +45,8 @@ module Homebrew
|
||||
"(binaries and symlinks are excluded, unless originally from the same cask)."
|
||||
switch "-v", "--verbose",
|
||||
description: "Print the verification and postinstall steps."
|
||||
switch "-n", "--dry-run",
|
||||
description: "Show what would be installed, but do not actually install anything."
|
||||
[
|
||||
[:switch, "--formula", "--formulae", {
|
||||
description: "Treat all named arguments as formulae.",
|
||||
@ -193,6 +195,7 @@ module Homebrew
|
||||
skip_cask_deps: args.skip_cask_deps?,
|
||||
quarantine: args.quarantine?,
|
||||
quiet: args.quiet?,
|
||||
dry_run: args.dry_run?,
|
||||
)
|
||||
end
|
||||
|
||||
@ -242,6 +245,7 @@ module Homebrew
|
||||
debug: args.debug?,
|
||||
quiet: args.quiet?,
|
||||
verbose: args.verbose?,
|
||||
dry_run: args.dry_run?,
|
||||
)
|
||||
|
||||
Upgrade.check_installed_dependents(
|
||||
@ -257,9 +261,10 @@ module Homebrew
|
||||
debug: args.debug?,
|
||||
quiet: args.quiet?,
|
||||
verbose: args.verbose?,
|
||||
dry_run: args.dry_run?,
|
||||
)
|
||||
|
||||
Cleanup.periodic_clean!
|
||||
Cleanup.periodic_clean!(dry_run: args.dry_run?)
|
||||
|
||||
Homebrew.messages.display_messages(display_times: args.display_times?)
|
||||
rescue FormulaUnreadableError, FormulaClassUnavailableError,
|
||||
|
@ -188,19 +188,6 @@ module Homebrew
|
||||
GitHub.create_bump_pr(pr_info, args: args)
|
||||
end
|
||||
|
||||
def fetch_cask(contents, config: nil)
|
||||
cask = Cask::CaskLoader.load(contents)
|
||||
cask.config = config if config.present?
|
||||
old_hash = cask.sha256.to_s
|
||||
|
||||
cask_download = Cask::Download.new(cask, quarantine: true)
|
||||
download = cask_download.fetch(verify_download_integrity: false)
|
||||
Utils::Tar.validate_file(download)
|
||||
new_hash = download.sha256
|
||||
|
||||
[old_hash, new_hash]
|
||||
end
|
||||
|
||||
def check_open_pull_requests(cask, args:)
|
||||
tap_remote_repo = cask.tap.remote_repo || cask.tap.full_name
|
||||
GitHub.check_for_duplicate_pull_requests(cask.token, tap_remote_repo,
|
||||
|
@ -72,17 +72,18 @@ module Homebrew
|
||||
|
||||
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) }
|
||||
ambiguous_casks = formulae_and_casks \
|
||||
.group_by { |item| Livecheck.package_or_resource_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) }
|
||||
(formulae_and_casks - ambiguous_casks).group_by { |item| Livecheck.package_or_resource_name(item) }
|
||||
.values
|
||||
.select { |items| items.length > 1 }
|
||||
.flatten
|
||||
@ -92,7 +93,7 @@ module Homebrew
|
||||
puts if i.positive?
|
||||
|
||||
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)
|
||||
name = Livecheck.package_or_resource_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
|
||||
@ -157,7 +158,7 @@ module Homebrew
|
||||
rescue
|
||||
next
|
||||
end
|
||||
name = Livecheck.formula_or_cask_name(formula_or_cask)
|
||||
name = Livecheck.package_or_resource_name(formula_or_cask)
|
||||
ambiguous_cask = begin
|
||||
formula_or_cask.is_a?(Cask::Cask) && !args.cask? && Formula[name]
|
||||
rescue FormulaUnavailableError
|
||||
@ -178,7 +179,7 @@ module Homebrew
|
||||
end
|
||||
|
||||
def livecheck_result(formula_or_cask)
|
||||
name = Livecheck.formula_or_cask_name(formula_or_cask)
|
||||
name = Livecheck.package_or_resource_name(formula_or_cask)
|
||||
|
||||
referenced_formula_or_cask, =
|
||||
Livecheck.resolve_livecheck_reference(formula_or_cask, full_name: false, debug: false)
|
||||
|
@ -37,6 +37,8 @@ module Homebrew
|
||||
description: "Show the latest version only if it's newer than the formula/cask."
|
||||
switch "--json",
|
||||
description: "Output information in JSON format."
|
||||
switch "-r", "--resources",
|
||||
description: "Also check resources for formulae."
|
||||
switch "-q", "--quiet",
|
||||
description: "Suppress warnings, don't print a progress bar for JSON output."
|
||||
switch "--formula", "--formulae",
|
||||
@ -101,6 +103,7 @@ module Homebrew
|
||||
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
|
||||
@ -111,6 +114,7 @@ module Homebrew
|
||||
json: args.json?,
|
||||
full_name: args.full_name?,
|
||||
handle_name_conflict: !args.formula? && !args.cask?,
|
||||
check_resources: args.resources?,
|
||||
newer_only: args.newer_only?,
|
||||
quiet: args.quiet?,
|
||||
debug: args.debug?,
|
||||
|
@ -7,6 +7,7 @@ class LinkageChecker
|
||||
# Libraries provided by glibc and gcc.
|
||||
SYSTEM_LIBRARY_ALLOWLIST = %w[
|
||||
ld-linux-x86-64.so.2
|
||||
ld-linux-aarch64.so.1
|
||||
libanl.so.1
|
||||
libatomic.so.1
|
||||
libc.so.6
|
||||
|
@ -11,7 +11,7 @@ module Hardware
|
||||
INTEL_64BIT_ARCHS = [:x86_64].freeze
|
||||
PPC_32BIT_ARCHS = [:ppc, :ppc32, :ppc7400, :ppc7450, :ppc970].freeze
|
||||
PPC_64BIT_ARCHS = [:ppc64, :ppc64le, :ppc970].freeze
|
||||
ARM_64BIT_ARCHS = [:arm64].freeze
|
||||
ARM_64BIT_ARCHS = [:arm64, :aarch64].freeze
|
||||
ALL_ARCHS = [
|
||||
*INTEL_32BIT_ARCHS,
|
||||
*INTEL_64BIT_ARCHS,
|
||||
|
@ -278,10 +278,11 @@ module Homebrew
|
||||
overwrite: false,
|
||||
debug: false,
|
||||
quiet: false,
|
||||
verbose: false
|
||||
verbose: false,
|
||||
dry_run: false
|
||||
)
|
||||
formula_installers = formulae_to_install.map do |f|
|
||||
Migrator.migrate_if_needed(f, force: force)
|
||||
Migrator.migrate_if_needed(f, force: force, dry_run: dry_run)
|
||||
build_options = f.build
|
||||
|
||||
fi = FormulaInstaller.new(
|
||||
@ -307,8 +308,10 @@ module Homebrew
|
||||
)
|
||||
|
||||
begin
|
||||
fi.prelude
|
||||
fi.fetch
|
||||
unless dry_run
|
||||
fi.prelude
|
||||
fi.fetch
|
||||
end
|
||||
fi
|
||||
rescue CannotInstallFormulaError => e
|
||||
ofail e.message
|
||||
@ -319,6 +322,20 @@ module Homebrew
|
||||
end
|
||||
end.compact
|
||||
|
||||
if dry_run
|
||||
if (formulae_name_to_install = formulae_to_install.map(&:name))
|
||||
plural = "formula".pluralize(formulae_name_to_install.count)
|
||||
ohai "Would install #{formulae_name_to_install.count} #{plural}:"
|
||||
puts formulae_name_to_install.join(" ")
|
||||
|
||||
formula_installers.each do |fi|
|
||||
f = fi.formula
|
||||
print_dry_run_dependencies(f, fi.compute_dependencies, &:name)
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
formula_installers.each do |fi|
|
||||
install_formula(fi)
|
||||
Cleanup.install_formula_clean!(fi.formula)
|
||||
@ -333,6 +350,15 @@ module Homebrew
|
||||
Upgrade.install_formula(formula_installer, upgrade: upgrade)
|
||||
end
|
||||
private_class_method :install_formula
|
||||
|
||||
def print_dry_run_dependencies(formula, dependencies, &block)
|
||||
return if dependencies.empty?
|
||||
|
||||
plural = "dependency".pluralize(dependencies.count)
|
||||
ohai "Would install #{dependencies.count} #{plural} for #{formula.name}:"
|
||||
formula_names = dependencies.map(&:first).map(&:to_formula).map(&block)
|
||||
puts formula_names.join(" ")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -126,11 +126,11 @@ module Homebrew
|
||||
if debug
|
||||
# Print the chain of references for debugging
|
||||
puts "Reference Chain:"
|
||||
puts formula_or_cask_name(first_formula_or_cask, full_name: full_name)
|
||||
puts package_or_resource_name(first_formula_or_cask, full_name: full_name)
|
||||
|
||||
references << referenced_formula_or_cask
|
||||
references.each do |ref_formula_or_cask|
|
||||
puts formula_or_cask_name(ref_formula_or_cask, full_name: full_name)
|
||||
puts package_or_resource_name(ref_formula_or_cask, full_name: full_name)
|
||||
end
|
||||
end
|
||||
|
||||
@ -157,11 +157,14 @@ module Homebrew
|
||||
|
||||
# Executes the livecheck logic for each formula/cask in the
|
||||
# `formulae_and_casks_to_check` array and prints the results.
|
||||
# rubocop:disable Metrics/CyclomaticComplexity
|
||||
# rubocop:disable Metrics/PerceivedComplexity
|
||||
sig {
|
||||
params(
|
||||
formulae_and_casks_to_check: T::Array[T.any(Formula, Cask::Cask)],
|
||||
full_name: T::Boolean,
|
||||
handle_name_conflict: T::Boolean,
|
||||
check_resources: T::Boolean,
|
||||
json: T::Boolean,
|
||||
newer_only: T::Boolean,
|
||||
debug: T::Boolean,
|
||||
@ -171,24 +174,25 @@ module Homebrew
|
||||
}
|
||||
def run_checks(
|
||||
formulae_and_casks_to_check,
|
||||
full_name: false, handle_name_conflict: false, json: false, newer_only: false,
|
||||
full_name: false, handle_name_conflict: false, check_resources: 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) }
|
||||
ambiguous_casks = formulae_and_casks_to_check \
|
||||
.group_by { |item| package_or_resource_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) }
|
||||
(formulae_and_casks_to_check - ambiguous_casks).group_by { |item| package_or_resource_name(item) }
|
||||
.values
|
||||
.select { |items| items.length > 1 }
|
||||
.flatten
|
||||
@ -218,7 +222,7 @@ module Homebrew
|
||||
cask = formula_or_cask if formula_or_cask.is_a?(Cask::Cask)
|
||||
|
||||
use_full_name = full_name || ambiguous_names.include?(formula_or_cask)
|
||||
name = formula_or_cask_name(formula_or_cask, full_name: use_full_name)
|
||||
name = package_or_resource_name(formula_or_cask, full_name: use_full_name)
|
||||
|
||||
referenced_formula_or_cask, livecheck_references =
|
||||
resolve_livecheck_reference(formula_or_cask, full_name: use_full_name, debug: debug)
|
||||
@ -282,6 +286,30 @@ module Homebrew
|
||||
version_info[:latest] if version_info.present?
|
||||
end
|
||||
|
||||
check_for_resources = check_resources && formula_or_cask.is_a?(Formula) && formula_or_cask.resources.present?
|
||||
if check_for_resources
|
||||
resource_version_info = formula_or_cask.resources.map do |resource|
|
||||
res_skip_info ||= SkipConditions.skip_information(resource, verbose: verbose)
|
||||
if res_skip_info.present?
|
||||
res_skip_info
|
||||
else
|
||||
res_version_info = resource_version(
|
||||
resource,
|
||||
json: json,
|
||||
debug: debug,
|
||||
quiet: quiet,
|
||||
verbose: verbose,
|
||||
)
|
||||
if res_version_info.empty?
|
||||
status_hash(resource, "error", ["Unable to get versions"], verbose: verbose)
|
||||
else
|
||||
res_version_info
|
||||
end
|
||||
end
|
||||
end.compact_blank
|
||||
Homebrew.failed = true if resource_version_info.any? { |info| info[:status] == "error" }
|
||||
end
|
||||
|
||||
if latest.blank?
|
||||
no_versions_msg = "Unable to get versions"
|
||||
raise Livecheck::Error, no_versions_msg unless json
|
||||
@ -289,7 +317,14 @@ 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: use_full_name, verbose: verbose)
|
||||
latest_info = status_hash(formula_or_cask, "error", [no_versions_msg], full_name: use_full_name,
|
||||
verbose: verbose)
|
||||
if check_for_resources
|
||||
resource_version_info.map! { |r| r.except!(:meta) } unless verbose
|
||||
latest_info[:resources] = resource_version_info
|
||||
end
|
||||
|
||||
next latest_info
|
||||
end
|
||||
|
||||
if (m = latest.to_s.match(/(.*)-release$/)) && !current.to_s.match(/.*-release$/)
|
||||
@ -324,6 +359,8 @@ module Homebrew
|
||||
info[:meta][:head_only] = true if formula&.head_only?
|
||||
info[:meta].merge!(version_info[:meta]) if version_info.present? && version_info.key?(:meta)
|
||||
|
||||
info[:resources] = resource_version_info if check_for_resources
|
||||
|
||||
next if newer_only && !info[:version][:outdated]
|
||||
|
||||
has_a_newer_upstream_version ||= true
|
||||
@ -331,10 +368,12 @@ module Homebrew
|
||||
if json
|
||||
progress&.increment
|
||||
info.except!(:meta) unless verbose
|
||||
resource_version_info.map! { |r| r.except!(:meta) } if check_for_resources && !verbose
|
||||
next info
|
||||
end
|
||||
|
||||
puts if debug
|
||||
print_latest_version(info, verbose: verbose, ambiguous_cask: ambiguous_casks.include?(formula_or_cask))
|
||||
print_resources_info(resource_version_info, verbose: verbose) if check_for_resources
|
||||
nil
|
||||
rescue => e
|
||||
Homebrew.failed = true
|
||||
@ -344,11 +383,12 @@ module Homebrew
|
||||
progress&.increment
|
||||
status_hash(formula_or_cask, "error", [e.to_s], full_name: use_full_name, verbose: verbose) unless quiet
|
||||
elsif !quiet
|
||||
name = formula_or_cask_name(formula_or_cask, full_name: use_full_name)
|
||||
name = package_or_resource_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)
|
||||
print_resources_info(resource_version_info, verbose: verbose) if check_for_resources
|
||||
nil
|
||||
end
|
||||
end
|
||||
@ -367,16 +407,20 @@ module Homebrew
|
||||
|
||||
puts JSON.pretty_generate(formulae_checked.compact)
|
||||
end
|
||||
# rubocop:enable Metrics/CyclomaticComplexity
|
||||
# rubocop:enable Metrics/PerceivedComplexity
|
||||
|
||||
sig { params(formula_or_cask: T.any(Formula, Cask::Cask), full_name: T::Boolean).returns(String) }
|
||||
def formula_or_cask_name(formula_or_cask, full_name: false)
|
||||
case formula_or_cask
|
||||
sig { params(package_or_resource: T.any(Formula, Cask::Cask, Resource), full_name: T::Boolean).returns(String) }
|
||||
def package_or_resource_name(package_or_resource, full_name: false)
|
||||
case package_or_resource
|
||||
when Formula
|
||||
formula_name(formula_or_cask, full_name: full_name)
|
||||
formula_name(package_or_resource, full_name: full_name)
|
||||
when Cask::Cask
|
||||
cask_name(formula_or_cask, full_name: full_name)
|
||||
cask_name(package_or_resource, full_name: full_name)
|
||||
when Resource
|
||||
package_or_resource.name
|
||||
else
|
||||
T.absurd(formula_or_cask)
|
||||
T.absurd(package_or_resource)
|
||||
end
|
||||
end
|
||||
|
||||
@ -396,40 +440,44 @@ module Homebrew
|
||||
|
||||
sig {
|
||||
params(
|
||||
formula_or_cask: T.any(Formula, Cask::Cask),
|
||||
status_str: String,
|
||||
messages: T.nilable(T::Array[String]),
|
||||
full_name: T::Boolean,
|
||||
verbose: T::Boolean,
|
||||
package_or_resource: T.any(Formula, Cask::Cask, Resource),
|
||||
status_str: String,
|
||||
messages: T.nilable(T::Array[String]),
|
||||
full_name: T::Boolean,
|
||||
verbose: T::Boolean,
|
||||
).returns(Hash)
|
||||
}
|
||||
def status_hash(formula_or_cask, status_str, messages = nil, full_name: false, verbose: false)
|
||||
formula = formula_or_cask if formula_or_cask.is_a?(Formula)
|
||||
cask = formula_or_cask if formula_or_cask.is_a?(Cask::Cask)
|
||||
def status_hash(package_or_resource, status_str, messages = nil, full_name: false, verbose: false)
|
||||
formula = package_or_resource if package_or_resource.is_a?(Formula)
|
||||
cask = package_or_resource if package_or_resource.is_a?(Cask::Cask)
|
||||
resource = package_or_resource if package_or_resource.is_a?(Resource)
|
||||
|
||||
status_hash = {}
|
||||
if formula
|
||||
status_hash[:formula] = formula_name(formula, full_name: full_name)
|
||||
elsif cask
|
||||
status_hash[:cask] = cask_name(formula_or_cask, full_name: full_name)
|
||||
status_hash[:cask] = cask_name(cask, full_name: full_name)
|
||||
elsif resource
|
||||
status_hash[:resource] = resource.name
|
||||
end
|
||||
status_hash[:status] = status_str
|
||||
status_hash[:messages] = messages if messages.is_a?(Array)
|
||||
|
||||
status_hash[:meta] = {
|
||||
livecheckable: formula_or_cask.livecheckable?,
|
||||
livecheckable: package_or_resource.livecheckable?,
|
||||
}
|
||||
status_hash[:meta][:head_only] = true if formula&.head_only?
|
||||
|
||||
status_hash
|
||||
end
|
||||
|
||||
# Formats and prints the livecheck result for a formula.
|
||||
# Formats and prints the livecheck result for a formula/cask/resource.
|
||||
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
|
||||
def print_latest_version(info, verbose: false, ambiguous_cask: false)
|
||||
package_or_resource_s = info[:resource].present? ? " " : ""
|
||||
package_or_resource_s += "#{Tty.blue}#{info[:formula] || info[:cask] || info[:resource]}#{Tty.reset}"
|
||||
package_or_resource_s += " (cask)" if ambiguous_cask
|
||||
package_or_resource_s += " (guessed)" if verbose && !info[:meta][:livecheckable]
|
||||
|
||||
current_s = if info[:version][:newer_than_upstream]
|
||||
"#{Tty.red}#{info[:version][:current]}#{Tty.reset}"
|
||||
@ -443,47 +491,61 @@ module Homebrew
|
||||
info[:version][:latest]
|
||||
end
|
||||
|
||||
puts "#{formula_or_cask_s}: #{current_s} ==> #{latest_s}"
|
||||
puts "#{package_or_resource_s}: #{current_s} ==> #{latest_s}"
|
||||
end
|
||||
|
||||
# Prints the livecheck result for the resources of a given Formula.
|
||||
sig { params(info: T::Array[Hash], verbose: T::Boolean).void }
|
||||
def print_resources_info(info, verbose: false)
|
||||
info.each do |r_info|
|
||||
if r_info[:status] && r_info[:messages]
|
||||
SkipConditions.print_skip_information(r_info)
|
||||
else
|
||||
print_latest_version(r_info, verbose: verbose)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
sig {
|
||||
params(
|
||||
livecheck_url: T.any(String, Symbol),
|
||||
formula_or_cask: T.any(Formula, Cask::Cask),
|
||||
livecheck_url: T.any(String, Symbol),
|
||||
package_or_resource: T.any(Formula, Cask::Cask, Resource),
|
||||
).returns(T.nilable(String))
|
||||
}
|
||||
def livecheck_url_to_string(livecheck_url, formula_or_cask)
|
||||
def livecheck_url_to_string(livecheck_url, package_or_resource)
|
||||
case livecheck_url
|
||||
when String
|
||||
livecheck_url
|
||||
when :url
|
||||
formula_or_cask.url&.to_s if formula_or_cask.is_a?(Cask::Cask)
|
||||
package_or_resource.url&.to_s if package_or_resource.is_a?(Cask::Cask) || package_or_resource.is_a?(Resource)
|
||||
when :head, :stable
|
||||
formula_or_cask.send(livecheck_url)&.url if formula_or_cask.is_a?(Formula)
|
||||
package_or_resource.send(livecheck_url)&.url if package_or_resource.is_a?(Formula)
|
||||
when :homepage
|
||||
formula_or_cask.homepage
|
||||
package_or_resource.homepage unless package_or_resource.is_a?(Resource)
|
||||
end
|
||||
end
|
||||
|
||||
# Returns an Array containing the formula/cask URLs that can be used by livecheck.
|
||||
sig { params(formula_or_cask: T.any(Formula, Cask::Cask)).returns(T::Array[String]) }
|
||||
def checkable_urls(formula_or_cask)
|
||||
# Returns an Array containing the formula/cask/resource URLs that can be used by livecheck.
|
||||
sig { params(package_or_resource: T.any(Formula, Cask::Cask, Resource)).returns(T::Array[String]) }
|
||||
def checkable_urls(package_or_resource)
|
||||
urls = []
|
||||
|
||||
case formula_or_cask
|
||||
case package_or_resource
|
||||
when Formula
|
||||
if formula_or_cask.stable
|
||||
urls << formula_or_cask.stable.url
|
||||
urls.concat(formula_or_cask.stable.mirrors)
|
||||
if package_or_resource.stable
|
||||
urls << package_or_resource.stable.url
|
||||
urls.concat(package_or_resource.stable.mirrors)
|
||||
end
|
||||
urls << formula_or_cask.head.url if formula_or_cask.head
|
||||
urls << formula_or_cask.homepage if formula_or_cask.homepage
|
||||
urls << package_or_resource.head.url if package_or_resource.head
|
||||
urls << package_or_resource.homepage if package_or_resource.homepage
|
||||
when Cask::Cask
|
||||
urls << formula_or_cask.appcast.to_s if formula_or_cask.appcast
|
||||
urls << formula_or_cask.url.to_s if formula_or_cask.url
|
||||
urls << formula_or_cask.homepage if formula_or_cask.homepage
|
||||
urls << package_or_resource.appcast.to_s if package_or_resource.appcast
|
||||
urls << package_or_resource.url.to_s if package_or_resource.url
|
||||
urls << package_or_resource.homepage if package_or_resource.homepage
|
||||
when Resource
|
||||
urls << package_or_resource.url
|
||||
else
|
||||
T.absurd(formula_or_cask)
|
||||
T.absurd(package_or_resource)
|
||||
end
|
||||
|
||||
urls.compact.uniq
|
||||
@ -561,7 +623,7 @@ module Homebrew
|
||||
homebrew_curl_root_domains.include?(url_root_domain)
|
||||
end
|
||||
|
||||
# Identifies the latest version of the formula and returns a Hash containing
|
||||
# Identifies the latest version of the formula/cask and returns a Hash containing
|
||||
# the version information. Returns nil if a latest version couldn't be found.
|
||||
# rubocop:disable Metrics/CyclomaticComplexity
|
||||
sig {
|
||||
@ -713,7 +775,6 @@ module Homebrew
|
||||
version.to_s.include?(rejection)
|
||||
end
|
||||
end
|
||||
|
||||
next if match_version_map.blank?
|
||||
|
||||
if debug
|
||||
@ -770,6 +831,195 @@ module Homebrew
|
||||
nil
|
||||
end
|
||||
# rubocop:enable Metrics/CyclomaticComplexity
|
||||
|
||||
# Identifies the latest version of a resource and returns a Hash containing the
|
||||
# version information. Returns nil if a latest version couldn't be found.
|
||||
sig {
|
||||
params(
|
||||
resource: Resource,
|
||||
json: T::Boolean,
|
||||
debug: T::Boolean,
|
||||
quiet: T::Boolean,
|
||||
verbose: T::Boolean,
|
||||
).returns(Hash)
|
||||
}
|
||||
def resource_version(
|
||||
resource,
|
||||
json: false,
|
||||
debug: false,
|
||||
quiet: false,
|
||||
verbose: false
|
||||
)
|
||||
has_livecheckable = resource.livecheckable?
|
||||
|
||||
if debug
|
||||
puts "\n\n"
|
||||
puts "Resource: #{resource.name}"
|
||||
puts "Livecheckable?: #{has_livecheckable ? "Yes" : "No"}"
|
||||
end
|
||||
|
||||
resource_version_info = {}
|
||||
|
||||
livecheck = resource.livecheck
|
||||
livecheck_url = livecheck.url
|
||||
livecheck_regex = livecheck.regex
|
||||
livecheck_strategy = livecheck.strategy
|
||||
livecheck_strategy_block = livecheck.strategy_block
|
||||
|
||||
livecheck_url_string = livecheck_url_to_string(livecheck_url, resource)
|
||||
|
||||
urls = [livecheck_url_string] if livecheck_url_string
|
||||
urls ||= checkable_urls(resource)
|
||||
|
||||
checked_urls = []
|
||||
# rubocop:disable Metrics/BlockLength
|
||||
urls.each_with_index do |original_url, i|
|
||||
# Only preprocess the URL when it's appropriate
|
||||
url = if STRATEGY_SYMBOLS_TO_SKIP_PREPROCESS_URL.include?(livecheck_strategy)
|
||||
original_url
|
||||
else
|
||||
preprocess_url(original_url)
|
||||
end
|
||||
next if checked_urls.include?(url)
|
||||
|
||||
strategies = Strategy.from_url(
|
||||
url,
|
||||
livecheck_strategy: livecheck_strategy,
|
||||
url_provided: livecheck_url.present?,
|
||||
regex_provided: livecheck_regex.present?,
|
||||
block_provided: livecheck_strategy_block.present?,
|
||||
)
|
||||
strategy = Strategy.from_symbol(livecheck_strategy) || strategies.first
|
||||
strategy_name = livecheck_strategy_names[strategy]
|
||||
|
||||
if debug
|
||||
puts
|
||||
if livecheck_url.is_a?(Symbol)
|
||||
# This assumes the URL symbol will fit within the available space
|
||||
puts "URL (#{livecheck_url}):".ljust(18, " ") + original_url
|
||||
else
|
||||
puts "URL: #{original_url}"
|
||||
end
|
||||
puts "URL (processed): #{url}" if url != original_url
|
||||
if strategies.present? && verbose
|
||||
puts "Strategies: #{strategies.map { |s| livecheck_strategy_names[s] }.join(", ")}"
|
||||
end
|
||||
puts "Strategy: #{strategy.blank? ? "None" : strategy_name}"
|
||||
puts "Regex: #{livecheck_regex.inspect}" if livecheck_regex.present?
|
||||
end
|
||||
|
||||
if livecheck_strategy.present?
|
||||
if livecheck_url.blank? && strategy.method(:find_versions).parameters.include?([:keyreq, :url])
|
||||
odebug "#{strategy_name} strategy requires a URL"
|
||||
next
|
||||
elsif livecheck_strategy != :page_match && strategies.exclude?(strategy)
|
||||
odebug "#{strategy_name} strategy does not apply to this URL"
|
||||
next
|
||||
end
|
||||
end
|
||||
puts if debug && strategy.blank?
|
||||
next if strategy.blank?
|
||||
|
||||
strategy_data = strategy.find_versions(
|
||||
url: url,
|
||||
regex: livecheck_regex,
|
||||
homebrew_curl: false,
|
||||
&livecheck_strategy_block
|
||||
)
|
||||
match_version_map = strategy_data[:matches]
|
||||
regex = strategy_data[:regex]
|
||||
messages = strategy_data[:messages]
|
||||
checked_urls << url
|
||||
|
||||
if messages.is_a?(Array) && match_version_map.blank?
|
||||
puts messages unless json
|
||||
next if i + 1 < urls.length
|
||||
|
||||
return status_hash(resource, "error", messages, verbose: verbose)
|
||||
end
|
||||
|
||||
if debug
|
||||
if strategy_data[:url].present? && strategy_data[:url] != url
|
||||
puts "URL (strategy): #{strategy_data[:url]}"
|
||||
end
|
||||
puts "URL (final): #{strategy_data[:final_url]}" if strategy_data[:final_url].present?
|
||||
if strategy_data[:regex].present? && strategy_data[:regex] != livecheck_regex
|
||||
puts "Regex (strategy): #{strategy_data[:regex].inspect}"
|
||||
end
|
||||
puts "Cached?: Yes" if strategy_data[:cached] == true
|
||||
end
|
||||
|
||||
match_version_map.delete_if do |_match, version|
|
||||
next true if version.blank?
|
||||
next false if has_livecheckable
|
||||
|
||||
UNSTABLE_VERSION_KEYWORDS.any? do |rejection|
|
||||
version.to_s.include?(rejection)
|
||||
end
|
||||
end
|
||||
next if match_version_map.blank?
|
||||
|
||||
if debug
|
||||
puts
|
||||
puts "Matched Versions:"
|
||||
|
||||
if verbose
|
||||
match_version_map.each do |match, version|
|
||||
puts "#{match} => #{version.inspect}"
|
||||
end
|
||||
else
|
||||
puts match_version_map.values.join(", ")
|
||||
end
|
||||
end
|
||||
|
||||
res_current = resource.version
|
||||
res_latest = Version.new(match_version_map.values.max_by { |v| LivecheckVersion.create(resource, v) })
|
||||
|
||||
return status_hash(resource, "error", ["Unable to get versions"], verbose: verbose) if res_latest.blank?
|
||||
|
||||
is_outdated = res_current < res_latest
|
||||
is_newer_than_upstream = res_current > res_latest
|
||||
|
||||
resource_version_info = {
|
||||
resource: resource.name,
|
||||
version: {
|
||||
current: res_current.to_s,
|
||||
latest: res_latest.to_s,
|
||||
outdated: is_outdated,
|
||||
newer_than_upstream: is_newer_than_upstream,
|
||||
},
|
||||
}
|
||||
|
||||
resource_version_info[:meta] = { livecheckable: has_livecheckable, url: {} }
|
||||
if livecheck_url.is_a?(Symbol) && livecheck_url_string
|
||||
resource_version_info[:meta][:url][:symbol] = livecheck_url
|
||||
end
|
||||
resource_version_info[:meta][:url][:original] = original_url
|
||||
resource_version_info[:meta][:url][:processed] = url if url != original_url
|
||||
if strategy_data[:url].present? && strategy_data[:url] != url
|
||||
resource_version_info[:meta][:url][:strategy] = strategy_data[:url]
|
||||
end
|
||||
resource_version_info[:meta][:url][:final] = strategy_data[:final_url] if strategy_data[:final_url]
|
||||
resource_version_info[:meta][:strategy] = strategy.present? ? strategy_name : nil
|
||||
if strategies.present?
|
||||
resource_version_info[:meta][:strategies] = strategies.map { |s| livecheck_strategy_names[s] }
|
||||
end
|
||||
resource_version_info[:meta][:regex] = regex.inspect if regex.present?
|
||||
resource_version_info[:meta][:cached] = true if strategy_data[:cached] == true
|
||||
|
||||
rescue => e
|
||||
Homebrew.failed = true
|
||||
if json
|
||||
status_hash(resource, "error", [e.to_s], verbose: verbose)
|
||||
elsif !quiet
|
||||
onoe "#{Tty.blue}#{resource.name}#{Tty.reset}: #{e}"
|
||||
$stderr.puts e.backtrace if debug && !e.is_a?(Livecheck::Error)
|
||||
nil
|
||||
end
|
||||
end
|
||||
# rubocop:enable Metrics/BlockLength
|
||||
resource_version_info
|
||||
end
|
||||
end
|
||||
# rubocop:enable Metrics/ModuleLength
|
||||
end
|
||||
|
@ -11,15 +11,17 @@ module Homebrew
|
||||
|
||||
include Comparable
|
||||
|
||||
sig { params(formula_or_cask: T.any(Formula, Cask::Cask), version: Version).returns(LivecheckVersion) }
|
||||
def self.create(formula_or_cask, version)
|
||||
versions = case formula_or_cask
|
||||
when Formula
|
||||
sig {
|
||||
params(package_or_resource: T.any(Formula, Cask::Cask, Resource), version: Version).returns(LivecheckVersion)
|
||||
}
|
||||
def self.create(package_or_resource, version)
|
||||
versions = case package_or_resource
|
||||
when Formula, Resource
|
||||
[version]
|
||||
when Cask::Cask
|
||||
version.to_s.split(/[,:]/).map { |s| Version.new(s) }
|
||||
else
|
||||
T.absurd(formula_or_cask)
|
||||
T.absurd(package_or_resource)
|
||||
end
|
||||
new(versions)
|
||||
end
|
||||
|
@ -6,7 +6,7 @@ require "livecheck/livecheck"
|
||||
module Homebrew
|
||||
module Livecheck
|
||||
# The `Livecheck::SkipConditions` module primarily contains methods that
|
||||
# check for various formula/cask conditions where a check should be skipped.
|
||||
# check for various formula/cask/resource conditions where a check should be skipped.
|
||||
#
|
||||
# @api private
|
||||
module SkipConditions
|
||||
@ -16,14 +16,14 @@ module Homebrew
|
||||
|
||||
sig {
|
||||
params(
|
||||
formula_or_cask: T.any(Formula, Cask::Cask),
|
||||
livecheckable: T::Boolean,
|
||||
full_name: T::Boolean,
|
||||
verbose: T::Boolean,
|
||||
package_or_resource: T.any(Formula, Cask::Cask, Resource),
|
||||
livecheckable: T::Boolean,
|
||||
full_name: T::Boolean,
|
||||
verbose: T::Boolean,
|
||||
).returns(Hash)
|
||||
}
|
||||
def formula_or_cask_skip(formula_or_cask, livecheckable, full_name: false, verbose: false)
|
||||
formula = formula_or_cask if formula_or_cask.is_a?(Formula)
|
||||
def package_or_resource_skip(package_or_resource, livecheckable, full_name: false, verbose: false)
|
||||
formula = package_or_resource if package_or_resource.is_a?(Formula)
|
||||
|
||||
if (stable_url = formula&.stable&.url)
|
||||
stable_is_gist = stable_url.match?(%r{https?://gist\.github(?:usercontent)?\.com/}i)
|
||||
@ -33,8 +33,8 @@ module Homebrew
|
||||
stable_from_internet_archive = stable_url.match?(%r{https?://web\.archive\.org/}i)
|
||||
end
|
||||
|
||||
skip_message = if formula_or_cask.livecheck.skip_msg.present?
|
||||
formula_or_cask.livecheck.skip_msg
|
||||
skip_message = if package_or_resource.livecheck.skip_msg.present?
|
||||
package_or_resource.livecheck.skip_msg
|
||||
elsif !livecheckable
|
||||
if stable_from_google_code_archive
|
||||
"Stable URL is from Google Code Archive"
|
||||
@ -45,10 +45,10 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
return {} if !formula_or_cask.livecheck.skip? && skip_message.blank?
|
||||
return {} if !package_or_resource.livecheck.skip? && skip_message.blank?
|
||||
|
||||
skip_messages = skip_message ? [skip_message] : nil
|
||||
Livecheck.status_hash(formula_or_cask, "skipped", skip_messages, full_name: full_name, verbose: verbose)
|
||||
Livecheck.status_hash(package_or_resource, "skipped", skip_messages, full_name: full_name, verbose: verbose)
|
||||
end
|
||||
|
||||
sig {
|
||||
@ -157,7 +157,7 @@ module Homebrew
|
||||
|
||||
# Skip conditions for formulae.
|
||||
FORMULA_CHECKS = [
|
||||
:formula_or_cask_skip,
|
||||
:package_or_resource_skip,
|
||||
:formula_head_only,
|
||||
:formula_deprecated,
|
||||
:formula_disabled,
|
||||
@ -166,76 +166,85 @@ module Homebrew
|
||||
|
||||
# Skip conditions for casks.
|
||||
CASK_CHECKS = [
|
||||
:formula_or_cask_skip,
|
||||
:package_or_resource_skip,
|
||||
:cask_discontinued,
|
||||
:cask_version_latest,
|
||||
:cask_url_unversioned,
|
||||
].freeze
|
||||
|
||||
# If a formula/cask should be skipped, we return a hash from
|
||||
# Skip conditions for resources.
|
||||
RESOURCE_CHECKS = [
|
||||
:package_or_resource_skip,
|
||||
].freeze
|
||||
|
||||
# If a formula/cask/resource should be skipped, we return a hash from
|
||||
# `Livecheck#status_hash`, which contains a `status` type and sometimes
|
||||
# error `messages`.
|
||||
sig {
|
||||
params(
|
||||
formula_or_cask: T.any(Formula, Cask::Cask),
|
||||
full_name: T::Boolean,
|
||||
verbose: T::Boolean,
|
||||
package_or_resource: T.any(Formula, Cask::Cask, Resource),
|
||||
full_name: T::Boolean,
|
||||
verbose: T::Boolean,
|
||||
).returns(Hash)
|
||||
}
|
||||
def skip_information(formula_or_cask, full_name: false, verbose: false)
|
||||
livecheckable = formula_or_cask.livecheckable?
|
||||
def skip_information(package_or_resource, full_name: false, verbose: false)
|
||||
livecheckable = package_or_resource.livecheckable?
|
||||
|
||||
checks = case formula_or_cask
|
||||
checks = case package_or_resource
|
||||
when Formula
|
||||
FORMULA_CHECKS
|
||||
when Cask::Cask
|
||||
CASK_CHECKS
|
||||
when Resource
|
||||
RESOURCE_CHECKS
|
||||
end
|
||||
return {} unless checks
|
||||
|
||||
checks.each do |method_name|
|
||||
skip_hash = send(method_name, formula_or_cask, livecheckable, full_name: full_name, verbose: verbose)
|
||||
skip_hash = send(method_name, package_or_resource, livecheckable, full_name: full_name, verbose: verbose)
|
||||
return skip_hash if skip_hash.present?
|
||||
end
|
||||
|
||||
{}
|
||||
end
|
||||
|
||||
# Skip conditions for formulae/casks referenced in a `livecheck` block
|
||||
# Skip conditions for formulae/casks/resources referenced in a `livecheck` block
|
||||
# are treated differently than normal. We only respect certain skip
|
||||
# conditions (returning the related hash) and others are treated as
|
||||
# errors.
|
||||
sig {
|
||||
params(
|
||||
livecheck_formula_or_cask: T.any(Formula, Cask::Cask),
|
||||
original_formula_or_cask_name: String,
|
||||
full_name: T::Boolean,
|
||||
verbose: T::Boolean,
|
||||
livecheck_package_or_resource: T.any(Formula, Cask::Cask, Resource),
|
||||
original_package_or_resource_name: String,
|
||||
full_name: T::Boolean,
|
||||
verbose: T::Boolean,
|
||||
).returns(T.nilable(Hash))
|
||||
}
|
||||
def referenced_skip_information(
|
||||
livecheck_formula_or_cask,
|
||||
original_formula_or_cask_name,
|
||||
livecheck_package_or_resource,
|
||||
original_package_or_resource_name,
|
||||
full_name: false,
|
||||
verbose: false
|
||||
)
|
||||
skip_info = SkipConditions.skip_information(
|
||||
livecheck_formula_or_cask,
|
||||
livecheck_package_or_resource,
|
||||
full_name: full_name,
|
||||
verbose: verbose,
|
||||
)
|
||||
return if skip_info.blank?
|
||||
|
||||
referenced_name = Livecheck.formula_or_cask_name(livecheck_formula_or_cask, full_name: full_name)
|
||||
referenced_type = case livecheck_formula_or_cask
|
||||
referenced_name = Livecheck.package_or_resource_name(livecheck_package_or_resource, full_name: full_name)
|
||||
referenced_type = case livecheck_package_or_resource
|
||||
when Formula
|
||||
:formula
|
||||
when Cask::Cask
|
||||
:cask
|
||||
when Resource
|
||||
:resource
|
||||
end
|
||||
|
||||
if skip_info[:status] != "error" &&
|
||||
!(skip_info[:status] == "skipped" && livecheck_formula_or_cask.livecheck.skip?)
|
||||
!(skip_info[:status] == "skipped" && livecheck_package_or_resource.livecheck.skip?)
|
||||
error_msg_end = if skip_info[:status] == "skipped"
|
||||
"automatically skipped"
|
||||
else
|
||||
@ -245,7 +254,7 @@ module Homebrew
|
||||
raise "Referenced #{referenced_type} (#{referenced_name}) is #{error_msg_end}"
|
||||
end
|
||||
|
||||
skip_info[referenced_type] = original_formula_or_cask_name
|
||||
skip_info[referenced_type] = original_package_or_resource_name
|
||||
skip_info
|
||||
end
|
||||
|
||||
@ -258,6 +267,8 @@ module Homebrew
|
||||
skip_hash[:formula]
|
||||
elsif skip_hash[:cask].is_a?(String)
|
||||
skip_hash[:cask]
|
||||
elsif skip_hash[:resource].is_a?(String)
|
||||
" #{skip_hash[:resource]}"
|
||||
end
|
||||
return unless name
|
||||
|
||||
|
@ -11,6 +11,7 @@ describe Homebrew::Livecheck do
|
||||
let(:homepage_url) { "https://brew.sh" }
|
||||
let(:livecheck_url) { "https://formulae.brew.sh/api/formula/ruby.json" }
|
||||
let(:stable_url) { "https://brew.sh/test-0.0.1.tgz" }
|
||||
let(:resource_url) { "https://brew.sh/foo-1.0.tar.gz" }
|
||||
|
||||
let(:f) do
|
||||
formula("test") do
|
||||
@ -23,9 +24,21 @@ describe Homebrew::Livecheck do
|
||||
url "https://formulae.brew.sh/api/formula/ruby.json"
|
||||
regex(/"stable":"(\d+(?:\.\d+)+)"/i)
|
||||
end
|
||||
|
||||
resource "foo" do
|
||||
url "https://brew.sh/foo-1.0.tar.gz"
|
||||
sha256 "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
||||
|
||||
livecheck do
|
||||
url "https://brew.sh/test/releases"
|
||||
regex(/foo[._-]v?(\d+(?:\.\d+)+)\.t/i)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
let(:r) { f.resources.first }
|
||||
|
||||
let(:c) do
|
||||
Cask::CaskLoader.load(+<<-RUBY)
|
||||
cask "test" do
|
||||
@ -44,15 +57,6 @@ describe Homebrew::Livecheck do
|
||||
RUBY
|
||||
end
|
||||
|
||||
let(:f_duplicate_urls) do
|
||||
formula("test_duplicate_urls") do
|
||||
desc "Test formula with a duplicate URL"
|
||||
homepage "https://github.com/Homebrew/brew.git"
|
||||
url "https://brew.sh/test-0.0.1.tgz"
|
||||
head "https://github.com/Homebrew/brew.git"
|
||||
end
|
||||
end
|
||||
|
||||
describe "::resolve_livecheck_reference" do
|
||||
context "when a formula/cask has a livecheck block without formula/cask methods" do
|
||||
it "returns [nil, []]" do
|
||||
@ -83,7 +87,7 @@ describe Homebrew::Livecheck do
|
||||
end
|
||||
|
||||
describe "::status_hash" do
|
||||
it "returns a hash containing the livecheck status" do
|
||||
it "returns a hash containing the livecheck status for a formula" do
|
||||
expect(livecheck.status_hash(f, "error", ["Unable to get versions"]))
|
||||
.to eq({
|
||||
formula: "test",
|
||||
@ -94,6 +98,18 @@ describe Homebrew::Livecheck do
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
it "returns a hash containing the livecheck status for a resource" do
|
||||
expect(livecheck.status_hash(r, "error", ["Unable to get versions"]))
|
||||
.to eq({
|
||||
resource: "foo",
|
||||
status: "error",
|
||||
messages: ["Unable to get versions"],
|
||||
meta: {
|
||||
livecheckable: true,
|
||||
},
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
describe "::livecheck_url_to_string" do
|
||||
@ -101,15 +117,28 @@ describe Homebrew::Livecheck do
|
||||
homepage_url_s = homepage_url
|
||||
stable_url_s = stable_url
|
||||
head_url_s = head_url
|
||||
resource_url_s = resource_url
|
||||
|
||||
formula("test_livecheck_url") do
|
||||
desc "Test Livecheck URL formula"
|
||||
homepage homepage_url_s
|
||||
url stable_url_s
|
||||
head head_url_s
|
||||
|
||||
resource "foo" do
|
||||
url resource_url_s
|
||||
sha256 "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
||||
|
||||
livecheck do
|
||||
url "https://brew.sh/test/releases"
|
||||
regex(/foo[._-]v?(\d+(?:\.\d+)+)\.t/i)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
let(:r_livecheck_url) { f_livecheck_url.resources.first }
|
||||
|
||||
let(:c_livecheck_url) do
|
||||
Cask::CaskLoader.load(+<<-RUBY)
|
||||
cask "test_livecheck_url" do
|
||||
@ -123,30 +152,48 @@ describe Homebrew::Livecheck do
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "returns a URL string when given a livecheck_url string" do
|
||||
it "returns a URL string when given a livecheck_url string for a formula" do
|
||||
expect(livecheck.livecheck_url_to_string(livecheck_url, f_livecheck_url)).to eq(livecheck_url)
|
||||
end
|
||||
|
||||
it "returns a URL string when given a livecheck_url string for a resource" do
|
||||
expect(livecheck.livecheck_url_to_string(livecheck_url, r_livecheck_url)).to eq(livecheck_url)
|
||||
end
|
||||
|
||||
it "returns a URL symbol when given a valid livecheck_url symbol" do
|
||||
expect(livecheck.livecheck_url_to_string(:head, f_livecheck_url)).to eq(head_url)
|
||||
expect(livecheck.livecheck_url_to_string(:homepage, f_livecheck_url)).to eq(homepage_url)
|
||||
expect(livecheck.livecheck_url_to_string(:homepage, c_livecheck_url)).to eq(homepage_url)
|
||||
expect(livecheck.livecheck_url_to_string(:stable, f_livecheck_url)).to eq(stable_url)
|
||||
expect(livecheck.livecheck_url_to_string(:url, c_livecheck_url)).to eq(cask_url)
|
||||
expect(livecheck.livecheck_url_to_string(:url, r_livecheck_url)).to eq(resource_url)
|
||||
end
|
||||
|
||||
it "returns nil when not given a string or valid symbol" do
|
||||
expect(livecheck.livecheck_url_to_string(nil, f_livecheck_url)).to be_nil
|
||||
expect(livecheck.livecheck_url_to_string(nil, c_livecheck_url)).to be_nil
|
||||
expect(livecheck.livecheck_url_to_string(nil, r_livecheck_url)).to be_nil
|
||||
expect(livecheck.livecheck_url_to_string(:invalid_symbol, f_livecheck_url)).to be_nil
|
||||
expect(livecheck.livecheck_url_to_string(:invalid_symbol, c_livecheck_url)).to be_nil
|
||||
expect(livecheck.livecheck_url_to_string(:invalid_symbol, r_livecheck_url)).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "::checkable_urls" do
|
||||
let(:resource_url) { "https://brew.sh/foo-1.0.tar.gz" }
|
||||
let(:f_duplicate_urls) do
|
||||
formula("test_duplicate_urls") do
|
||||
desc "Test formula with a duplicate URL"
|
||||
homepage "https://github.com/Homebrew/brew.git"
|
||||
url "https://brew.sh/test-0.0.1.tgz"
|
||||
head "https://github.com/Homebrew/brew.git"
|
||||
end
|
||||
end
|
||||
|
||||
it "returns the list of URLs to check" do
|
||||
expect(livecheck.checkable_urls(f)).to eq([stable_url, head_url, homepage_url])
|
||||
expect(livecheck.checkable_urls(c)).to eq([cask_url, homepage_url])
|
||||
expect(livecheck.checkable_urls(r)).to eq([resource_url])
|
||||
expect(livecheck.checkable_urls(f_duplicate_urls)).to eq([stable_url, head_url])
|
||||
end
|
||||
end
|
||||
|
@ -6,6 +6,7 @@ require "livecheck/livecheck_version"
|
||||
describe Homebrew::Livecheck::LivecheckVersion do
|
||||
let(:formula) { instance_double(Formula) }
|
||||
let(:cask) { instance_double(Cask::Cask) }
|
||||
let(:resource) { instance_double(Resource) }
|
||||
|
||||
before do
|
||||
# Case statements use #=== for case equality purposes
|
||||
@ -13,6 +14,8 @@ describe Homebrew::Livecheck::LivecheckVersion do
|
||||
allow(Formula).to receive(:===).with(formula).and_return(true)
|
||||
allow(Cask::Cask).to receive(:===).and_call_original
|
||||
allow(Cask::Cask).to receive(:===).with(cask).and_return(true)
|
||||
allow(Resource).to receive(:===).and_call_original
|
||||
allow(Resource).to receive(:===).with(resource).and_return(true)
|
||||
end
|
||||
|
||||
specify "::create" do
|
||||
@ -28,5 +31,11 @@ describe Homebrew::Livecheck::LivecheckVersion do
|
||||
.to eq ["1.0", "100", "1426778671"]
|
||||
expect(described_class.create(cask, Version.new("0.17.0,20210111183933,226")).versions)
|
||||
.to eq ["0.17.0", "20210111183933", "226"]
|
||||
|
||||
expect(described_class.create(resource, Version.new("1.1.6")).versions).to eq ["1.1.6"]
|
||||
expect(described_class.create(resource, Version.new("2.19.0,1.8.0")).versions).to eq ["2.19.0,1.8.0"]
|
||||
expect(described_class.create(resource, Version.new("1.0,100:1426778671")).versions).to eq ["1.0,100:1426778671"]
|
||||
expect(described_class.create(resource, Version.new("0.17.0,20210111183933,226")).versions)
|
||||
.to eq ["0.17.0,20210111183933,226"]
|
||||
end
|
||||
end
|
||||
|
@ -94,22 +94,6 @@ module Homebrew
|
||||
.map { |k| Keg.new(k.resolved_path) }
|
||||
end
|
||||
|
||||
def print_dry_run_dependencies(formula, fi_deps)
|
||||
return if fi_deps.empty?
|
||||
|
||||
plural = "dependency".pluralize(fi_deps.count)
|
||||
ohai "Would upgrade #{fi_deps.count} #{plural} for #{formula.full_specified_name}:"
|
||||
formulae_upgrades = fi_deps.map(&:first).map(&:to_formula).map do |f|
|
||||
name = f.full_specified_name
|
||||
if f.optlinked?
|
||||
"#{name} #{Keg.new(f.opt_prefix).version} -> #{f.pkg_version}"
|
||||
else
|
||||
"#{name} #{f.pkg_version}"
|
||||
end
|
||||
end
|
||||
puts formulae_upgrades.join(", ")
|
||||
end
|
||||
|
||||
def print_upgrade_message(formula, fi_options)
|
||||
version_upgrade = if formula.optlinked?
|
||||
"#{Keg.new(formula.opt_prefix).version} -> #{formula.pkg_version}"
|
||||
@ -178,7 +162,14 @@ module Homebrew
|
||||
formula = formula_installer.formula
|
||||
|
||||
if dry_run
|
||||
print_dry_run_dependencies(formula, formula_installer.compute_dependencies)
|
||||
Install.print_dry_run_dependencies(formula, formula_installer.compute_dependencies) do |f|
|
||||
name = f.full_specified_name
|
||||
if f.optlinked?
|
||||
"#{name} #{Keg.new(f.opt_prefix).version} -> #{f.pkg_version}"
|
||||
else
|
||||
"#{name} #{f.pkg_version}"
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -13,8 +13,8 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/public_suffix-5.0.0/l
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/addressable-2.8.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ast-2.4.2/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/bindata-2.4.11/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/universal-darwin-21/2.6.0/msgpack-1.5.6"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/msgpack-1.5.6/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/universal-darwin-21/2.6.0/msgpack-1.6.0"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/msgpack-1.6.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/universal-darwin-21/2.6.0/bootsnap-1.13.0"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/bootsnap-1.13.0/lib"
|
||||
$:.unshift "#{path}/"
|
||||
@ -82,7 +82,7 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-its-1.3.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-retry-0.6.2/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-sorbet-1.9.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-wait-0.0.9/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec_junit_formatter-0.5.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec_junit_formatter-0.6.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-ast-1.21.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-progressbar-1.11.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/unicode-display_width-2.3.0/lib"
|
||||
|
@ -1112,6 +1112,7 @@ _brew_instal() {
|
||||
--debug-symbols
|
||||
--dictionarydir
|
||||
--display-times
|
||||
--dry-run
|
||||
--fetch-HEAD
|
||||
--fontdir
|
||||
--force
|
||||
@ -1171,6 +1172,7 @@ _brew_install() {
|
||||
--debug-symbols
|
||||
--dictionarydir
|
||||
--display-times
|
||||
--dry-run
|
||||
--fetch-HEAD
|
||||
--fontdir
|
||||
--force
|
||||
@ -1261,6 +1263,7 @@ _brew_lc() {
|
||||
--json
|
||||
--newer-only
|
||||
--quiet
|
||||
--resources
|
||||
--tap
|
||||
--verbose
|
||||
"
|
||||
@ -1375,6 +1378,7 @@ _brew_livecheck() {
|
||||
--json
|
||||
--newer-only
|
||||
--quiet
|
||||
--resources
|
||||
--tap
|
||||
--verbose
|
||||
"
|
||||
|
@ -798,6 +798,7 @@ __fish_brew_complete_arg 'instal' -l debug -d 'If brewing fails, open an interac
|
||||
__fish_brew_complete_arg 'instal' -l debug-symbols -d 'Generate debug symbols on build. Source will be retained in a cache directory. '
|
||||
__fish_brew_complete_arg 'instal' -l dictionarydir -d 'Target location for Dictionaries (default: `~/Library/Dictionaries`)'
|
||||
__fish_brew_complete_arg 'instal' -l display-times -d 'Print install times for each package at the end of the run'
|
||||
__fish_brew_complete_arg 'instal' -l dry-run -d 'Show what would be installed, but do not actually install anything'
|
||||
__fish_brew_complete_arg 'instal' -l fetch-HEAD -d 'Fetch the upstream repository to detect if the HEAD installation of the formula is outdated. Otherwise, the repository\'s HEAD will only be checked for updates when a new stable or development version has been released'
|
||||
__fish_brew_complete_arg 'instal' -l fontdir -d 'Target location for Fonts (default: `~/Library/Fonts`)'
|
||||
__fish_brew_complete_arg 'instal' -l force -d 'Install formulae without checking for previously installed keg-only or non-migrated versions. When installing casks, overwrite existing files (binaries and symlinks are excluded, unless originally from the same cask)'
|
||||
@ -848,6 +849,7 @@ __fish_brew_complete_arg 'install' -l debug -d 'If brewing fails, open an intera
|
||||
__fish_brew_complete_arg 'install' -l debug-symbols -d 'Generate debug symbols on build. Source will be retained in a cache directory. '
|
||||
__fish_brew_complete_arg 'install' -l dictionarydir -d 'Target location for Dictionaries (default: `~/Library/Dictionaries`)'
|
||||
__fish_brew_complete_arg 'install' -l display-times -d 'Print install times for each package at the end of the run'
|
||||
__fish_brew_complete_arg 'install' -l dry-run -d 'Show what would be installed, but do not actually install anything'
|
||||
__fish_brew_complete_arg 'install' -l fetch-HEAD -d 'Fetch the upstream repository to detect if the HEAD installation of the formula is outdated. Otherwise, the repository\'s HEAD will only be checked for updates when a new stable or development version has been released'
|
||||
__fish_brew_complete_arg 'install' -l fontdir -d 'Target location for Fonts (default: `~/Library/Fonts`)'
|
||||
__fish_brew_complete_arg 'install' -l force -d 'Install formulae without checking for previously installed keg-only or non-migrated versions. When installing casks, overwrite existing files (binaries and symlinks are excluded, unless originally from the same cask)'
|
||||
@ -911,6 +913,7 @@ __fish_brew_complete_arg 'lc' -l installed -d 'Check formulae and casks that are
|
||||
__fish_brew_complete_arg 'lc' -l json -d 'Output information in JSON format'
|
||||
__fish_brew_complete_arg 'lc' -l newer-only -d 'Show the latest version only if it\'s newer than the formula/cask'
|
||||
__fish_brew_complete_arg 'lc' -l quiet -d 'Suppress warnings, don\'t print a progress bar for JSON output'
|
||||
__fish_brew_complete_arg 'lc' -l resources -d 'Also check resources for formulae'
|
||||
__fish_brew_complete_arg 'lc' -l tap -d 'Check formulae and casks within the given tap, specified as user`/`repo'
|
||||
__fish_brew_complete_arg 'lc' -l verbose -d 'Make some output more verbose'
|
||||
__fish_brew_complete_arg 'lc; and not __fish_seen_argument -l cask -l casks' -a '(__fish_brew_suggest_formulae_all)'
|
||||
@ -980,6 +983,7 @@ __fish_brew_complete_arg 'livecheck' -l installed -d 'Check formulae and casks t
|
||||
__fish_brew_complete_arg 'livecheck' -l json -d 'Output information in JSON format'
|
||||
__fish_brew_complete_arg 'livecheck' -l newer-only -d 'Show the latest version only if it\'s newer than the formula/cask'
|
||||
__fish_brew_complete_arg 'livecheck' -l quiet -d 'Suppress warnings, don\'t print a progress bar for JSON output'
|
||||
__fish_brew_complete_arg 'livecheck' -l resources -d 'Also check resources for formulae'
|
||||
__fish_brew_complete_arg 'livecheck' -l tap -d 'Check formulae and casks within the given tap, specified as user`/`repo'
|
||||
__fish_brew_complete_arg 'livecheck' -l verbose -d 'Make some output more verbose'
|
||||
__fish_brew_complete_arg 'livecheck; and not __fish_seen_argument -l cask -l casks' -a '(__fish_brew_suggest_formulae_all)'
|
||||
|
@ -983,6 +983,7 @@ _brew_instal() {
|
||||
'(--cask)--debug-symbols[Generate debug symbols on build. Source will be retained in a cache directory. ]' \
|
||||
'(--formula)--dictionarydir[Target location for Dictionaries (default: `~/Library/Dictionaries`)]' \
|
||||
'(--cask)--display-times[Print install times for each package at the end of the run]' \
|
||||
'--dry-run[Show what would be installed, but do not actually install anything]' \
|
||||
'(--cask)--fetch-HEAD[Fetch the upstream repository to detect if the HEAD installation of the formula is outdated. Otherwise, the repository'\''s HEAD will only be checked for updates when a new stable or development version has been released]' \
|
||||
'(--formula)--fontdir[Target location for Fonts (default: `~/Library/Fonts`)]' \
|
||||
'--force[Install formulae without checking for previously installed keg-only or non-migrated versions. When installing casks, overwrite existing files (binaries and symlinks are excluded, unless originally from the same cask)]' \
|
||||
@ -1037,6 +1038,7 @@ _brew_install() {
|
||||
'(--cask)--debug-symbols[Generate debug symbols on build. Source will be retained in a cache directory. ]' \
|
||||
'(--formula)--dictionarydir[Target location for Dictionaries (default: `~/Library/Dictionaries`)]' \
|
||||
'(--cask)--display-times[Print install times for each package at the end of the run]' \
|
||||
'--dry-run[Show what would be installed, but do not actually install anything]' \
|
||||
'(--cask)--fetch-HEAD[Fetch the upstream repository to detect if the HEAD installation of the formula is outdated. Otherwise, the repository'\''s HEAD will only be checked for updates when a new stable or development version has been released]' \
|
||||
'(--formula)--fontdir[Target location for Fonts (default: `~/Library/Fonts`)]' \
|
||||
'--force[Install formulae without checking for previously installed keg-only or non-migrated versions. When installing casks, overwrite existing files (binaries and symlinks are excluded, unless originally from the same cask)]' \
|
||||
@ -1107,6 +1109,7 @@ _brew_lc() {
|
||||
'(--debug)--json[Output information in JSON format]' \
|
||||
'--newer-only[Show the latest version only if it'\''s newer than the formula/cask]' \
|
||||
'--quiet[Suppress warnings, don'\''t print a progress bar for JSON output]' \
|
||||
'--resources[Also check resources for formulae]' \
|
||||
'(--eval-all --installed)--tap[Check formulae and casks within the given tap, specified as user`/`repo]' \
|
||||
'--verbose[Make some output more verbose]' \
|
||||
- formula \
|
||||
@ -1192,6 +1195,7 @@ _brew_livecheck() {
|
||||
'(--debug)--json[Output information in JSON format]' \
|
||||
'--newer-only[Show the latest version only if it'\''s newer than the formula/cask]' \
|
||||
'--quiet[Suppress warnings, don'\''t print a progress bar for JSON output]' \
|
||||
'--resources[Also check resources for formulae]' \
|
||||
'(--eval-all --installed)--tap[Check formulae and casks within the given tap, specified as user`/`repo]' \
|
||||
'--verbose[Make some output more verbose]' \
|
||||
- formula \
|
||||
|
@ -6,14 +6,14 @@ The `brew livecheck` command finds the newest version of a formula or cask's sof
|
||||
|
||||
When livecheck isn't given instructions for how to check for upstream versions, it does the following by default:
|
||||
|
||||
1. For formulae: Collect the `head`, `stable`, and `homepage` URLs, in that order. For casks: Collect the `url` and `homepage` URLs, in that order.
|
||||
1. For formulae: Collect the `stable`, `head`, and `homepage` URLs, in that order (resources simply use their `url`). For casks: Collect the `url` and `homepage` URLs, in that order.
|
||||
1. Determine if any strategies apply to the first URL. If not, try the next URL.
|
||||
1. If a strategy can be applied, use it to check for new versions.
|
||||
1. Return the newest version (or an error if versions could not be found at any available URLs).
|
||||
|
||||
It's sometimes necessary to override this default behavior to create a working check. If a source doesn't provide the newest version, we need to check a different one. If livecheck doesn't correctly match version text, we need to provide an appropriate regex or `strategy` block.
|
||||
|
||||
This can be accomplished by adding a `livecheck` block to the formula/cask. For more information on the available methods, please refer to the [`Livecheck` class documentation](https://rubydoc.brew.sh/Livecheck.html).
|
||||
This can be accomplished by adding a `livecheck` block to the formula/cask/resource. For more information on the available methods, please refer to the [`Livecheck` class documentation](https://rubydoc.brew.sh/Livecheck.html).
|
||||
|
||||
## Creating a check
|
||||
|
||||
|
@ -329,6 +329,8 @@ is already installed but outdated.
|
||||
Install formulae without checking for previously installed keg-only or non-migrated versions. When installing casks, overwrite existing files (binaries and symlinks are excluded, unless originally from the same cask).
|
||||
* `-v`, `--verbose`:
|
||||
Print the verification and postinstall steps.
|
||||
* `-n`, `--dry-run`:
|
||||
Show what would be installed, but do not actually install anything.
|
||||
* `--formula`:
|
||||
Treat all named arguments as formulae.
|
||||
* `--ignore-dependencies`:
|
||||
@ -1267,6 +1269,8 @@ casks to check is taken from `HOMEBREW_LIVECHECK_WATCHLIST` or
|
||||
Show the latest version only if it's newer than the formula/cask.
|
||||
* `--json`:
|
||||
Output information in JSON format.
|
||||
* `-r`, `--resources`:
|
||||
Also check resources for formulae.
|
||||
* `-q`, `--quiet`:
|
||||
Suppress warnings, don't print a progress bar for JSON output.
|
||||
* `--formula`:
|
||||
|
@ -432,6 +432,10 @@ Install formulae without checking for previously installed keg\-only or non\-mig
|
||||
Print the verification and postinstall steps\.
|
||||
.
|
||||
.TP
|
||||
\fB\-n\fR, \fB\-\-dry\-run\fR
|
||||
Show what would be installed, but do not actually install anything\.
|
||||
.
|
||||
.TP
|
||||
\fB\-\-formula\fR
|
||||
Treat all named arguments as formulae\.
|
||||
.
|
||||
@ -1810,6 +1814,10 @@ Show the latest version only if it\'s newer than the formula/cask\.
|
||||
Output information in JSON format\.
|
||||
.
|
||||
.TP
|
||||
\fB\-r\fR, \fB\-\-resources\fR
|
||||
Also check resources for formulae\.
|
||||
.
|
||||
.TP
|
||||
\fB\-q\fR, \fB\-\-quiet\fR
|
||||
Suppress warnings, don\'t print a progress bar for JSON output\.
|
||||
.
|
||||
|
Loading…
x
Reference in New Issue
Block a user