aboutsummaryrefslogtreecommitdiffstats
path: root/Library
diff options
context:
space:
mode:
authorMax Howell2012-03-06 02:23:01 +0000
committerMax Howell2012-03-16 21:06:16 +0000
commit2e86a41e6162caec5c6922b04746c45c2686a5b1 (patch)
tree3034b2185534724502c54b4753a66e1cb699ae1a /Library
parent31188c7df34a355bc761b5ff83023192b358a5f3 (diff)
downloadhomebrew-2e86a41e6162caec5c6922b04746c45c2686a5b1.tar.bz2
`brew update` will update taps
Diffstat (limited to 'Library')
-rw-r--r--Library/Homebrew/cmd/update.rb244
1 files changed, 95 insertions, 149 deletions
diff --git a/Library/Homebrew/cmd/update.rb b/Library/Homebrew/cmd/update.rb
index 7e4157a03..3d7713784 100644
--- a/Library/Homebrew/cmd/update.rb
+++ b/Library/Homebrew/cmd/update.rb
@@ -1,192 +1,138 @@
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
-
-class RefreshBrew
- REPOSITORY_URL = "https://github.com/mxcl/homebrew.git"
- FORMULA_DIR = 'Library/Formula/'
- EXAMPLE_DIR = 'Library/Contributions/examples/'
-
- attr_reader :added_formulae, :updated_formulae, :deleted_formulae, :installed_formulae
- attr_reader :added_examples, :deleted_examples
- attr_reader :initial_revision, :current_revision
-
- def initialize
- @added_formulae, @updated_formulae, @deleted_formulae, @installed_formulae = [], [], [], []
- @added_examples, @deleted_examples = [], [], []
- @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!
# ensure GIT_CONFIG is unset as we need to operate on .git/config
ENV.delete('GIT_CONFIG')
- HOMEBREW_REPOSITORY.cd do
- if git_repo?
- safe_system "git checkout -q master"
- @initial_revision = read_revision
- # 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
- else
- begin
- safe_system "git init"
- safe_system "git config core.autocrlf false"
- safe_system "git remote add origin #{REPOSITORY_URL}"
- safe_system "git fetch origin"
- safe_system "git reset --hard origin/master"
- rescue Exception
- safe_system "/bin/rm -rf .git"
- raise
- end
- end
+ cd HOMEBREW_REPOSITORY
+ git_init_if_necessary
- # ensure we don't munge line endings on checkout
- safe_system "git config core.autocrlf false"
- # specify a refspec so that 'origin/master' gets updated
- refspec = "refs/heads/master:refs/remotes/origin/master"
- rebase = "--rebase" if ARGV.include? "--rebase"
- execute "git pull #{rebase} origin #{refspec}"
- @current_revision = read_revision
- end
-
- 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("git diff-tree -r --name-status -z #{initial_revision} #{current_revision}").split("\0")
- end
+ report = Report.new
+ master_updater = Updater.new
+ master_updater.pull!
+ report.merge!(master_updater.report)
- while status = changes.shift
- file = changes.shift
- @changes_map[status] << file
+ Dir["Library/Taps/*"].each do |tapd|
+ cd tapd do
+ updater = Updater.new
+ updater.pull!
+ report.merge!(updater.report) do |key, oldval, newval|
+ oldval.concat(newval)
+ end
end
+ 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)
- @added_internal_commands = changed_items('A', "Library/Homebrew/cmd")
- @deleted_internal_commands = changed_items('D', "Library/Homebrew/cmd")
+ 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
- @installed_formulae = HOMEBREW_CELLAR.children.
- select{ |pn| pn.directory? }.
- map{ |pn| pn.basename.to_s }.sort if HOMEBREW_CELLAR.directory?
+ private
- return true
- end
+ def git_init_if_necessary
+ if Dir['.git/*'].empty?
+ safe_system "git init"
+ safe_system "git config core.autocrlf false"
+ safe_system "git remote add origin https://github.com/mxcl/homebrew.git"
+ safe_system "git fetch origin"
+ safe_system "git reset --hard origin/master"
end
- # assume nothing was updated
- return false
+ rescue Exception
+ FileUtils.rm_rf ".git"
+ raise
end
- def git_repo?
- Dir['.git/*'].length > 0
- end
+end
- def pending_formulae_changes?
- !@updated_formulae.empty?
- end
+class Updater
+ attr_reader :initial_revision, :current_revision
- def pending_new_formulae?
- !@added_formulae.empty?
- end
+ def pull!
+ safe_system "git checkout -q master"
- def deleted_formulae?
- !@deleted_formulae.empty?
- end
+ @initial_revision = read_current_revision
- def pending_examples_changes?
- !@updated_examples.empty?
- end
+ # ensure we don't munge line endings on checkout
+ safe_system "git config core.autocrlf false"
- def pending_new_examples?
- !@added_examples.empty?
- end
+ 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"
+
+ safe_system "git", *args
- def deleted_examples?
- !@deleted_examples.empty?
+ @current_revision = read_current_revision
end
def report
- puts "Updated Homebrew from #{initial_revision[0,8]} to #{current_revision[0,8]}."
- if pending_new_formulae?
- ohai "New formulae"
- puts_columns added_formulae
- end
- if deleted_formulae?
- ohai "Removed formulae"
- puts_columns deleted_formulae, installed_formulae
- end
- if pending_formulae_changes?
- ohai "Updated formulae"
- puts_columns updated_formulae, installed_formulae
- end
+ map = Hash.new{ |h,k| h[k] = [] }
- 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
+ if initial_revision && initial_revision != current_revision
+ changes = `git diff-tree -r --name-status -z #{initial_revision} #{current_revision}`.split("\0")
+ changes.each_slice(2) do |status, file|
+ file = Pathname.pwd.join(file).relative_path_from(HOMEBREW_REPOSITORY)
+ map[status.to_sym] << file.to_s
+ end
end
- # external commands aren't generally documented but the distinction
- # is loose. They are less "supported" and more "playful".
- if pending_new_examples?
- ohai "New external commands"
- puts_columns added_examples
- end
- if deleted_examples?
- ohai "Removed external commands"
- puts_columns deleted_examples
- end
+ map
end
private
- def read_revision
- execute("git rev-parse HEAD").chomp
+ def read_current_revision
+ `git rev-parse HEAD`.chomp
end
- def filter_by_directory(files, dir)
- files.select { |f| f.index(dir) == 0 }
+ def `(cmd)
+ out = Kernel.`(cmd) #`
+ if $? && !$?.success?
+ $stderr.puts out
+ raise ErrorDuringExecution, "Failure while executing: #{cmd}"
+ end
+ ohai(cmd, out) if ARGV.verbose?
+ out
end
+end
+
+
+class Report < Hash
- def basenames(files)
- files.map { |f| File.basename(f, '.rb') }
+ def dump
+ # Key Legend: Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R)
+
+ dump_formula_report :A, "New Formula"
+ dump_formula_report :M, "Updated Formula"
+ dump_formula_report :D, "Deleted Formula"
+ dump_formula_report :R, "Renamed Formula"
+# dump_new_commands
+# dump_deleted_commands
end
- # extracts items by status from @changes_map
- def changed_items(status, dir)
- basenames(filter_by_directory(@changes_map[status], dir)).sort
+ def select_formula key
+ fetch(key, []).map do |path|
+ case path when %r{^Library/Formula}
+ File.basename(path, ".rb")
+ when %r{^Library/Taps/(\w+)-(\w+)/(.*)}
+ "#$1/#$2/#{File.basename(path, '.rb')}"
+ end
+ end.compact.sort
end
- def execute(cmd)
- out = `#{cmd}`
- if $? && !$?.success?
- $stderr.puts out
- raise "Failed while executing #{cmd}"
+ def dump_formula_report key, title
+ formula = select_formula(key)
+ unless formula.empty?
+ ohai title
+ puts_columns formula
end
- ohai(cmd, out) if ARGV.verbose?
- out
end
+
end