2010-09-11 20:22:54 +01:00
|
|
|
module Homebrew extend self
|
|
|
|
def update
|
|
|
|
abort "Please `brew install git' first." unless system "/usr/bin/which -s git"
|
|
|
|
|
|
|
|
updater = RefreshBrew.new
|
|
|
|
if updater.update_from_masterbrew!
|
|
|
|
updater.report
|
|
|
|
else
|
|
|
|
puts "Already up-to-date."
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2009-09-08 00:02:28 +02:00
|
|
|
class RefreshBrew
|
2011-08-04 13:45:48 +01:00
|
|
|
REPOSITORY_URL = "http://github.com/mxcl/homebrew.git"
|
2011-06-12 17:07:59 +02:00
|
|
|
FORMULA_DIR = 'Library/Formula/'
|
|
|
|
EXAMPLE_DIR = 'Library/Contributions/examples/'
|
2010-07-23 17:32:43 -07:00
|
|
|
|
2011-01-01 00:49:05 +00:00
|
|
|
attr_reader :added_formulae, :updated_formulae, :deleted_formulae, :installed_formulae
|
2011-08-26 13:04:08 +01:00
|
|
|
attr_reader :added_examples, :deleted_examples
|
2011-06-12 17:07:59 +02:00
|
|
|
attr_reader :initial_revision, :current_revision
|
2010-07-23 17:32:43 -07:00
|
|
|
|
2009-09-08 00:02:28 +02:00
|
|
|
def initialize
|
2011-01-01 00:49:05 +00:00
|
|
|
@added_formulae, @updated_formulae, @deleted_formulae, @installed_formulae = [], [], [], []
|
2011-08-26 13:04:08 +01:00
|
|
|
@added_examples, @deleted_examples = [], [], []
|
2011-06-12 17:07:59 +02:00
|
|
|
@initial_revision, @current_revision = nil
|
2009-09-08 00:02:28 +02:00
|
|
|
end
|
2010-07-23 17:32:43 -07:00
|
|
|
|
2009-09-08 00:02:28 +02:00
|
|
|
# Performs an update of the homebrew source. Returns +true+ if a newer
|
2009-09-11 19:17:50 +02:00
|
|
|
# version was available, +false+ if already up-to-date.
|
2009-09-08 00:02:28 +02:00
|
|
|
def update_from_masterbrew!
|
2010-07-23 17:37:03 -07:00
|
|
|
HOMEBREW_REPOSITORY.cd do
|
2011-06-12 17:07:59 +02:00
|
|
|
if git_repo?
|
2011-08-04 13:45:48 +01:00
|
|
|
safe_system "git checkout -q master"
|
2011-06-12 17:07:59 +02:00
|
|
|
@initial_revision = read_revision
|
2011-08-25 01:20:33 +01:00
|
|
|
# originally we fetched by URL but then we decided that we should
|
|
|
|
# use origin so that it's easier for forks to operate seamlessly
|
|
|
|
unless `git remote`.split.include? 'origin'
|
|
|
|
safe_system "git remote add origin #{REPOSITORY_URL}"
|
|
|
|
end
|
2009-11-12 03:55:09 +00:00
|
|
|
else
|
2011-06-15 13:00:13 +01:00
|
|
|
begin
|
|
|
|
safe_system "git init"
|
2011-08-25 01:20:33 +01:00
|
|
|
safe_system "git remote add origin #{REPOSITORY_URL}"
|
|
|
|
safe_system "git fetch origin"
|
2011-08-26 11:25:09 +01:00
|
|
|
safe_system "git reset --hard origin/master"
|
2011-06-15 13:00:13 +01:00
|
|
|
rescue Exception
|
2011-08-04 13:45:48 +01:00
|
|
|
safe_system "/bin/rm -rf .git"
|
2011-06-15 13:00:13 +01:00
|
|
|
raise
|
|
|
|
end
|
2009-11-12 03:55:09 +00:00
|
|
|
end
|
2011-08-30 00:41:51 -05:00
|
|
|
# specify a refspec so that 'origin/master' gets updated
|
|
|
|
execute "git pull origin refs/heads/master:refs/remotes/origin/master"
|
2011-06-12 17:07:59 +02:00
|
|
|
@current_revision = read_revision
|
2009-11-12 03:55:09 +00:00
|
|
|
end
|
|
|
|
|
2011-06-12 17:07:59 +02:00
|
|
|
if initial_revision && initial_revision != current_revision
|
|
|
|
# hash with status characters for keys:
|
|
|
|
# Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R)
|
|
|
|
@changes_map = Hash.new {|h,k| h[k] = [] }
|
|
|
|
|
|
|
|
changes = HOMEBREW_REPOSITORY.cd do
|
2011-08-04 13:45:48 +01:00
|
|
|
execute("git diff-tree -r --name-status -z #{initial_revision} #{current_revision}").split("\0")
|
2011-06-12 17:07:59 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
while status = changes.shift
|
|
|
|
file = changes.shift
|
|
|
|
@changes_map[status] << file
|
|
|
|
end
|
|
|
|
|
|
|
|
if @changes_map.any?
|
|
|
|
@added_formulae = changed_items('A', FORMULA_DIR)
|
|
|
|
@deleted_formulae = changed_items('D', FORMULA_DIR)
|
|
|
|
@updated_formulae = changed_items('M', FORMULA_DIR)
|
|
|
|
@added_examples = changed_items('A', EXAMPLE_DIR)
|
|
|
|
@deleted_examples = changed_items('D', EXAMPLE_DIR)
|
2011-08-26 13:04:08 +01:00
|
|
|
@added_internal_commands = changed_items('A', "Library/Homebrew/cmd")
|
2011-08-31 09:58:30 -05:00
|
|
|
@deleted_internal_commands = changed_items('D', "Library/Homebrew/cmd")
|
2011-06-12 17:07:59 +02:00
|
|
|
|
|
|
|
@installed_formulae = HOMEBREW_CELLAR.children.
|
|
|
|
select{ |pn| pn.directory? }.
|
2011-06-15 13:00:31 +01:00
|
|
|
map{ |pn| pn.basename.to_s }.sort if HOMEBREW_CELLAR.directory?
|
2011-06-12 17:07:59 +02:00
|
|
|
|
|
|
|
return true
|
2009-09-20 17:54:10 +02:00
|
|
|
end
|
2009-09-08 00:02:28 +02:00
|
|
|
end
|
2011-06-12 17:07:59 +02:00
|
|
|
# assume nothing was updated
|
|
|
|
return false
|
|
|
|
end
|
2010-07-23 17:32:43 -07:00
|
|
|
|
2011-06-12 17:07:59 +02:00
|
|
|
def git_repo?
|
2011-07-31 10:32:09 -07:00
|
|
|
Dir['.git/*'].length > 0
|
2009-09-08 00:02:28 +02:00
|
|
|
end
|
2010-07-23 17:32:43 -07:00
|
|
|
|
2009-09-08 00:02:28 +02:00
|
|
|
def pending_formulae_changes?
|
|
|
|
!@updated_formulae.empty?
|
|
|
|
end
|
2010-07-23 17:32:43 -07:00
|
|
|
|
2010-02-18 19:24:03 -05:00
|
|
|
def pending_new_formulae?
|
|
|
|
!@added_formulae.empty?
|
|
|
|
end
|
|
|
|
|
|
|
|
def deleted_formulae?
|
|
|
|
!@deleted_formulae.empty?
|
|
|
|
end
|
|
|
|
|
2010-07-23 17:32:43 -07:00
|
|
|
def pending_examples_changes?
|
|
|
|
!@updated_examples.empty?
|
|
|
|
end
|
|
|
|
|
|
|
|
def pending_new_examples?
|
|
|
|
!@added_examples.empty?
|
|
|
|
end
|
|
|
|
|
|
|
|
def deleted_examples?
|
|
|
|
!@deleted_examples.empty?
|
|
|
|
end
|
|
|
|
|
|
|
|
def report
|
|
|
|
puts "Updated Homebrew from #{initial_revision[0,8]} to #{current_revision[0,8]}."
|
|
|
|
if pending_new_formulae?
|
2011-08-26 13:04:08 +01:00
|
|
|
ohai "New formulae"
|
2010-07-23 17:32:43 -07:00
|
|
|
puts_columns added_formulae
|
|
|
|
end
|
|
|
|
if deleted_formulae?
|
2011-08-26 13:04:08 +01:00
|
|
|
ohai "Removed formulae"
|
2011-01-01 00:49:05 +00:00
|
|
|
puts_columns deleted_formulae, installed_formulae
|
2010-07-23 17:32:43 -07:00
|
|
|
end
|
|
|
|
if pending_formulae_changes?
|
2011-08-26 13:04:08 +01:00
|
|
|
ohai "Updated formulae"
|
2011-01-01 00:49:05 +00:00
|
|
|
puts_columns updated_formulae, installed_formulae
|
2010-07-23 17:32:43 -07:00
|
|
|
end
|
2011-08-26 13:04:08 +01:00
|
|
|
|
|
|
|
unless @added_internal_commands.empty?
|
|
|
|
ohai "New commands"
|
|
|
|
puts_columns @added_internal_commands
|
|
|
|
end
|
|
|
|
unless @deleted_internal_commands.empty?
|
|
|
|
ohai "Removed commands"
|
|
|
|
puts_columns @deleted_internal_commands
|
|
|
|
end
|
|
|
|
|
|
|
|
# external commands aren't generally documented but the distinction
|
|
|
|
# is loose. They are less "supported" and more "playful".
|
2010-07-23 17:32:43 -07:00
|
|
|
if pending_new_examples?
|
2011-08-26 13:04:08 +01:00
|
|
|
ohai "New external commands"
|
2010-07-23 17:32:43 -07:00
|
|
|
puts_columns added_examples
|
|
|
|
end
|
|
|
|
if deleted_examples?
|
2011-08-26 13:04:08 +01:00
|
|
|
ohai "Removed external commands"
|
2010-07-23 17:32:43 -07:00
|
|
|
puts_columns deleted_examples
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2009-09-08 00:02:28 +02:00
|
|
|
private
|
2010-07-23 17:37:03 -07:00
|
|
|
|
2011-06-12 17:07:59 +02:00
|
|
|
def read_revision
|
2011-08-04 13:45:48 +01:00
|
|
|
execute("git rev-parse HEAD").chomp
|
2011-06-12 17:07:59 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
def filter_by_directory(files, dir)
|
|
|
|
files.select { |f| f.index(dir) == 0 }
|
|
|
|
end
|
|
|
|
|
|
|
|
def basenames(files)
|
|
|
|
files.map { |f| File.basename(f, '.rb') }
|
|
|
|
end
|
|
|
|
|
|
|
|
# extracts items by status from @changes_map
|
|
|
|
def changed_items(status, dir)
|
|
|
|
basenames(filter_by_directory(@changes_map[status], dir)).sort
|
|
|
|
end
|
|
|
|
|
2009-09-11 20:09:39 +02:00
|
|
|
def execute(cmd)
|
|
|
|
out = `#{cmd}`
|
2010-05-08 15:35:06 +10:00
|
|
|
if $? && !$?.success?
|
2011-06-12 17:07:59 +02:00
|
|
|
$stderr.puts out
|
2009-09-20 17:54:10 +02:00
|
|
|
raise "Failed while executing #{cmd}"
|
2009-09-11 20:58:41 +02:00
|
|
|
end
|
2009-09-17 18:26:31 +01:00
|
|
|
ohai(cmd, out) if ARGV.verbose?
|
2009-09-11 20:09:39 +02:00
|
|
|
out
|
|
|
|
end
|
2009-09-17 18:40:21 +01:00
|
|
|
end
|