2012-03-07 22:48:44 +00:00
|
|
|
require 'cmd/tap'
|
2012-03-18 01:23:01 +00:00
|
|
|
require 'cmd/untap'
|
2012-03-07 22:48:44 +00:00
|
|
|
|
2014-06-18 22:41:47 -05:00
|
|
|
module Homebrew
|
2010-09-11 20:22:54 +01:00
|
|
|
def update
|
2013-02-17 13:42:45 +00:00
|
|
|
unless ARGV.named.empty?
|
|
|
|
abort <<-EOS.undent
|
|
|
|
This command updates brew itself, and does not take formula names.
|
|
|
|
Use `brew upgrade <formula>`.
|
|
|
|
EOS
|
|
|
|
end
|
2010-09-11 20:22:54 +01:00
|
|
|
|
2012-03-02 18:23:49 -06:00
|
|
|
# ensure GIT_CONFIG is unset as we need to operate on .git/config
|
|
|
|
ENV.delete('GIT_CONFIG')
|
|
|
|
|
2012-03-06 02:23:01 +00:00
|
|
|
cd HOMEBREW_REPOSITORY
|
|
|
|
git_init_if_necessary
|
2011-09-20 02:25:50 +01:00
|
|
|
|
2014-04-25 12:34:28 -05:00
|
|
|
tapped_formulae = []
|
|
|
|
HOMEBREW_LIBRARY.join("Formula").children.each do |path|
|
2013-09-24 19:39:04 +01:00
|
|
|
next unless path.symlink?
|
2014-04-25 15:12:13 -05:00
|
|
|
tapped_formulae << path.resolved_path
|
2013-09-24 19:39:04 +01:00
|
|
|
end
|
|
|
|
unlink_tap_formula(tapped_formulae)
|
|
|
|
|
2012-03-06 02:23:01 +00:00
|
|
|
report = Report.new
|
2014-06-23 18:41:50 -05:00
|
|
|
master_updater = Updater.new(HOMEBREW_REPOSITORY)
|
2013-09-24 19:39:04 +01:00
|
|
|
begin
|
|
|
|
master_updater.pull!
|
|
|
|
ensure
|
|
|
|
link_tap_formula(tapped_formulae)
|
|
|
|
end
|
2014-06-27 21:58:15 -05:00
|
|
|
report.update(master_updater.report)
|
2011-06-12 17:07:59 +02:00
|
|
|
|
2014-04-24 11:26:45 +09:00
|
|
|
# rename Taps directories
|
|
|
|
# this procedure will be removed in the future if it seems unnecessasry
|
|
|
|
rename_taps_dir_if_necessary
|
|
|
|
|
2014-04-25 11:25:38 -05:00
|
|
|
each_tap do |user, repo|
|
|
|
|
repo.cd do
|
2014-06-23 18:41:50 -05:00
|
|
|
updater = Updater.new(repo)
|
2014-04-25 12:34:28 -05:00
|
|
|
|
2014-04-25 11:25:38 -05:00
|
|
|
begin
|
|
|
|
updater.pull!
|
2014-04-25 12:34:28 -05:00
|
|
|
rescue
|
|
|
|
onoe "Failed to update tap: #{user.basename}/#{repo.basename.sub("homebrew-", "")}"
|
|
|
|
else
|
2014-06-27 21:58:15 -05:00
|
|
|
report.update(updater.report) do |key, oldval, newval|
|
2014-04-25 11:25:38 -05:00
|
|
|
oldval.concat(newval)
|
2012-08-01 16:19:25 -04:00
|
|
|
end
|
2012-03-06 02:23:01 +00:00
|
|
|
end
|
2011-06-12 17:07:59 +02:00
|
|
|
end
|
2012-03-06 02:23:01 +00:00
|
|
|
end
|
2012-03-18 01:23:01 +00:00
|
|
|
|
|
|
|
# we unlink first in case the formula has moved to another tap
|
|
|
|
Homebrew.unlink_tap_formula(report.removed_tapped_formula)
|
2012-03-07 22:48:44 +00:00
|
|
|
Homebrew.link_tap_formula(report.new_tapped_formula)
|
2011-06-12 17:07:59 +02:00
|
|
|
|
2013-10-30 11:24:05 -07:00
|
|
|
# automatically tap any migrated formulae's new tap
|
|
|
|
report.select_formula(:D).each do |f|
|
2013-11-01 23:23:08 -07:00
|
|
|
next unless (HOMEBREW_CELLAR/f).exist?
|
2013-11-14 09:25:27 -06:00
|
|
|
migration = TAP_MIGRATIONS[f]
|
|
|
|
next unless migration
|
|
|
|
tap_user, tap_repo = migration.split '/'
|
2014-01-03 21:51:42 +00:00
|
|
|
install_tap tap_user, tap_repo
|
2013-12-02 16:14:43 -06:00
|
|
|
end if load_tap_migrations
|
2013-10-30 11:24:05 -07:00
|
|
|
|
2012-03-06 02:23:01 +00:00
|
|
|
if report.empty?
|
|
|
|
puts "Already up-to-date."
|
|
|
|
else
|
|
|
|
puts "Updated Homebrew from #{master_updater.initial_revision[0,8]} to #{master_updater.current_revision[0,8]}."
|
|
|
|
report.dump
|
|
|
|
end
|
|
|
|
end
|
2011-06-12 17:07:59 +02:00
|
|
|
|
2012-03-06 02:23:01 +00:00
|
|
|
private
|
2011-06-12 17:07:59 +02:00
|
|
|
|
2012-03-06 02:23:01 +00:00
|
|
|
def git_init_if_necessary
|
2014-06-20 18:36:18 -05:00
|
|
|
if Dir[".git/*"].empty?
|
|
|
|
safe_system "git", "init"
|
|
|
|
safe_system "git", "config", "core.autocrlf", "false"
|
|
|
|
safe_system "git", "remote", "add", "origin", "https://github.com/Homebrew/homebrew.git"
|
|
|
|
safe_system "git", "fetch", "origin"
|
|
|
|
safe_system "git", "reset", "--hard", "origin/master"
|
2009-09-08 00:02:28 +02:00
|
|
|
end
|
2013-11-16 20:24:24 +00:00
|
|
|
|
|
|
|
if `git remote show origin -n` =~ /Fetch URL: \S+mxcl\/homebrew/
|
2014-06-20 18:36:18 -05:00
|
|
|
safe_system "git", "remote", "set-url", "origin", "https://github.com/Homebrew/homebrew.git"
|
|
|
|
safe_system "git", "remote", "set-url", "--delete", "origin", ".*mxcl\/homebrew.*"
|
2013-11-16 20:24:24 +00:00
|
|
|
end
|
2012-03-06 02:23:01 +00:00
|
|
|
rescue Exception
|
|
|
|
FileUtils.rm_rf ".git"
|
|
|
|
raise
|
2011-06-12 17:07:59 +02:00
|
|
|
end
|
2010-07-23 17:32:43 -07:00
|
|
|
|
2014-04-24 11:26:45 +09:00
|
|
|
def rename_taps_dir_if_necessary
|
|
|
|
need_repair_taps = false
|
2014-05-31 23:53:36 -05:00
|
|
|
Dir.glob("#{HOMEBREW_LIBRARY}/Taps/*/") do |tapd|
|
2014-04-24 11:26:45 +09:00
|
|
|
begin
|
|
|
|
tapd_basename = File.basename(tapd)
|
|
|
|
|
|
|
|
if File.directory?(tapd + "/.git")
|
|
|
|
if tapd_basename.include?("-")
|
|
|
|
# only replace the *last* dash: yes, tap filenames suck
|
|
|
|
user, repo = tapd_basename.reverse.sub("-", "/").reverse.split("/")
|
|
|
|
|
|
|
|
FileUtils.mkdir_p("#{HOMEBREW_LIBRARY}/Taps/#{user.downcase}")
|
|
|
|
FileUtils.mv(tapd, "#{HOMEBREW_LIBRARY}/Taps/#{user.downcase}/homebrew-#{repo.downcase}")
|
|
|
|
need_repair_taps = true
|
|
|
|
|
|
|
|
if tapd_basename.count("-") >= 2
|
|
|
|
opoo "Homebrew changed the structure of Taps like <someuser>/<sometap>. "\
|
|
|
|
+ "So you may need to rename #{HOMEBREW_LIBRARY}/Taps/#{user.downcase}/homebrew-#{repo.downcase} manually."
|
|
|
|
end
|
|
|
|
else
|
|
|
|
opoo "Homebrew changed the structure of Taps like <someuser>/<sometap>. "\
|
|
|
|
"#{tapd} is incorrect name format. You may need to rename it like <someuser>/<sometap> manually."
|
|
|
|
end
|
|
|
|
end
|
|
|
|
rescue => ex
|
|
|
|
onoe ex.message
|
|
|
|
next # next tap directory
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
repair_taps if need_repair_taps
|
|
|
|
end
|
|
|
|
|
2013-12-02 16:14:43 -06:00
|
|
|
def load_tap_migrations
|
|
|
|
require 'tap_migrations'
|
|
|
|
rescue LoadError
|
|
|
|
false
|
|
|
|
end
|
2012-03-06 02:23:01 +00:00
|
|
|
end
|
2010-07-23 17:32:43 -07:00
|
|
|
|
2012-03-06 02:23:01 +00:00
|
|
|
class Updater
|
2014-06-23 18:41:50 -05:00
|
|
|
attr_reader :initial_revision, :current_revision, :repository
|
|
|
|
|
|
|
|
def initialize(repository)
|
|
|
|
@repository = repository
|
|
|
|
end
|
2010-07-23 17:32:43 -07:00
|
|
|
|
2012-03-06 02:23:01 +00:00
|
|
|
def pull!
|
2014-06-20 18:36:18 -05:00
|
|
|
safe_system "git", "checkout", "-q", "master"
|
2010-02-18 19:24:03 -05:00
|
|
|
|
2012-03-06 02:23:01 +00:00
|
|
|
@initial_revision = read_current_revision
|
2010-02-18 19:24:03 -05:00
|
|
|
|
2012-03-06 02:23:01 +00:00
|
|
|
# ensure we don't munge line endings on checkout
|
2014-06-20 18:36:18 -05:00
|
|
|
safe_system "git", "config", "core.autocrlf", "false"
|
2010-07-23 17:32:43 -07:00
|
|
|
|
2012-03-06 02:23:01 +00:00
|
|
|
args = ["pull"]
|
|
|
|
args << "--rebase" if ARGV.include? "--rebase"
|
|
|
|
args << "-q" unless ARGV.verbose?
|
|
|
|
args << "origin"
|
|
|
|
# the refspec ensures that 'origin/master' gets updated
|
|
|
|
args << "refs/heads/master:refs/remotes/origin/master"
|
|
|
|
|
2013-09-10 15:08:03 -05:00
|
|
|
reset_on_interrupt { safe_system "git", *args }
|
2010-07-23 17:32:43 -07:00
|
|
|
|
2012-03-06 02:23:01 +00:00
|
|
|
@current_revision = read_current_revision
|
2010-07-23 17:32:43 -07:00
|
|
|
end
|
|
|
|
|
2013-09-10 15:08:03 -05:00
|
|
|
def reset_on_interrupt
|
|
|
|
ignore_interrupts { yield }
|
|
|
|
ensure
|
|
|
|
if $?.signaled? && $?.termsig == 2 # SIGINT
|
|
|
|
safe_system "git", "reset", "--hard", @initial_revision
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2010-07-23 17:32:43 -07:00
|
|
|
def report
|
2012-03-06 02:23:01 +00:00
|
|
|
map = Hash.new{ |h,k| h[k] = [] }
|
2011-08-26 13:04:08 +01:00
|
|
|
|
2012-03-06 02:23:01 +00:00
|
|
|
if initial_revision && initial_revision != current_revision
|
2014-07-26 20:11:53 -05:00
|
|
|
diff.each_line do |line|
|
2014-07-26 20:11:53 -05:00
|
|
|
status, *paths = line.split
|
|
|
|
|
|
|
|
next unless File.extname(paths.last) == ".rb"
|
|
|
|
next unless File.dirname(paths.last) == formula_directory
|
|
|
|
|
|
|
|
case status
|
|
|
|
when "A", "M", "D"
|
|
|
|
map[status.to_sym] << repository.join(paths.first)
|
|
|
|
when /^R\d{0,3}/
|
|
|
|
map[:D] << repository.join(paths.first)
|
|
|
|
map[:A] << repository.join(paths.last)
|
|
|
|
end
|
2012-03-06 02:23:01 +00:00
|
|
|
end
|
2011-08-26 13:04:08 +01:00
|
|
|
end
|
|
|
|
|
2012-03-06 02:23:01 +00:00
|
|
|
map
|
2010-07-23 17:32:43 -07:00
|
|
|
end
|
|
|
|
|
2009-09-08 00:02:28 +02:00
|
|
|
private
|
2010-07-23 17:37:03 -07:00
|
|
|
|
2014-07-26 20:11:53 -05:00
|
|
|
def formula_directory
|
|
|
|
if repository == HOMEBREW_REPOSITORY
|
|
|
|
"Library/Formula"
|
|
|
|
elsif repository.join("Formula").directory?
|
|
|
|
"Formula"
|
|
|
|
elsif repository.join("HomebrewFormula").directory?
|
|
|
|
"HomebrewFormula"
|
|
|
|
else
|
|
|
|
"."
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-03-06 02:23:01 +00:00
|
|
|
def read_current_revision
|
2012-03-22 18:22:19 -05:00
|
|
|
`git rev-parse -q --verify HEAD`.chomp
|
2011-06-12 17:07:59 +02:00
|
|
|
end
|
|
|
|
|
2014-07-26 20:11:53 -05:00
|
|
|
def diff
|
2014-07-26 20:11:53 -05:00
|
|
|
Utils.popen_read(
|
|
|
|
"git", "diff-tree", "-r", "--name-status", "--diff-filter=AMDR",
|
|
|
|
"-M85%", initial_revision, current_revision
|
|
|
|
)
|
2014-07-26 20:11:53 -05:00
|
|
|
end
|
|
|
|
|
2012-03-06 02:23:01 +00:00
|
|
|
def `(cmd)
|
2014-06-23 18:50:55 -05:00
|
|
|
out = super
|
2012-03-06 02:23:01 +00:00
|
|
|
if $? && !$?.success?
|
|
|
|
$stderr.puts out
|
|
|
|
raise ErrorDuringExecution, "Failure while executing: #{cmd}"
|
|
|
|
end
|
|
|
|
ohai(cmd, out) if ARGV.verbose?
|
|
|
|
out
|
2011-06-12 17:07:59 +02:00
|
|
|
end
|
2012-03-06 02:23:01 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
2014-06-27 21:58:15 -05:00
|
|
|
class Report
|
|
|
|
def initialize
|
|
|
|
@hash = {}
|
|
|
|
end
|
|
|
|
|
|
|
|
def fetch(*args, &block)
|
|
|
|
@hash.fetch(*args, &block)
|
|
|
|
end
|
|
|
|
|
|
|
|
def update(*args, &block)
|
|
|
|
@hash.update(*args, &block)
|
|
|
|
end
|
|
|
|
|
|
|
|
def empty?
|
|
|
|
@hash.empty?
|
|
|
|
end
|
2011-06-12 17:07:59 +02:00
|
|
|
|
2012-03-06 02:23:01 +00:00
|
|
|
def dump
|
|
|
|
# Key Legend: Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R)
|
|
|
|
|
2012-10-05 13:43:07 -07:00
|
|
|
dump_formula_report :A, "New Formulae"
|
|
|
|
dump_formula_report :M, "Updated Formulae"
|
|
|
|
dump_formula_report :D, "Deleted Formulae"
|
2011-06-12 17:07:59 +02:00
|
|
|
end
|
|
|
|
|
2012-03-18 01:23:01 +00:00
|
|
|
def tapped_formula_for key
|
2014-04-25 15:12:13 -05:00
|
|
|
fetch(key, []).select do |path|
|
2014-05-14 16:43:52 +09:00
|
|
|
case path.to_s
|
|
|
|
when HOMEBREW_TAP_PATH_REGEX
|
|
|
|
valid_formula_location?("#{$1}/#{$2}/#{$3}")
|
2014-04-25 15:12:13 -05:00
|
|
|
else
|
|
|
|
false
|
2012-03-07 22:48:44 +00:00
|
|
|
end
|
|
|
|
end.compact
|
|
|
|
end
|
|
|
|
|
2013-07-08 19:56:43 -05:00
|
|
|
def valid_formula_location?(relative_path)
|
2014-04-24 11:26:45 +09:00
|
|
|
parts = relative_path.split('/')[2..-1]
|
2014-06-27 21:58:15 -05:00
|
|
|
return false unless File.extname(parts.last) == ".rb"
|
|
|
|
case parts.first
|
|
|
|
when "Formula", "HomebrewFormula"
|
|
|
|
parts.length == 2
|
|
|
|
else
|
|
|
|
parts.length == 1
|
|
|
|
end
|
2013-07-08 19:56:43 -05:00
|
|
|
end
|
|
|
|
|
2012-03-18 01:23:01 +00:00
|
|
|
def new_tapped_formula
|
|
|
|
tapped_formula_for :A
|
|
|
|
end
|
|
|
|
|
|
|
|
def removed_tapped_formula
|
|
|
|
tapped_formula_for :D
|
|
|
|
end
|
|
|
|
|
2012-03-06 02:23:01 +00:00
|
|
|
def select_formula key
|
|
|
|
fetch(key, []).map do |path|
|
2014-05-14 16:43:52 +09:00
|
|
|
case path.to_s
|
2014-07-06 11:24:24 -05:00
|
|
|
when %r{^#{Regexp.escape(HOMEBREW_LIBRARY.to_s)}/Formula}o
|
2014-04-25 15:12:13 -05:00
|
|
|
path.basename(".rb").to_s
|
2014-05-14 16:43:52 +09:00
|
|
|
when HOMEBREW_TAP_PATH_REGEX
|
2014-07-06 12:42:08 -05:00
|
|
|
"#{$1}/#{$2.sub("homebrew-", "")}/#{path.basename(".rb")}"
|
2012-03-06 02:23:01 +00:00
|
|
|
end
|
|
|
|
end.compact.sort
|
2011-06-12 17:07:59 +02:00
|
|
|
end
|
|
|
|
|
2012-03-06 02:23:01 +00:00
|
|
|
def dump_formula_report key, title
|
|
|
|
formula = select_formula(key)
|
|
|
|
unless formula.empty?
|
|
|
|
ohai title
|
2013-03-15 09:50:38 -04:00
|
|
|
puts_columns formula.uniq
|
2009-09-11 20:58:41 +02:00
|
|
|
end
|
2009-09-11 20:09:39 +02:00
|
|
|
end
|
2009-09-17 18:40:21 +01:00
|
|
|
end
|