1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
require 'cmd/tap'
module Homebrew extend self
def update
abort "Please `brew install git' first." unless system "/usr/bin/which -s git"
# ensure GIT_CONFIG is unset as we need to operate on .git/config
ENV.delete('GIT_CONFIG')
cd HOMEBREW_REPOSITORY
git_init_if_necessary
report = Report.new
master_updater = Updater.new
master_updater.pull!
report.merge!(master_updater.report)
new_files = []
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
Homebrew.link_tap_formula(report.new_tapped_formula)
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
private
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
rescue Exception
FileUtils.rm_rf ".git"
raise
end
end
class Updater
attr_reader :initial_revision, :current_revision
def pull!
safe_system "git checkout -q master"
@initial_revision = read_current_revision
# ensure we don't munge line endings on checkout
safe_system "git config core.autocrlf false"
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
@current_revision = read_current_revision
end
def report
map = Hash.new{ |h,k| h[k] = [] }
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
map
end
private
def read_current_revision
`git rev-parse HEAD`.chomp
end
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 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
def new_tapped_formula
fetch(:A, []).map do |path|
case path when %r{^Library/Taps(/\w+-\w+/.*)}
Pathname.new($1)
end
end.compact
end
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 dump_formula_report key, title
formula = select_formula(key)
unless formula.empty?
ohai title
puts_columns formula
end
end
end
|