Merge pull request #7927 from MLH-Fellowship/integrate-cask

Allow references to casks when running upgrade and outdated
This commit is contained in:
Mike McQuaid 2020-07-27 15:11:32 +01:00 committed by GitHub
commit 2ff56c9e71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 198 additions and 65 deletions

View File

@ -3,6 +3,8 @@
require "formula" require "formula"
require "keg" require "keg"
require "cli/parser" require "cli/parser"
require "cask/cmd"
require "cask/caskroom"
module Homebrew module Homebrew
module_function module_function
@ -20,94 +22,183 @@ module Homebrew
switch :verbose, switch :verbose,
description: "Include detailed version information." description: "Include detailed version information."
flag "--json", flag "--json",
description: "Print output in JSON format. Currently the default and only accepted "\ description: "Print output in JSON format. There are two versions: v1 and v2. " \
"value for <version> is `v1`. See the docs for examples of using the JSON "\ "v1 is deprecated and is currently the default if no version is specified. " \
"output: <https://docs.brew.sh/Querying-Brew>" "v2 prints outdated formulae and casks. "
switch "--fetch-HEAD", switch "--fetch-HEAD",
description: "Fetch the upstream repository to detect if the HEAD installation of the "\ description: "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 "\ "formula is outdated. Otherwise, the repository's HEAD will only be checked for "\
"updates when a new stable or development version has been released." "updates when a new stable or development version has been released."
switch "--greedy",
description: "Print outdated casks with `auto_updates` or `version :latest`."
switch "--formula",
description: "Treat all arguments as formulae."
switch "--cask",
description: "Treat all arguments as casks."
switch :debug switch :debug
conflicts "--quiet", "--verbose", "--json" conflicts "--quiet", "--verbose", "--json"
conflicts "--formula", "--cask"
end end
end end
def outdated def outdated
outdated_args.parse outdated_args.parse
formulae = if args.resolved_formulae.blank? case json_version
Formula.installed when :v1, :default
else # TODO: enable for next major/minor release
args.resolved_formulae # odeprecated "brew outdated --json#{json_version == :v1 ? "=v1" : ""}", "brew outdated --json=v2"
end
if args.json outdated = if args.formula? || !args.cask?
raise UsageError, "invalid JSON version: #{args.json}" unless ["v1", true].include? args.json outdated_formulae
else
outdated_casks
end
puts JSON.generate(json_info(outdated))
when :v2
formulae, casks = if args.formula?
[outdated_formulae, []]
elsif args.cask?
[[], outdated_casks]
else
outdated_formulae_casks
end
json = {
"formulae" => json_info(formulae),
"casks" => json_info(casks),
}
puts JSON.generate(json)
outdated = formulae + casks
outdated = print_outdated_json(formulae)
else else
outdated = print_outdated(formulae) outdated = if args.formula?
outdated_formulae
elsif args.cask?
outdated_casks
else
outdated_formulae_casks.flatten
end
print_outdated(outdated)
end end
Homebrew.failed = args.resolved_formulae.present? && !outdated.empty?
Homebrew.failed = args.named.present? && outdated.present?
end end
def print_outdated(formulae) def print_outdated(formulae_or_casks)
verbose = ($stdout.tty? || args.verbose?) && !args.quiet? formulae_or_casks.each do |formula_or_cask|
fetch_head = args.fetch_HEAD? if formula_or_cask.is_a?(Formula)
f = formula_or_cask
outdated_formulae = formulae.select { |f| f.outdated?(fetch_head: fetch_head) } if verbose?
.sort outdated_kegs = f.outdated_kegs(fetch_head: args.fetch_HEAD?)
outdated_formulae.each do |f| current_version = if f.alias_changed?
if verbose latest = f.latest_formula
outdated_kegs = f.outdated_kegs(fetch_head: fetch_head) "#{latest.name} (#{latest.pkg_version})"
elsif f.head? && outdated_kegs.any? { |k| k.version.to_s == f.pkg_version.to_s }
# There is a newer HEAD but the version number has not changed.
"latest HEAD"
else
f.pkg_version.to_s
end
current_version = if f.alias_changed? outdated_versions = outdated_kegs.group_by { |keg| Formulary.from_keg(keg).full_name }
latest = f.latest_formula .sort_by { |full_name, _kegs| full_name }
"#{latest.name} (#{latest.pkg_version})" .map do |full_name, kegs|
elsif f.head? && outdated_kegs.any? { |k| k.version.to_s == f.pkg_version.to_s } "#{full_name} (#{kegs.map(&:version).join(", ")})"
# There is a newer HEAD but the version number has not changed. end.join(", ")
"latest HEAD"
pinned_version = " [pinned at #{f.pinned_version}]" if f.pinned?
puts "#{outdated_versions} < #{current_version}#{pinned_version}"
else
puts f.full_installed_specified_name
end
else
c = formula_or_cask
puts c.outdated_info(args.greedy?, verbose?, false)
end
end
end
def json_info(formulae_or_casks)
formulae_or_casks.map do |formula_or_cask|
if formula_or_cask.is_a?(Formula)
f = formula_or_cask
outdated_versions = f.outdated_kegs(fetch_head: args.fetch_HEAD?).map(&:version)
current_version = if f.head? && outdated_versions.any? { |v| v.to_s == f.pkg_version.to_s }
"HEAD"
else else
f.pkg_version.to_s f.pkg_version.to_s
end end
outdated_versions = outdated_kegs { name: f.full_name,
.group_by { |keg| Formulary.from_keg(keg).full_name } installed_versions: outdated_versions.map(&:to_s),
.sort_by { |full_name, _kegs| full_name } current_version: current_version,
.map do |full_name, kegs| pinned: f.pinned?,
"#{full_name} (#{kegs.map(&:version).join(", ")})" pinned_version: f.pinned_version }
end.join(", ")
pinned_version = " [pinned at #{f.pinned_version}]" if f.pinned?
puts "#{outdated_versions} < #{current_version}#{pinned_version}"
else else
puts f.full_installed_specified_name c = formula_or_cask
c.outdated_info(args.greedy?, verbose?, true)
end end
end end
end end
def print_outdated_json(formulae) def verbose?
json = [] ($stdout.tty? || args.verbose?) && !args.quiet?
fetch_head = args.fetch_HEAD? end
outdated_formulae = formulae.select { |f| f.outdated?(fetch_head: fetch_head) }
outdated = outdated_formulae.each do |f| def json_version
outdated_versions = f.outdated_kegs(fetch_head: fetch_head).map(&:version) version_hash = {
current_version = if f.head? && outdated_versions.any? { |v| v.to_s == f.pkg_version.to_s } nil => nil,
"HEAD" true => :default,
else "v1" => :v1,
f.pkg_version.to_s "v2" => :v2,
end }
json << { name: f.full_name, raise UsageError, "invalid JSON version: #{args.json}" unless version_hash.include? args.json
installed_versions: outdated_versions.map(&:to_s),
current_version: current_version, version_hash[args.json]
pinned: f.pinned?, end
pinned_version: f.pinned_version }
def outdated_formulae
select_outdated((args.resolved_formulae.presence || Formula.installed)).sort
end
def outdated_casks
if args.named.present?
select_outdated(args.named.uniq.map(&Cask::CaskLoader.method(:load)))
else
select_outdated(Cask::Caskroom.casks)
end end
puts JSON.generate(json) end
outdated def outdated_formulae_casks
formulae, casks = args.resolved_formulae_casks
if formulae.blank? && casks.blank?
formulae = Formula.installed
casks = Cask::Caskroom.casks
end
[select_outdated(formulae), select_outdated(casks)]
end
def select_outdated(formulae_or_casks)
formulae_or_casks.select do |formula_or_cask|
if formula_or_cask.is_a?(Formula)
formula_or_cask.outdated?(fetch_head: args.fetch_HEAD?)
else
formula_or_cask.outdated?(args.greedy?)
end
end
end end
end end

View File

@ -4,6 +4,9 @@ require "cli/parser"
require "formula_installer" require "formula_installer"
require "install" require "install"
require "upgrade" require "upgrade"
require "cask/cmd"
require "cask/utils"
require "cask/macos"
module Homebrew module Homebrew
module_function module_function
@ -50,6 +53,8 @@ module Homebrew
description: "Print install times for each formula at the end of the run." description: "Print install times for each formula at the end of the run."
switch "-n", "--dry-run", switch "-n", "--dry-run",
description: "Show what would be upgraded, but do not actually upgrade anything." description: "Show what would be upgraded, but do not actually upgrade anything."
switch "--greedy",
description: "Upgrade casks with `auto_updates` or `version :latest`"
conflicts "--build-from-source", "--force-bottle" conflicts "--build-from-source", "--force-bottle"
formula_options formula_options
end end
@ -58,22 +63,27 @@ module Homebrew
def upgrade def upgrade
args = upgrade_args.parse args = upgrade_args.parse
formulae, casks = args.resolved_formulae_casks
upgrade_outdated_formulae(formulae)
upgrade_outdated_casks(casks)
end
def upgrade_outdated_formulae(formulae)
FormulaInstaller.prevent_build_flags unless DevelopmentTools.installed? FormulaInstaller.prevent_build_flags unless DevelopmentTools.installed?
Install.perform_preinstall_checks Install.perform_preinstall_checks
if args.no_named? if formulae.blank?
outdated = Formula.installed.select do |f| outdated = Formula.installed.select do |f|
f.outdated?(fetch_head: args.fetch_HEAD?) f.outdated?(fetch_head: args.fetch_HEAD?)
end end
exit 0 if outdated.empty?
else else
outdated = args.resolved_formulae.select do |f| outdated, not_outdated = formulae.partition do |f|
f.outdated?(fetch_head: args.fetch_HEAD?) f.outdated?(fetch_head: args.fetch_HEAD?)
end end
(args.resolved_formulae - outdated).each do |f| not_outdated.each do |f|
versions = f.installed_kegs.map(&:version) versions = f.installed_kegs.map(&:version)
if versions.empty? if versions.empty?
ofail "#{f.full_specified_name} not installed" ofail "#{f.full_specified_name} not installed"
@ -82,9 +92,10 @@ module Homebrew
opoo "#{f.full_specified_name} #{version} already installed" opoo "#{f.full_specified_name} #{version} already installed"
end end
end end
return if outdated.empty?
end end
return if outdated.blank?
pinned = outdated.select(&:pinned?) pinned = outdated.select(&:pinned?)
outdated -= pinned outdated -= pinned
formulae_to_install = outdated.map(&:latest_formula) formulae_to_install = outdated.map(&:latest_formula)
@ -115,4 +126,12 @@ module Homebrew
Homebrew.messages.display_messages Homebrew.messages.display_messages
end end
def upgrade_outdated_casks(casks)
cask_upgrade = Cask::Cmd::Upgrade.new(casks)
cask_upgrade.force = args.force?
cask_upgrade.dry_run = args.dry_run?
cask_upgrade.greedy = args.greedy?
cask_upgrade.run
end
end end

View File

@ -23,7 +23,6 @@ describe "brew outdated", :integration_test do
expect { brew "outdated", "--json=v1" } expect { brew "outdated", "--json=v1" }
.to output(expected_json + "\n").to_stdout .to output(expected_json + "\n").to_stdout
.and not_to_output.to_stderr
.and be_a_success .and be_a_success
end end
end end

View File

@ -356,9 +356,15 @@ otherwise.
* `-v`, `--verbose`: * `-v`, `--verbose`:
Include detailed version information. Include detailed version information.
* `--json`: * `--json`:
Print output in JSON format. Currently the default and only accepted value for *`version`* is `v1`. See the docs for examples of using the JSON output: <https://docs.brew.sh/Querying-Brew> Print output in JSON format. There are two versions: v1 and v2. v1 is deprecated and is currently the default if no version is specified. v2 prints outdated formulae and casks.
* `--fetch-HEAD`: * `--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. 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.
* `--greedy`:
Print outdated casks with `auto_updates` or `version :latest`.
* `--formula`:
Treat all arguments as formulae.
* `--cask`:
Treat all arguments as casks.
### `pin` *`formula`* ### `pin` *`formula`*
@ -556,6 +562,8 @@ the upgraded formulae or, every 30 days, for all formulae.
Print install times for each formula at the end of the run. Print install times for each formula at the end of the run.
* `-n`, `--dry-run`: * `-n`, `--dry-run`:
Show what would be upgraded, but do not actually upgrade anything. Show what would be upgraded, but do not actually upgrade anything.
* `--greedy`:
Upgrade casks with `auto_updates` or `version :latest`
### `uses` [*`options`*] *`formula`* ### `uses` [*`options`*] *`formula`*

View File

@ -477,12 +477,24 @@ Include detailed version information\.
. .
.TP .TP
\fB\-\-json\fR \fB\-\-json\fR
Print output in JSON format\. Currently the default and only accepted value for \fIversion\fR is \fBv1\fR\. See the docs for examples of using the JSON output: \fIhttps://docs\.brew\.sh/Querying\-Brew\fR Print output in JSON format\. There are two versions: v1 and v2\. v1 is deprecated and is currently the default if no version is specified\. v2 prints outdated formulae and casks\.
. .
.TP .TP
\fB\-\-fetch\-HEAD\fR \fB\-\-fetch\-HEAD\fR
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\. 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\.
. .
.TP
\fB\-\-greedy\fR
Print outdated casks with \fBauto_updates\fR or \fBversion :latest\fR\.
.
.TP
\fB\-\-formula\fR
Treat all arguments as formulae\.
.
.TP
\fB\-\-cask\fR
Treat all arguments as casks\.
.
.SS "\fBpin\fR \fIformula\fR" .SS "\fBpin\fR \fIformula\fR"
Pin the specified \fIformula\fR, preventing them from being upgraded when issuing the \fBbrew upgrade\fR \fIformula\fR command\. See also \fBunpin\fR\. Pin the specified \fIformula\fR, preventing them from being upgraded when issuing the \fBbrew upgrade\fR \fIformula\fR command\. See also \fBunpin\fR\.
. .
@ -722,6 +734,10 @@ Print install times for each formula at the end of the run\.
\fB\-n\fR, \fB\-\-dry\-run\fR \fB\-n\fR, \fB\-\-dry\-run\fR
Show what would be upgraded, but do not actually upgrade anything\. Show what would be upgraded, but do not actually upgrade anything\.
. .
.TP
\fB\-\-greedy\fR
Upgrade casks with \fBauto_updates\fR or \fBversion :latest\fR
.
.SS "\fBuses\fR [\fIoptions\fR] \fIformula\fR" .SS "\fBuses\fR [\fIoptions\fR] \fIformula\fR"
Show formulae that specify \fIformula\fR as a dependency (i\.e\. show dependents of \fIformula\fR)\. When given multiple formula arguments, show the intersection of formulae that use \fIformula\fR\. By default, \fBuses\fR shows all formulae that specify \fIformula\fR as a required or recommended dependency for their stable builds\. Show formulae that specify \fIformula\fR as a dependency (i\.e\. show dependents of \fIformula\fR)\. When given multiple formula arguments, show the intersection of formulae that use \fIformula\fR\. By default, \fBuses\fR shows all formulae that specify \fIformula\fR as a required or recommended dependency for their stable builds\.
. .