brew/Library/Homebrew/cmd/upgrade.rb

174 lines
5.2 KiB
Ruby
Raw Normal View History

#: * `upgrade` [<install-options>] [`--cleanup`] [`--fetch-HEAD`] [<formulae>]:
2016-04-08 16:28:43 +02:00
#: Upgrade outdated, unpinned brews.
#:
#: Options for the `install` command are also valid here.
#:
#: If `--cleanup` is specified then remove previously installed <formula> version(s).
#:
2016-08-11 09:28:29 +02:00
#: If `--fetch-HEAD` is passed, fetch the upstream repository to detect if
#: the HEAD installation of the formula is outdated. Otherwise, the
#: repository's HEAD will be checked for updates when a new stable or devel
#: version has been released.
#:
2016-04-08 16:28:43 +02:00
#: If <formulae> are given, upgrade only the specified brews (but do so even
#: if they are pinned; see `pin`, `unpin`).
require "cmd/install"
require "cleanup"
require "development_tools"
module Homebrew
2016-09-26 01:44:51 +02:00
module_function
def upgrade
FormulaInstaller.prevent_build_flags unless DevelopmentTools.installed?
Homebrew.perform_preinstall_checks
if ARGV.include?("--all")
2017-10-15 02:28:32 +02:00
opoo <<~EOS
We decided to not change the behaviour of `brew upgrade` so
`brew upgrade --all` is equivalent to `brew upgrade` without any other
arguments (so the `--all` is a no-op and can be removed).
EOS
end
if ARGV.named.empty?
outdated = Formula.installed.select do |f|
f.outdated?(fetch_head: ARGV.fetch_head?)
end
exit 0 if outdated.empty?
else
outdated = ARGV.resolved_formulae.select do |f|
f.outdated?(fetch_head: ARGV.fetch_head?)
end
2015-05-17 21:16:07 +08:00
(ARGV.resolved_formulae - outdated).each do |f|
2016-09-10 10:24:57 +01:00
versions = f.installed_kegs.map(&:version)
if versions.empty?
onoe "#{f.full_specified_name} not installed"
else
2015-11-29 15:37:06 +08:00
version = versions.max
onoe "#{f.full_specified_name} #{version} already installed"
end
end
exit 1 if outdated.empty?
end
unless upgrade_pinned?
pinned = outdated.select(&:pinned?)
outdated -= pinned
end
formulae_to_install = outdated.map(&:latest_formula)
if formulae_to_install.empty?
2016-09-10 10:24:57 +01:00
oh1 "No packages to upgrade"
else
2017-03-11 11:33:12 +01:00
oh1 "Upgrading #{Formatter.pluralize(formulae_to_install.length, "outdated package")}, with result:"
puts formulae_to_install.map { |f| "#{f.full_specified_name} #{f.pkg_version}" } * ", "
end
2013-07-15 23:47:03 -05:00
unless upgrade_pinned? || pinned.empty?
2017-03-11 11:33:12 +01:00
oh1 "Not upgrading #{Formatter.pluralize(pinned.length, "pinned package")}:"
puts pinned.map { |f| "#{f.full_specified_name} #{f.pkg_version}" } * ", "
end
# Sort keg_only before non-keg_only formulae to avoid any needless conflicts
# with outdated, non-keg_only versions of formulae being upgraded.
formulae_to_install.sort! do |a, b|
if !a.keg_only? && b.keg_only?
1
elsif a.keg_only? && !b.keg_only?
-1
else
0
end
end
formulae_to_install.each do |f|
Migrator.migrate_if_needed(f)
upgrade_formula(f)
next unless ARGV.include?("--cleanup")
next unless f.installed?
Homebrew::Cleanup.cleanup_formula f
end
end
def upgrade_pinned?
!ARGV.named.empty?
end
def upgrade_formula(f)
if f.opt_prefix.directory?
keg = Keg.new(f.opt_prefix.resolved_path)
keg_had_linked_opt = true
keg_was_linked = keg.linked?
end
formulae_maybe_with_kegs = [f] + f.old_installed_formulae
2016-09-19 16:04:32 +01:00
outdated_kegs = formulae_maybe_with_kegs
.map(&:linked_keg)
.select(&:directory?)
.map { |k| Keg.new(k.resolved_path) }
linked_kegs = outdated_kegs.select(&:linked?)
if f.opt_prefix.directory?
keg = Keg.new(f.opt_prefix.resolved_path)
tab = Tab.for_keg(keg)
end
new_build_options = BuildOptions.new(Options.create(ARGV.flags_only), f.options)
fi = FormulaInstaller.new(f)
fi.options = new_build_options.used_options
fi.options |= f.build.used_options
fi.options &= f.options
fi.build_bottle = ARGV.build_bottle? || (!f.bottled? && f.build.build_bottle?)
fi.installed_on_request = !ARGV.named.empty?
fi.link_keg = keg_was_linked if keg_had_linked_opt
if tab
fi.installed_as_dependency = tab.installed_as_dependency
fi.installed_on_request ||= tab.installed_on_request
end
fi.prelude
oh1 "Upgrading #{f.full_specified_name} #{fi.options.to_a.join " "}"
# first we unlink the currently active keg for this formula otherwise it is
# possible for the existing build to interfere with the build we are about to
# do! Seriously, it happens!
outdated_kegs.each(&:unlink)
fi.install
fi.finish
# If the formula was pinned, and we were force-upgrading it, unpin and
# pin it again to get a symlink pointing to the correct keg.
if f.pinned?
f.unpin
f.pin
end
rescue FormulaInstallationAlreadyAttemptedError
# We already attempted to upgrade f as part of the dependency tree of
# another formula. In that case, don't generate an error, just move on.
return
rescue CannotInstallFormulaError => e
ofail e
rescue BuildError => e
e.dump
puts
Homebrew.failed = true
rescue DownloadError => e
ofail e
ensure
# restore previous installation state if build failed
2016-09-10 10:24:57 +01:00
begin
linked_kegs.each(&:link) unless f.installed?
2016-09-10 10:24:57 +01:00
rescue
nil
end
end
end