2016-09-08 09:05:00 +01:00
|
|
|
#: @hide_from_man_page
|
|
|
|
#: * `update_report`:
|
|
|
|
#: The Ruby implementation of `brew update`. Never called manually.
|
|
|
|
|
2016-01-10 20:28:52 +00:00
|
|
|
require "formula_versions"
|
|
|
|
require "migrator"
|
|
|
|
require "formulary"
|
|
|
|
require "descriptions"
|
2016-06-01 08:46:33 +01:00
|
|
|
require "cleanup"
|
2016-09-17 15:00:46 +01:00
|
|
|
require "utils"
|
2016-01-10 20:28:52 +00:00
|
|
|
|
|
|
|
module Homebrew
|
2016-04-11 09:31:50 +01:00
|
|
|
def update_preinstall_header
|
|
|
|
@header_already_printed ||= begin
|
|
|
|
ohai "Auto-updated Homebrew!" if ARGV.include?("--preinstall")
|
|
|
|
true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-01-10 20:28:52 +00:00
|
|
|
def update_report
|
2016-04-25 18:05:30 -05:00
|
|
|
HOMEBREW_REPOSITORY.cd do
|
|
|
|
analytics_message_displayed = \
|
2016-04-25 18:51:00 -05:00
|
|
|
Utils.popen_read("git", "config", "--local", "--get", "homebrew.analyticsmessage").chuzzle
|
|
|
|
analytics_disabled = \
|
|
|
|
Utils.popen_read("git", "config", "--local", "--get", "homebrew.analyticsdisabled").chuzzle
|
2016-05-01 22:04:46 +08:00
|
|
|
if analytics_message_displayed != "true" && analytics_disabled != "true" && !ENV["HOMEBREW_NO_ANALYTICS"]
|
2016-04-26 04:28:38 -04:00
|
|
|
ENV["HOMEBREW_NO_ANALYTICS_THIS_RUN"] = "1"
|
2016-04-25 18:05:30 -05:00
|
|
|
ohai "Homebrew has enabled anonymous aggregate user behaviour analytics"
|
|
|
|
puts "Read the analytics documentation (and how to opt-out) here:"
|
|
|
|
puts " https://git.io/brew-analytics"
|
|
|
|
|
|
|
|
# Consider the message possibly missed if not a TTY.
|
|
|
|
if $stdout.tty?
|
2016-04-25 18:51:00 -05:00
|
|
|
safe_system "git", "config", "--local", "--replace-all", "homebrew.analyticsmessage", "true"
|
2016-04-25 18:05:30 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-02-26 17:39:49 +08:00
|
|
|
install_core_tap_if_necessary
|
2016-01-10 20:28:52 +00:00
|
|
|
|
2016-02-25 16:41:34 +08:00
|
|
|
hub = ReporterHub.new
|
2016-03-06 14:55:37 +08:00
|
|
|
updated = false
|
2016-02-25 16:41:34 +08:00
|
|
|
|
2016-03-06 14:55:37 +08:00
|
|
|
initial_revision = ENV["HOMEBREW_UPDATE_BEFORE"].to_s
|
|
|
|
current_revision = ENV["HOMEBREW_UPDATE_AFTER"].to_s
|
|
|
|
if initial_revision.empty? || current_revision.empty?
|
2016-02-25 16:41:34 +08:00
|
|
|
odie "update-report should not be called directly!"
|
|
|
|
end
|
|
|
|
|
2016-03-06 14:55:37 +08:00
|
|
|
if initial_revision != current_revision
|
2016-04-11 09:31:50 +01:00
|
|
|
update_preinstall_header
|
2016-03-06 14:55:37 +08:00
|
|
|
puts "Updated Homebrew from #{shorten_revision(initial_revision)} to #{shorten_revision(current_revision)}."
|
|
|
|
updated = true
|
2016-01-10 20:28:52 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
updated_taps = []
|
|
|
|
Tap.each do |tap|
|
2016-01-20 19:42:55 +08:00
|
|
|
next unless tap.git?
|
2016-02-25 16:41:34 +08:00
|
|
|
begin
|
|
|
|
reporter = Reporter.new(tap)
|
|
|
|
rescue Reporter::ReporterRevisionUnsetError => e
|
2016-08-05 15:53:24 +01:00
|
|
|
onoe "#{e.message}\n#{e.backtrace.join "\n"}" if ARGV.homebrew_developer?
|
2016-02-25 16:41:34 +08:00
|
|
|
next
|
|
|
|
end
|
|
|
|
if reporter.updated?
|
|
|
|
updated_taps << tap.name
|
|
|
|
hub.add(reporter)
|
2016-01-10 20:28:52 +00:00
|
|
|
end
|
|
|
|
end
|
2016-03-06 14:55:37 +08:00
|
|
|
|
2016-01-10 20:28:52 +00:00
|
|
|
unless updated_taps.empty?
|
2016-04-11 09:31:50 +01:00
|
|
|
update_preinstall_header
|
2016-01-10 20:28:52 +00:00
|
|
|
puts "Updated #{updated_taps.size} tap#{plural(updated_taps.size)} " \
|
|
|
|
"(#{updated_taps.join(", ")})."
|
2016-03-06 14:55:37 +08:00
|
|
|
updated = true
|
2016-01-10 20:28:52 +00:00
|
|
|
end
|
2016-01-26 09:03:28 +00:00
|
|
|
|
2016-06-01 08:46:33 +01:00
|
|
|
migrate_legacy_cache_if_necessary
|
2016-09-16 13:51:21 +01:00
|
|
|
migrate_legacy_keg_symlinks_if_necessary
|
2016-06-01 08:46:33 +01:00
|
|
|
|
2016-03-06 14:55:37 +08:00
|
|
|
if !updated
|
2016-05-03 14:24:41 +01:00
|
|
|
if !ARGV.include?("--preinstall") && !ENV["HOMEBREW_UPDATE_FAILED"]
|
|
|
|
puts "Already up-to-date."
|
|
|
|
end
|
2016-02-25 16:41:34 +08:00
|
|
|
else
|
2016-09-03 19:36:34 +01:00
|
|
|
if hub.empty?
|
|
|
|
puts "No changes to formulae."
|
|
|
|
else
|
|
|
|
hub.dump
|
|
|
|
hub.reporters.each(&:migrate_tap_migration)
|
|
|
|
hub.reporters.each(&:migrate_formula_rename)
|
|
|
|
Descriptions.update_cache(hub)
|
|
|
|
end
|
|
|
|
puts if ARGV.include?("--preinstall")
|
2016-01-26 09:03:28 +00:00
|
|
|
end
|
2016-01-10 20:28:52 +00:00
|
|
|
|
2016-09-06 09:04:51 +01:00
|
|
|
link_completions_and_docs
|
2016-01-10 20:28:52 +00:00
|
|
|
Tap.each(&:link_manpages)
|
2016-05-03 14:24:41 +01:00
|
|
|
|
|
|
|
Homebrew.failed = true if ENV["HOMEBREW_UPDATE_FAILED"]
|
2016-09-17 14:24:57 +01:00
|
|
|
|
|
|
|
# This should always be the last thing to run
|
|
|
|
migrate_legacy_repository_if_necessary
|
2016-01-10 20:28:52 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def shorten_revision(revision)
|
2016-02-25 16:41:34 +08:00
|
|
|
Utils.popen_read("git", "-C", HOMEBREW_REPOSITORY, "rev-parse", "--short", revision).chomp
|
2016-01-10 20:28:52 +00:00
|
|
|
end
|
2016-02-26 17:39:49 +08:00
|
|
|
|
|
|
|
def install_core_tap_if_necessary
|
|
|
|
core_tap = CoreTap.instance
|
|
|
|
return if core_tap.installed?
|
2016-09-17 15:32:44 +01:00
|
|
|
CoreTap.ensure_installed! quiet: false
|
2016-02-26 17:39:49 +08:00
|
|
|
revision = core_tap.git_head
|
|
|
|
ENV["HOMEBREW_UPDATE_BEFORE_HOMEBREW_HOMEBREW_CORE"] = revision
|
|
|
|
ENV["HOMEBREW_UPDATE_AFTER_HOMEBREW_HOMEBREW_CORE"] = revision
|
|
|
|
end
|
2016-06-01 08:46:33 +01:00
|
|
|
|
|
|
|
def migrate_legacy_cache_if_necessary
|
|
|
|
legacy_cache = Pathname.new "/Library/Caches/Homebrew"
|
|
|
|
return if HOMEBREW_CACHE.to_s == legacy_cache.to_s
|
|
|
|
return unless legacy_cache.directory?
|
|
|
|
return unless legacy_cache.readable_real?
|
|
|
|
|
|
|
|
migration_attempted_file = legacy_cache/".migration_attempted"
|
|
|
|
return if migration_attempted_file.exist?
|
|
|
|
|
|
|
|
return unless legacy_cache.writable_real?
|
|
|
|
FileUtils.touch migration_attempted_file
|
|
|
|
|
|
|
|
# Cleanup to avoid copying files unnecessarily
|
|
|
|
ohai "Cleaning up #{legacy_cache}..."
|
|
|
|
Cleanup.cleanup_cache legacy_cache
|
|
|
|
|
|
|
|
# This directory could have been compromised if it's world-writable/
|
|
|
|
# a symlink/owned by another user so don't copy files in those cases.
|
2016-06-01 09:49:50 +01:00
|
|
|
world_writable = legacy_cache.stat.mode & 0777 == 0777
|
|
|
|
return if world_writable
|
2016-06-01 08:46:33 +01:00
|
|
|
return if legacy_cache.symlink?
|
2016-09-10 10:24:57 +01:00
|
|
|
return if !legacy_cache.owned? && legacy_cache.lstat.uid.nonzero?
|
2016-06-01 08:46:33 +01:00
|
|
|
|
|
|
|
ohai "Migrating #{legacy_cache} to #{HOMEBREW_CACHE}..."
|
|
|
|
HOMEBREW_CACHE.mkpath
|
|
|
|
legacy_cache.cd do
|
|
|
|
legacy_cache.entries.each do |f|
|
2016-09-10 10:24:57 +01:00
|
|
|
next if [".", "..", ".migration_attempted"].include? f.to_s
|
2016-06-01 08:46:33 +01:00
|
|
|
begin
|
|
|
|
FileUtils.cp_r f, HOMEBREW_CACHE
|
|
|
|
rescue
|
|
|
|
@migration_failed ||= true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if @migration_failed
|
|
|
|
opoo <<-EOS.undent
|
|
|
|
Failed to migrate #{legacy_cache} to
|
|
|
|
#{HOMEBREW_CACHE}. Please do so manually.
|
|
|
|
EOS
|
|
|
|
else
|
|
|
|
ohai "Deleting #{legacy_cache}..."
|
|
|
|
FileUtils.rm_rf legacy_cache
|
2016-06-01 13:03:03 +01:00
|
|
|
if legacy_cache.exist?
|
|
|
|
FileUtils.touch migration_attempted_file
|
|
|
|
opoo <<-EOS.undent
|
|
|
|
Failed to delete #{legacy_cache}.
|
|
|
|
Please do so manually.
|
|
|
|
EOS
|
|
|
|
end
|
2016-06-01 08:46:33 +01:00
|
|
|
end
|
|
|
|
end
|
2016-08-22 11:07:15 +01:00
|
|
|
|
2016-09-17 14:24:57 +01:00
|
|
|
def migrate_legacy_repository_if_necessary
|
|
|
|
return unless HOMEBREW_PREFIX.to_s == "/usr/local"
|
|
|
|
return unless HOMEBREW_REPOSITORY.to_s == "/usr/local"
|
|
|
|
return unless ARGV.homebrew_developer?
|
|
|
|
|
|
|
|
ohai "Migrating HOMEBREW_REPOSITORY (please wait)..."
|
|
|
|
|
|
|
|
unless HOMEBREW_PREFIX.writable_real?
|
|
|
|
ofail <<-EOS.undent
|
|
|
|
#{HOMEBREW_PREFIX} is not writable.
|
|
|
|
|
|
|
|
You should change the ownership and permissions of #{HOMEBREW_PREFIX}
|
|
|
|
temporarily back to your user account so we can complete the Homebrew
|
|
|
|
repository migration:
|
|
|
|
sudo chown -R $(whoami) #{HOMEBREW_PREFIX}
|
|
|
|
EOS
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
new_homebrew_repository = Pathname.new "/usr/local/Homebrew"
|
|
|
|
if new_homebrew_repository.exist?
|
|
|
|
ofail <<-EOS.undent
|
|
|
|
#{new_homebrew_repository} already exists.
|
|
|
|
Please remove it manually or uninstall and reinstall Homebrew into a new
|
|
|
|
location as the migration cannot be done automatically.
|
|
|
|
EOS
|
|
|
|
return
|
|
|
|
end
|
|
|
|
new_homebrew_repository.mkpath
|
|
|
|
|
|
|
|
repo_files = HOMEBREW_REPOSITORY.cd do
|
|
|
|
Utils.popen_read("git ls-files").lines.map(&:chomp)
|
|
|
|
end
|
|
|
|
|
|
|
|
unless Utils.popen_read("git status --untracked-files=all --porcelain").empty?
|
|
|
|
HOMEBREW_REPOSITORY.cd do
|
|
|
|
safe_system "git", "-c", "user.email=brew-update@localhost",
|
|
|
|
"-c", "user.name=brew update",
|
|
|
|
"stash", "save", "--include-untracked"
|
|
|
|
end
|
|
|
|
stashed = true
|
|
|
|
end
|
|
|
|
|
|
|
|
FileUtils.cp_r "#{HOMEBREW_REPOSITORY}/.git", "#{new_homebrew_repository}/.git"
|
|
|
|
new_homebrew_repository.cd do
|
|
|
|
safe_system "git", "checkout", "--force", "."
|
|
|
|
safe_system "git", "stash", "pop" if stashed
|
|
|
|
end
|
|
|
|
|
|
|
|
if (HOMEBREW_REPOSITORY/"Library/Locks").exist?
|
|
|
|
FileUtils.cp_r "#{HOMEBREW_REPOSITORY}/Library/Locks", "#{new_homebrew_repository}/Library/Locks"
|
|
|
|
end
|
|
|
|
|
|
|
|
if (HOMEBREW_REPOSITORY/"Library/Taps").exist?
|
|
|
|
FileUtils.cp_r "#{HOMEBREW_REPOSITORY}/Library/Taps", "#{new_homebrew_repository}/Library/Taps"
|
|
|
|
end
|
|
|
|
|
|
|
|
unremovable_paths = []
|
|
|
|
extra_remove_paths = [".git", "Library/Locks", "Library/Taps",
|
|
|
|
"Library/Homebrew/test"]
|
|
|
|
(repo_files + extra_remove_paths).each do |file|
|
|
|
|
path = Pathname.new "#{HOMEBREW_REPOSITORY}/#{file}"
|
|
|
|
begin
|
|
|
|
FileUtils.rm_rf path
|
|
|
|
rescue Errno::EACCES
|
|
|
|
unremovable_paths << path
|
|
|
|
end
|
|
|
|
quiet_system "rmdir", "-p", path.parent if path.parent.exist?
|
|
|
|
end
|
|
|
|
|
|
|
|
unless unremovable_paths.empty?
|
|
|
|
ofail <<-EOS.undent
|
|
|
|
Could not remove old HOMEBREW_REPOSITORY paths!
|
|
|
|
Please do this manually with:
|
|
|
|
sudo rm -rf #{unremovable_paths.join " "}
|
|
|
|
EOS
|
|
|
|
end
|
|
|
|
|
2016-09-18 19:32:29 +01:00
|
|
|
(Keg::ALL_TOP_LEVEL_DIRECTORIES + ["Cellar"]).each do |dir|
|
2016-09-18 16:06:49 +01:00
|
|
|
FileUtils.mkdir_p "#{HOMEBREW_PREFIX}/#{dir}"
|
|
|
|
end
|
|
|
|
|
2016-09-17 14:24:57 +01:00
|
|
|
src = Pathname.new("#{new_homebrew_repository}/bin/brew")
|
|
|
|
dst = Pathname.new("#{HOMEBREW_PREFIX}/bin/brew")
|
|
|
|
begin
|
|
|
|
FileUtils.ln_s(src.relative_path_from(dst.parent), dst)
|
2016-09-18 16:55:59 +01:00
|
|
|
rescue Errno::EACCES, Errno::ENOENT
|
2016-09-17 14:24:57 +01:00
|
|
|
ofail <<-EOS.undent
|
|
|
|
Could not create symlink at #{dst}!
|
|
|
|
Please do this manually with:
|
|
|
|
sudo ln -sf #{src} #{dst}
|
|
|
|
sudo chown $(whoami) #{dst}
|
|
|
|
EOS
|
|
|
|
end
|
|
|
|
|
|
|
|
link_completions_and_docs(new_homebrew_repository)
|
|
|
|
|
|
|
|
ohai "Migrated HOMEBREW_REPOSITORY to #{new_homebrew_repository}!"
|
|
|
|
puts "You may now chown #{HOMEBREW_PREFIX} back to root:wheel."
|
|
|
|
rescue => e
|
|
|
|
ofail <<-EOS.undent
|
|
|
|
#{e}
|
|
|
|
#{Tty.white}Failed to migrate HOMEBREW_REPOSITORY to #{new_homebrew_repository}!
|
|
|
|
Please comment with your (new) error in issue:
|
|
|
|
#{Tty.em}https://github.com/Homebrew/brew/issues/987#{Tty.reset}
|
|
|
|
EOS
|
|
|
|
$stderr.puts e.backtrace
|
|
|
|
end
|
|
|
|
|
|
|
|
def link_completions_and_docs(repository = HOMEBREW_REPOSITORY)
|
|
|
|
return if HOMEBREW_PREFIX.to_s == repository.to_s
|
2016-09-06 09:04:51 +01:00
|
|
|
command = "brew update"
|
2016-09-17 14:24:57 +01:00
|
|
|
link_src_dst_dirs(repository/"etc/bash_completion.d",
|
2016-09-06 09:04:51 +01:00
|
|
|
HOMEBREW_PREFIX/"etc/bash_completion.d", command)
|
2016-09-17 14:24:57 +01:00
|
|
|
link_src_dst_dirs(repository/"share/doc/homebrew",
|
2016-09-17 15:32:44 +01:00
|
|
|
HOMEBREW_PREFIX/"share/doc/homebrew", command, link_dir: true)
|
2016-09-17 14:24:57 +01:00
|
|
|
link_src_dst_dirs(repository/"share/zsh/site-functions",
|
2016-09-06 09:04:51 +01:00
|
|
|
HOMEBREW_PREFIX/"share/zsh/site-functions", command)
|
2016-09-17 14:24:57 +01:00
|
|
|
link_path_manpages(repository/"share", command)
|
2016-08-22 11:07:15 +01:00
|
|
|
end
|
2016-01-10 20:28:52 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
class Reporter
|
2016-02-25 15:34:11 +08:00
|
|
|
class ReporterRevisionUnsetError < RuntimeError
|
|
|
|
def initialize(var_name)
|
|
|
|
super "#{var_name} is unset!"
|
2016-01-20 19:41:42 +08:00
|
|
|
end
|
2016-01-10 20:28:52 +00:00
|
|
|
end
|
|
|
|
|
2016-02-25 15:34:11 +08:00
|
|
|
attr_reader :tap, :initial_revision, :current_revision
|
|
|
|
|
|
|
|
def initialize(tap)
|
|
|
|
@tap = tap
|
2016-01-10 20:28:52 +00:00
|
|
|
|
|
|
|
initial_revision_var = "HOMEBREW_UPDATE_BEFORE#{repo_var}"
|
|
|
|
@initial_revision = ENV[initial_revision_var].to_s
|
2016-02-25 15:34:11 +08:00
|
|
|
raise ReporterRevisionUnsetError, initial_revision_var if @initial_revision.empty?
|
2016-01-10 20:28:52 +00:00
|
|
|
|
|
|
|
current_revision_var = "HOMEBREW_UPDATE_AFTER#{repo_var}"
|
|
|
|
@current_revision = ENV[current_revision_var].to_s
|
2016-02-25 15:34:11 +08:00
|
|
|
raise ReporterRevisionUnsetError, current_revision_var if @current_revision.empty?
|
2016-01-10 20:28:52 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def report
|
2016-02-25 15:34:11 +08:00
|
|
|
return @report if @report
|
|
|
|
|
|
|
|
@report = Hash.new { |h, k| h[k] = [] }
|
|
|
|
return @report unless updated?
|
|
|
|
|
|
|
|
diff.each_line do |line|
|
|
|
|
status, *paths = line.split
|
|
|
|
src = Pathname.new paths.first
|
|
|
|
dst = Pathname.new paths.last
|
|
|
|
|
|
|
|
next unless dst.extname == ".rb"
|
2016-08-05 16:00:33 +01:00
|
|
|
|
|
|
|
if paths.any? { |p| tap.cask_file?(p) }
|
|
|
|
# Currently only need to handle Cask deletion/migration.
|
|
|
|
if status == "D"
|
|
|
|
# Have a dedicated report array for deleted casks.
|
|
|
|
@report[:DC] << tap.formula_file_to_name(src)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
next unless paths.any? { |p| tap.formula_file?(p) }
|
2016-02-25 15:34:11 +08:00
|
|
|
|
|
|
|
case status
|
|
|
|
when "A", "D"
|
|
|
|
@report[status.to_sym] << tap.formula_file_to_name(src)
|
|
|
|
when "M"
|
|
|
|
begin
|
|
|
|
formula = Formulary.factory(tap.path/src)
|
|
|
|
new_version = formula.pkg_version
|
|
|
|
old_version = FormulaVersions.new(formula).formula_at_revision(@initial_revision, &:pkg_version)
|
|
|
|
next if new_version == old_version
|
|
|
|
rescue Exception => e
|
2016-08-05 15:53:24 +01:00
|
|
|
onoe "#{e.message}\n#{e.backtrace.join "\n"}" if ARGV.homebrew_developer?
|
2016-01-10 20:28:52 +00:00
|
|
|
end
|
2016-02-25 15:34:11 +08:00
|
|
|
@report[:M] << tap.formula_file_to_name(src)
|
|
|
|
when /^R\d{0,3}/
|
2016-07-16 01:18:30 -04:00
|
|
|
src_full_name = tap.formula_file_to_name(src)
|
|
|
|
dst_full_name = tap.formula_file_to_name(dst)
|
|
|
|
# Don't report formulae that are moved within a tap but not renamed
|
|
|
|
next if src_full_name == dst_full_name
|
|
|
|
@report[:D] << src_full_name
|
|
|
|
@report[:A] << dst_full_name
|
2016-02-25 15:34:11 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
renamed_formulae = []
|
|
|
|
@report[:D].each do |old_full_name|
|
|
|
|
old_name = old_full_name.split("/").last
|
|
|
|
new_name = tap.formula_renames[old_name]
|
|
|
|
next unless new_name
|
|
|
|
|
2016-03-07 18:04:25 +08:00
|
|
|
if tap.core_tap?
|
2016-02-25 15:34:11 +08:00
|
|
|
new_full_name = new_name
|
|
|
|
else
|
2016-02-25 17:27:50 +08:00
|
|
|
new_full_name = "#{tap}/#{new_name}"
|
2016-01-10 20:28:52 +00:00
|
|
|
end
|
2016-02-25 15:34:11 +08:00
|
|
|
|
|
|
|
renamed_formulae << [old_full_name, new_full_name] if @report[:A].include? new_full_name
|
|
|
|
end
|
|
|
|
|
|
|
|
unless renamed_formulae.empty?
|
|
|
|
@report[:A] -= renamed_formulae.map(&:last)
|
|
|
|
@report[:D] -= renamed_formulae.map(&:first)
|
|
|
|
@report[:R] = renamed_formulae
|
2016-01-10 20:28:52 +00:00
|
|
|
end
|
|
|
|
|
2016-02-25 15:34:11 +08:00
|
|
|
@report
|
2016-01-10 20:28:52 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def updated?
|
2016-02-25 15:34:11 +08:00
|
|
|
initial_revision != current_revision
|
2016-01-10 20:28:52 +00:00
|
|
|
end
|
|
|
|
|
2016-02-25 15:34:11 +08:00
|
|
|
def migrate_tap_migration
|
2016-08-05 16:00:33 +01:00
|
|
|
(report[:D] + report[:DC]).each do |full_name|
|
2016-02-25 15:34:11 +08:00
|
|
|
name = full_name.split("/").last
|
2016-07-26 00:15:21 +03:00
|
|
|
new_tap_name = tap.tap_migrations[name]
|
|
|
|
next if new_tap_name.nil? # skip if not in tap_migrations list.
|
|
|
|
|
2016-08-05 16:00:33 +01:00
|
|
|
# This means it is a Cask
|
|
|
|
if report[:DC].include? full_name
|
2016-07-26 00:15:21 +03:00
|
|
|
next unless (HOMEBREW_REPOSITORY/"Caskroom"/name).exist?
|
|
|
|
new_tap = Tap.fetch(new_tap_name)
|
|
|
|
new_tap.install unless new_tap.installed?
|
|
|
|
ohai "#{name} has been moved to Homebrew.", <<-EOS.undent
|
|
|
|
To uninstall the cask run:
|
|
|
|
brew cask uninstall --force #{name}
|
|
|
|
EOS
|
|
|
|
new_full_name = "#{new_tap_name}/#{name}"
|
|
|
|
next if (HOMEBREW_CELLAR/name.split("/").last).directory?
|
|
|
|
ohai "Installing #{name}..."
|
|
|
|
system HOMEBREW_BREW_FILE, "install", new_full_name
|
|
|
|
begin
|
|
|
|
unless Formulary.factory(new_full_name).keg_only?
|
2016-08-02 11:48:11 +01:00
|
|
|
system HOMEBREW_BREW_FILE, "link", new_full_name, "--overwrite"
|
2016-07-26 00:15:21 +03:00
|
|
|
end
|
|
|
|
rescue Exception => e
|
2016-08-05 15:53:24 +01:00
|
|
|
onoe "#{e.message}\n#{e.backtrace.join "\n"}" if ARGV.homebrew_developer?
|
2016-07-26 00:15:21 +03:00
|
|
|
end
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
2016-02-25 15:34:11 +08:00
|
|
|
next unless (dir = HOMEBREW_CELLAR/name).exist? # skip if formula is not installed.
|
|
|
|
tabs = dir.subdirs.map { |d| Tab.for_keg(Keg.new(d)) }
|
|
|
|
next unless tabs.first.tap == tap # skip if installed formula is not from this tap.
|
|
|
|
new_tap = Tap.fetch(new_tap_name)
|
2016-06-22 16:36:17 +04:00
|
|
|
# For formulae migrated to cask: Auto-install cask or provide install instructions.
|
|
|
|
if new_tap_name == "caskroom/cask"
|
|
|
|
if new_tap.installed? && (HOMEBREW_REPOSITORY/"Caskroom").directory?
|
2016-08-02 11:45:32 +01:00
|
|
|
ohai "#{name} has been moved to Homebrew Cask."
|
|
|
|
ohai "brew uninstall --force #{name}"
|
2016-06-22 16:36:17 +04:00
|
|
|
system HOMEBREW_BREW_FILE, "uninstall", "--force", name
|
2016-08-02 11:45:32 +01:00
|
|
|
ohai "brew prune"
|
2016-07-03 14:34:38 -05:00
|
|
|
system HOMEBREW_BREW_FILE, "prune"
|
2016-08-02 11:45:32 +01:00
|
|
|
ohai "brew cask install #{name}"
|
2016-06-22 16:36:17 +04:00
|
|
|
system HOMEBREW_BREW_FILE, "cask", "install", name
|
|
|
|
else
|
|
|
|
ohai "#{name} has been moved to Homebrew Cask.", <<-EOS.undent
|
|
|
|
To uninstall the formula and install the cask run:
|
|
|
|
brew uninstall --force #{name}
|
2016-06-22 13:50:39 +01:00
|
|
|
brew cask install #{name}
|
2016-06-22 16:36:17 +04:00
|
|
|
EOS
|
|
|
|
end
|
|
|
|
else
|
|
|
|
new_tap.install unless new_tap.installed?
|
|
|
|
# update tap for each Tab
|
|
|
|
tabs.each { |tab| tab.tap = new_tap }
|
|
|
|
tabs.each(&:write)
|
|
|
|
end
|
2016-02-25 15:34:11 +08:00
|
|
|
end
|
|
|
|
end
|
2016-01-10 20:28:52 +00:00
|
|
|
|
2016-02-25 15:34:11 +08:00
|
|
|
def migrate_formula_rename
|
|
|
|
report[:R].each do |old_full_name, new_full_name|
|
|
|
|
old_name = old_full_name.split("/").last
|
|
|
|
next unless (dir = HOMEBREW_CELLAR/old_name).directory? && !dir.subdirs.empty?
|
|
|
|
|
|
|
|
begin
|
|
|
|
f = Formulary.factory(new_full_name)
|
|
|
|
rescue Exception => e
|
2016-08-05 15:53:24 +01:00
|
|
|
onoe "#{e.message}\n#{e.backtrace.join "\n"}" if ARGV.homebrew_developer?
|
2016-02-25 15:34:11 +08:00
|
|
|
next
|
|
|
|
end
|
|
|
|
|
|
|
|
begin
|
|
|
|
migrator = Migrator.new(f)
|
|
|
|
migrator.migrate
|
|
|
|
rescue Migrator::MigratorDifferentTapsError
|
|
|
|
rescue Exception => e
|
|
|
|
onoe e
|
|
|
|
end
|
2016-01-10 20:28:52 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-02-25 15:34:11 +08:00
|
|
|
private
|
|
|
|
|
|
|
|
def repo_var
|
2016-09-10 10:24:57 +01:00
|
|
|
@repo_var ||= tap.path.to_s
|
|
|
|
.strip_prefix(Tap::TAP_DIRECTORY.to_s)
|
|
|
|
.tr("^A-Za-z0-9", "_")
|
|
|
|
.upcase
|
2016-01-10 20:28:52 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def diff
|
|
|
|
Utils.popen_read(
|
2016-02-25 15:34:11 +08:00
|
|
|
"git", "-C", tap.path, "diff-tree", "-r", "--name-status", "--diff-filter=AMDR",
|
2016-01-10 20:28:52 +00:00
|
|
|
"-M85%", initial_revision, current_revision
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-02-25 15:43:02 +08:00
|
|
|
class ReporterHub
|
|
|
|
attr_reader :reporters
|
|
|
|
|
2016-01-10 20:28:52 +00:00
|
|
|
def initialize
|
|
|
|
@hash = {}
|
2016-02-25 15:43:02 +08:00
|
|
|
@reporters = []
|
2016-01-10 20:28:52 +00:00
|
|
|
end
|
|
|
|
|
2016-02-25 15:43:02 +08:00
|
|
|
def select_formula(key)
|
|
|
|
@hash.fetch(key, [])
|
2016-01-10 20:28:52 +00:00
|
|
|
end
|
|
|
|
|
2016-02-25 15:43:02 +08:00
|
|
|
def add(reporter)
|
|
|
|
@reporters << reporter
|
2016-09-10 10:24:57 +01:00
|
|
|
report = reporter.report.delete_if { |_k, v| v.empty? }
|
2016-02-25 15:43:02 +08:00
|
|
|
@hash.update(report) { |_key, oldval, newval| oldval.concat(newval) }
|
2016-01-10 20:28:52 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def empty?
|
|
|
|
@hash.empty?
|
|
|
|
end
|
|
|
|
|
|
|
|
def dump
|
|
|
|
# Key Legend: Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R)
|
|
|
|
|
|
|
|
dump_formula_report :A, "New Formulae"
|
|
|
|
dump_formula_report :M, "Updated Formulae"
|
|
|
|
dump_formula_report :R, "Renamed Formulae"
|
|
|
|
dump_formula_report :D, "Deleted Formulae"
|
|
|
|
end
|
|
|
|
|
2016-02-25 15:43:02 +08:00
|
|
|
private
|
2016-01-10 20:28:52 +00:00
|
|
|
|
|
|
|
def dump_formula_report(key, title)
|
2016-02-25 15:43:02 +08:00
|
|
|
formulae = select_formula(key).sort.map do |name, new_name|
|
2016-01-10 20:28:52 +00:00
|
|
|
# Format list items of renamed formulae
|
|
|
|
if key == :R
|
2016-02-25 15:43:02 +08:00
|
|
|
name = pretty_installed(name) if installed?(name)
|
|
|
|
new_name = pretty_installed(new_name) if installed?(new_name)
|
2016-01-10 20:28:52 +00:00
|
|
|
"#{name} -> #{new_name}"
|
|
|
|
else
|
|
|
|
installed?(name) ? pretty_installed(name) : name
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-02-25 15:43:02 +08:00
|
|
|
unless formulae.empty?
|
2016-01-10 20:28:52 +00:00
|
|
|
# Dump formula list.
|
|
|
|
ohai title
|
2016-02-25 15:43:02 +08:00
|
|
|
puts_columns(formulae)
|
2016-01-10 20:28:52 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def installed?(formula)
|
|
|
|
(HOMEBREW_CELLAR/formula.split("/").last).directory?
|
|
|
|
end
|
|
|
|
end
|