aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew/cmd/update.rb
diff options
context:
space:
mode:
authorMislav Marohnić2011-06-12 17:07:59 +0200
committerAdam Vandenberg2011-06-14 14:47:39 -0700
commit8c521ca3d0d1b1579f8f1ef3f76021217e485613 (patch)
tree413eb0113a65a1e09821002048eb12e5aa429e09 /Library/Homebrew/cmd/update.rb
parent5fdb145e76e41889668e797d81dfd314cf7dd72d (diff)
downloadbrew-8c521ca3d0d1b1579f8f1ef3f76021217e485613.tar.bz2
refactor `update` command to use git diff instead of parsing `pull` output
This fixes reporting of which formulae changed in git versions where `pull` output is not compatible. Signed-off-by: Adam Vandenberg <flangy@gmail.com>
Diffstat (limited to 'Library/Homebrew/cmd/update.rb')
-rw-r--r--Library/Homebrew/cmd/update.rb107
1 files changed, 60 insertions, 47 deletions
diff --git a/Library/Homebrew/cmd/update.rb b/Library/Homebrew/cmd/update.rb
index b5492e9c1..944e7304a 100644
--- a/Library/Homebrew/cmd/update.rb
+++ b/Library/Homebrew/cmd/update.rb
@@ -16,69 +16,71 @@ class RefreshBrew
INIT_COMMAND = "git init"
CHECKOUT_COMMAND = "git checkout -q master"
UPDATE_COMMAND = "git pull #{REPOSITORY_URL} master"
- REVISION_COMMAND = "git log -l -1 --pretty=format:%H 2> /dev/null"
- GIT_UP_TO_DATE = "Already up-to-date."
+ REVISION_COMMAND = "git rev-parse HEAD"
+ DIFF_COMMAND = "git diff-tree -r --name-status -z %s %s"
- formula_regexp = 'Library/Formula/(.+?)\.rb'
- ADDED_FORMULA = %r{^\s+create mode \d+ #{formula_regexp}$}
- UPDATED_FORMULA = %r{^\s+#{formula_regexp}\s}
- DELETED_FORMULA = %r{^\s+delete mode \d+ #{formula_regexp}$}
-
- example_regexp = 'Library/Contributions/examples/([^.\s]+).*'
- ADDED_EXAMPLE = %r{^\s+create mode \d+ #{example_regexp}$}
- UPDATED_EXAMPLE = %r{^\s+#{example_regexp}}
- DELETED_EXAMPLE = %r{^\s+delete mode \d+ #{example_regexp}$}
+ FORMULA_DIR = 'Library/Formula/'
+ EXAMPLE_DIR = 'Library/Contributions/examples/'
attr_reader :added_formulae, :updated_formulae, :deleted_formulae, :installed_formulae
attr_reader :added_examples, :updated_examples, :deleted_examples
- attr_reader :initial_revision
+ attr_reader :initial_revision, :current_revision
def initialize
@added_formulae, @updated_formulae, @deleted_formulae, @installed_formulae = [], [], [], []
@added_examples, @updated_examples, @deleted_examples = [], [], []
- @initial_revision = self.current_revision
+ @initial_revision, @current_revision = nil
end
# Performs an update of the homebrew source. Returns +true+ if a newer
# version was available, +false+ if already up-to-date.
def update_from_masterbrew!
- output = ''
HOMEBREW_REPOSITORY.cd do
- if File.directory? '.git'
+ if git_repo?
safe_system CHECKOUT_COMMAND
+ @initial_revision = read_revision
else
safe_system INIT_COMMAND
end
- output = execute(UPDATE_COMMAND)
+ execute(UPDATE_COMMAND)
+ @current_revision = read_revision
end
- output.split("\n").reverse.each do |line|
- case line
- when ADDED_FORMULA
- @added_formulae << $1
- when DELETED_FORMULA
- @deleted_formulae << $1
- when UPDATED_FORMULA
- @updated_formulae << $1 unless @added_formulae.include?($1) or @deleted_formulae.include?($1)
- when ADDED_EXAMPLE
- @added_examples << $1
- when DELETED_EXAMPLE
- @deleted_examples << $1
- when UPDATED_EXAMPLE
- @updated_examples << $1 unless @added_examples.include?($1) or @deleted_examples.include?($1)
+ 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
+ execute(DIFF_COMMAND % [initial_revision, current_revision]).split("\0")
+ 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)
+ @updated_examples = changed_items('M', EXAMPLE_DIR)
+
+ @installed_formulae = HOMEBREW_CELLAR.children.
+ select{ |pn| pn.directory? }.
+ map{ |pn| pn.basename.to_s }.sort
+
+ return true
end
end
- @added_formulae.sort!
- @updated_formulae.sort!
- @deleted_formulae.sort!
- @added_examples.sort!
- @updated_examples.sort!
- @deleted_examples.sort!
- @installed_formulae = HOMEBREW_CELLAR.children.
- select{ |pn| pn.directory? }.
- map{ |pn| pn.basename.to_s }.sort
+ # assume nothing was updated
+ return false
+ end
- output.strip != GIT_UP_TO_DATE
+ def git_repo?
+ File.directory? '.git'
end
def pending_formulae_changes?
@@ -105,12 +107,6 @@ class RefreshBrew
!@deleted_examples.empty?
end
- def current_revision
- HOMEBREW_REPOSITORY.cd { execute(REVISION_COMMAND).strip }
- rescue
- 'TAIL'
- end
-
def report
puts "Updated Homebrew from #{initial_revision[0,8]} to #{current_revision[0,8]}."
## New Formulae
@@ -151,10 +147,27 @@ class RefreshBrew
private
+ def read_revision
+ execute(REVISION_COMMAND).chomp
+ 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
+
def execute(cmd)
out = `#{cmd}`
if $? && !$?.success?
- puts out
+ $stderr.puts out
raise "Failed while executing #{cmd}"
end
ohai(cmd, out) if ARGV.verbose?