Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100755 336 lines (289 sloc) 9.885 kb
84c5c3e @mxcl The core tree, and some formulae
mxcl authored
1 #!/usr/bin/ruby
b539e96 @bmaland Sort the output from `brew install`
bmaland authored
2 # -*- coding: utf-8 -*-
725a699 @imbriaco Fix brew if it's symlinked from elsewhere
imbriaco authored
3
7be9788 @mxcl Don't look broken if CWD doesn't exist
mxcl authored
4 # Many Pathname operations use getwd when they shouldn't, and then throw
5 # odd exceptions. Reduce our support burden by showing a user-friendly error.
6 Dir.getwd rescue abort "The current working directory doesn't exist, cannot proceed."
7
d81a8e6 @mxcl Simplify the library path determination code a little
mxcl authored
8 HOMEBREW_BREW_FILE = ENV['HOMEBREW_BREW_FILE'] = File.expand_path(__FILE__)
ce01313 @adamv Rewrite of HOMEBREW_ folder locations
adamv authored
9
d81a8e6 @mxcl Simplify the library path determination code a little
mxcl authored
10 require 'pathname'
b5d132e @mxcl We can't rely on the $: order
mxcl authored
11 HOMEBREW_LIBRARY_PATH = (Pathname.new(__FILE__).realpath.dirname.parent+"Library"+"Homebrew").to_s
12 $:.unshift(HOMEBREW_LIBRARY_PATH)
2b22c47 @mxcl Allow formulae to use __END__
mxcl authored
13 require 'global'
6b6d369 @mxcl Refactor
mxcl authored
14
629c4e3 @mxcl Handle certain ARGV parameters before certain error checks
mxcl authored
15 case ARGV.first
16 when '--cache'
17 puts HOMEBREW_CACHE
18 exit 0
246f44d @adamv Also allow 'brew help'.
adamv authored
19 when '-h', '--help', '--usage', '-?', 'help', nil
629c4e3 @mxcl Handle certain ARGV parameters before certain error checks
mxcl authored
20 puts ARGV.usage
21 exit 0
22 when '--version'
23 puts HOMEBREW_VERSION
24 exit 0
25 when '-v'
26 if ARGV.length > 1
27 puts "Homebrew #{HOMEBREW_VERSION}"
28 # continue in verbose mode
29 ARGV << ARGV.shift
30 else
31 puts HOMEBREW_VERSION
32 exit 0
33 end
34 end
35
36 case HOMEBREW_PREFIX.to_s when '/', '/usr'
37 # it may work, but I only see pain this route and don't want to support it
38 abort "Cowardly refusing to continue at this prefix: #{HOMEBREW_PREFIX}"
d614113 @mxcl Refactor Formulae
mxcl authored
39 end
deeb33a @mxcl Use MACOS_VERSION in bin/brew
mxcl authored
40 if MACOS_VERSION < 10.5
725a699 @imbriaco Fix brew if it's symlinked from elsewhere
imbriaco authored
41 abort "Homebrew requires Leopard or higher, but you could fork it and fix that..."
ed1fed4 @mxcl Error out if the host OS X is too old
mxcl authored
42 end
68108e1 @mxcl Dependency resolution with fancy syntax
mxcl authored
43
ce01313 @adamv Rewrite of HOMEBREW_ folder locations
adamv authored
44 def dump_config
de1ebbe @adamv Add OS X, Ruby, compiler & hardware info to --config
adamv authored
45 require 'hardware'
ef39ada @adamv Move some helper functions into Hardware
adamv authored
46 bits = Hardware.bits
47 cores = Hardware.cores_as_words
709dcb9 @mxcl My idea of tidy, sorry Adam…
mxcl authored
48 llvm = llvm_build
7ced6aa @mxcl `brew --config` output improved if no GCC
mxcl authored
49 gcc = gcc_build
fb9c8cc @mxcl cd HOMEBREW_REPOSITORY before trying to git info it
mxcl authored
50 sha = `cd #{HOMEBREW_REPOSITORY} && git rev-parse --verify HEAD 2> /dev/null`.chomp
c078840 @mxcl Show kernel architecture in brew --config output
mxcl authored
51 kernel_arch = `uname -m`.chomp
ce01313 @adamv Rewrite of HOMEBREW_ folder locations
adamv authored
52
de1ebbe @adamv Add OS X, Ruby, compiler & hardware info to --config
adamv authored
53 puts <<-EOS
54 HOMEBREW_VERSION: #{HOMEBREW_VERSION}
0c550e1 @mxcl Include HEAD SHA with brew --config
mxcl authored
55 HEAD: #{sha}
709dcb9 @mxcl My idea of tidy, sorry Adam…
mxcl authored
56 HOMEBREW_PREFIX: #{HOMEBREW_PREFIX}
57 HOMEBREW_CELLAR: #{HOMEBREW_CELLAR}
58 HOMEBREW_CACHE: #{HOMEBREW_CACHE}
ce01313 @adamv Rewrite of HOMEBREW_ folder locations
adamv authored
59 HOMEBREW_REPOSITORY: #{HOMEBREW_REPOSITORY}
b5d132e @mxcl We can't rely on the $: order
mxcl authored
60 HOMEBREW_LIBRARY_PATH: #{HOMEBREW_LIBRARY_PATH}
709dcb9 @mxcl My idea of tidy, sorry Adam…
mxcl authored
61 Hardware: #{cores}-core #{bits}-bit #{Hardware.intel_family}
de1ebbe @adamv Add OS X, Ruby, compiler & hardware info to --config
adamv authored
62 OS X: #{MACOS_FULL_VERSION}
c078840 @mxcl Show kernel architecture in brew --config output
mxcl authored
63 Kernel Architecture: #{kernel_arch}
de1ebbe @adamv Add OS X, Ruby, compiler & hardware info to --config
adamv authored
64 Ruby: #{RUBY_VERSION}-#{RUBY_PATCHLEVEL}
7ced6aa @mxcl `brew --config` output improved if no GCC
mxcl authored
65 GCC-4.2: #{gcc ? "build #{gcc}" : "N/A"}
709dcb9 @mxcl My idea of tidy, sorry Adam…
mxcl authored
66 LLVM: #{llvm ? "build #{llvm}" : "N/A" }
a905313 @mxcl Include macports or fink info with brew --config
mxcl authored
67 MacPorts or Fink? #{macports_or_fink_installed?}
ce01313 @adamv Rewrite of HOMEBREW_ folder locations
adamv authored
68 EOS
69 end
70
d614113 @mxcl Refactor Formulae
mxcl authored
71 begin
629c4e3 @mxcl Handle certain ARGV parameters before certain error checks
mxcl authored
72 require 'brew.h'
73
72edfbf @mxcl brew install improvements
mxcl authored
74 case arg = ARGV.shift
629c4e3 @mxcl Handle certain ARGV parameters before certain error checks
mxcl authored
75 when '--prefix'
76 puts HOMEBREW_PREFIX
ce01313 @adamv Rewrite of HOMEBREW_ folder locations
adamv authored
77 when '--config'
78 dump_config
3cf1226 @mxcl Refactor--object orientate where sensible
mxcl authored
79
df793f7 @adamv brew home foo open's foo's homepage in default web-browser
adamv authored
80 when 'home', 'homepage'
39b392d @mxcl Don't throw if named.empty?
mxcl authored
81 if ARGV.named.empty?
6b6d369 @mxcl Refactor
mxcl authored
82 exec "open", HOMEBREW_WWW
83 else
84 exec "open", *ARGV.formulae.collect {|f| f.homepage}
85 end
df793f7 @adamv brew home foo open's foo's homepage in default web-browser
adamv authored
86
3cf1226 @mxcl Refactor--object orientate where sensible
mxcl authored
87 when 'ls', 'list'
61b3aea brew list --unbrewed
Kieran Pilkington authored
88 if ARGV.flag? '--unbrewed'
a18bc0f @mxcl brew list --unbrewed fix
mxcl authored
89 dirs = HOMEBREW_PREFIX.children.select { |pn| pn.directory? }.collect { |pn| pn.basename.to_s }
90 dirs -= ['Library', 'Cellar', '.git']
91 Dir.chdir HOMEBREW_PREFIX
92 exec 'find', *dirs + %w[-type f ( ! -iname .ds_store ! -iname brew )]
39b392d @mxcl Don't throw if named.empty?
mxcl authored
93 elsif ARGV.named.empty?
e3cd5d6 @mxcl brew ls with no further ARGV lists all installed kegs
mxcl authored
94 ENV['CLICOLOR']=nil
87d770d @mxcl Fixes #78
mxcl authored
95 exec 'ls', *ARGV.options<<HOMEBREW_CELLAR if HOMEBREW_CELLAR.exist?
36aacf7 @mxcl Don't summarize brew list if piped to another command
mxcl authored
96 elsif ARGV.verbose? or not $stdout.tty?
e3cd5d6 @mxcl brew ls with no further ARGV lists all installed kegs
mxcl authored
97 exec "find", *ARGV.kegs+%w[-not -type d -print]
e698609 @mxcl Summarised listings with brew list
mxcl authored
98 else
99 ARGV.kegs.each { |keg| PrettyListing.new keg }
e3cd5d6 @mxcl brew ls with no further ARGV lists all installed kegs
mxcl authored
100 end
3cf1226 @mxcl Refactor--object orientate where sensible
mxcl authored
101
c853b5f @indirect `brew search' command
indirect authored
102 when 'search', '-S'
d9820d9 @mxcl Prompt user to use pip for Hg and Bzr
mxcl authored
103 check_for_blacklisted_formula(ARGV.named)
104
84024e6 @adamv Add alias support to formulae
adamv authored
105 require "formula"
106 formulae = Formulary.names with_aliases=true
107
d8ad9ac @indirect Search by substring unless term is inside /../
indirect authored
108 if ARGV.first =~ /^\/(.*)\/$/
109 puts_columns formulae.grep(Regexp.new($1))
110 else
111 puts_columns formulae.grep(/.*#{ARGV.first}.*/)
112 end
c853b5f @indirect `brew search' command
indirect authored
113
7dfe55d @mxcl brew edit and brew macports commmands
mxcl authored
114 when 'edit'
39b392d @mxcl Don't throw if named.empty?
mxcl authored
115 if ARGV.named.empty?
e23a612 @scoates Use ENV[EDITOR] if possible
scoates authored
116 # EDITOR isn't a good fit here, we need a GUI client that actually has
117 # a UI for projects, so apologies if this wasn't what you expected,
118 # please improve it! :)
ce01313 @adamv Rewrite of HOMEBREW_ folder locations
adamv authored
119 exec 'mate', *Dir["#{HOMEBREW_REPOSITORY}/Library/*"]<<
120 "#{HOMEBREW_REPOSITORY}/bin/brew"<<
121 "#{HOMEBREW_REPOSITORY}/README.md"
8f3ff69 @adamv Fix when 'edit' if/else indentation
adamv authored
122 else
123 # we don't use ARGV.formulae as that will throw if the file doesn't parse
124 paths = ARGV.named.collect do |name|
125 unless File.exist? path = "#{HOMEBREW_REPOSITORY}/Library/Formula/#{name}.rb"
126 require 'formula'
127 raise FormulaUnavailableError, name
128 else
129 path
130 end
8e676a3 @mxcl brew edit works if the file in question won't parse
mxcl authored
131 end
8f3ff69 @adamv Fix when 'edit' if/else indentation
adamv authored
132 exec_editor *paths
7dfe55d @mxcl brew edit and brew macports commmands
mxcl authored
133 end
134
b2fd885 @mxcl Brew update will git init if required
mxcl authored
135 when 'up', 'update'
136 if system "/usr/bin/which -s git"
460ecea @mxcl Rename refresh_brew.rb to update.rb
mxcl authored
137 require 'update'
871b25c @alloy Update Homebrew and list the updated formulae.
alloy authored
138 updater = RefreshBrew.new
5092d7b @alloy Made the output of updating a bit nicer and log more if --verbose.
alloy authored
139 old_revision = updater.current_revision
871b25c @alloy Update Homebrew and list the updated formulae.
alloy authored
140 unless updater.update_from_masterbrew!
35b0b61 @mxcl Remove some ohai() use
mxcl authored
141 puts "Already up-to-date."
871b25c @alloy Update Homebrew and list the updated formulae.
alloy authored
142 else
0c48248 @alloy Only show the first 8 characters of the commit hashes.
alloy authored
143 puts "Updated Homebrew from #{old_revision[0,8]} to #{updater.current_revision[0,8]}."
0fa5dc0 @alloy Don't print that there are _and_ aren't formulae updates.
alloy authored
144 if updater.pending_formulae_changes?
35b0b61 @mxcl Remove some ohai() use
mxcl authored
145 ohai "The following formulae were updated:"
146 puts_columns updater.updated_formulae
0fa5dc0 @alloy Don't print that there are _and_ aren't formulae updates.
alloy authored
147 else
35b0b61 @mxcl Remove some ohai() use
mxcl authored
148 puts "No formulae were updated." unless updater.pending_formulae_changes?
0fa5dc0 @alloy Don't print that there are _and_ aren't formulae updates.
alloy authored
149 end
871b25c @alloy Update Homebrew and list the updated formulae.
alloy authored
150 end
b2fd885 @mxcl Brew update will git init if required
mxcl authored
151 else
152 abort "Please `brew install git' first."
153 end
871b25c @alloy Update Homebrew and list the updated formulae.
alloy authored
154
3cf1226 @mxcl Refactor--object orientate where sensible
mxcl authored
155 when 'ln', 'link'
6b6d369 @mxcl Refactor
mxcl authored
156 ARGV.kegs.each {|keg| puts "#{keg.link} links created for #{keg}"}
157
158 when 'unlink'
159 ARGV.kegs.each {|keg| puts "#{keg.unlink} links removed for #{keg}"}
cc611b1 @mxcl Fix typos
mxcl authored
160
6b6d369 @mxcl Refactor
mxcl authored
161 when 'rm', 'uninstall', 'remove'
162 ARGV.kegs.each do |keg|
163 puts "Uninstalling #{keg}..."
bc9ab14 @mxcl Faster uninstall
mxcl authored
164 keg.unlink
d83fe25 @mxcl Unlink before uninstalling
mxcl authored
165 keg.uninstall
3cf1226 @mxcl Refactor--object orientate where sensible
mxcl authored
166 end
6b6d369 @mxcl Refactor
mxcl authored
167
3cf1226 @mxcl Refactor--object orientate where sensible
mxcl authored
168 when 'prune'
6b6d369 @mxcl Refactor
mxcl authored
169 prune
3cf1226 @mxcl Refactor--object orientate where sensible
mxcl authored
170
f414bc8 @mxcl `brew make' becomes `brew create'
mxcl authored
171 # 'make' supported until 0.7 for historic reasons
3cf1226 @mxcl Refactor--object orientate where sensible
mxcl authored
172 when 'mk', 'make'
f414bc8 @mxcl `brew make' becomes `brew create'
mxcl authored
173 opoo "`brew make' has changed to `brew create'"
174 puts "This is because make can be confused with the `make' tool."
175 puts "brew make will continue working until Homebrew 0.7"
176 exec __FILE__, "create", *ARGV
177
178 when 'create'
6b6d369 @mxcl Refactor
mxcl authored
179 if ARGV.include? '--macports'
180 exec "open", "http://www.macports.org/ports.php?by=name&substr=#{ARGV.next}"
39b392d @mxcl Don't throw if named.empty?
mxcl authored
181 elsif ARGV.named.empty?
182 raise UsageError
616ab25 @mxcl With brew mk, open with mate if available
mxcl authored
183 else
ecf4d95 @mxcl Only create named arguments
mxcl authored
184 exec_editor *ARGV.named.collect {|name| make name}
616ab25 @mxcl With brew mk, open with mate if available
mxcl authored
185 end
186
50453ee @mxcl Allow configure alias for diy
mxcl authored
187 when 'diy', 'configure'
bfbcdb2 @mxcl brew diy command
mxcl authored
188 puts diy
189
3cf1226 @mxcl Refactor--object orientate where sensible
mxcl authored
190 when 'info', 'abv'
39b392d @mxcl Don't throw if named.empty?
mxcl authored
191 if ARGV.named.empty?
c1d91ef @adamv Add command 'brew info --all'.
adamv authored
192 if ARGV.include? "--all"
193 require 'formula'
194 Formulary.names.each do |name|
195 info name
196 puts '---'
197 end
198 else
199 puts `ls #{HOMEBREW_CELLAR} | wc -l`.strip+" kegs, "+HOMEBREW_CELLAR.abv
200 end
3cf1226 @mxcl Refactor--object orientate where sensible
mxcl authored
201 elsif ARGV[0][0..6] == 'http://'
202 puts Pathname.new(ARGV.shift).version
23f9fad @mxcl brew info provides installation status
mxcl authored
203 else
6b6d369 @mxcl Refactor
mxcl authored
204 ARGV.named.each {|name| info name}
dac062e @mxcl Handle -- args properly
mxcl authored
205 end
3cf1226 @mxcl Refactor--object orientate where sensible
mxcl authored
206
72edfbf @mxcl brew install improvements
mxcl authored
207 when 'install'
d9820d9 @mxcl Prompt user to use pip for Hg and Bzr
mxcl authored
208 check_for_blacklisted_formula(ARGV.named)
209
72edfbf @mxcl brew install improvements
mxcl authored
210 require 'formula_installer'
f4670bd @mxcl Don't require hardware.rb globally
mxcl authored
211 require 'hardware'
72edfbf @mxcl brew install improvements
mxcl authored
212
213 ############################################################ sanity checks
214 case Hardware.cpu_type when :ppc, :dunno
215 abort "Sorry, Homebrew does not support your computer's CPU architecture."
216 end
217
0a19a05 @mxcl Don't error out before Cellar is created
mxcl authored
218 raise "Cannot write to #{HOMEBREW_CELLAR}" if HOMEBREW_CELLAR.exist? and not HOMEBREW_CELLAR.writable?
72edfbf @mxcl brew install improvements
mxcl authored
219 raise "Cannot write to #{HOMEBREW_PREFIX}" unless HOMEBREW_PREFIX.writable?
220
221 ################################################################# warnings
222 if MACOS_VERSION >= 10.6
b43dbfa @mxcl DRY gcc_build and llvm_build
mxcl authored
223 opoo "You should upgrade to Xcode 3.2.1" if llvm_build < 2206
bc32b13 @mxcl Warn users about Xcode versions that are too old
mxcl authored
224 else
394e4fd @adamv Be specific about 3.1 point release.
adamv authored
225 opoo "You should upgrade to Xcode 3.1.4" if gcc_build < 5577
72edfbf @mxcl brew install improvements
mxcl authored
226 end
227
228 if macports_or_fink_installed?
229 opoo "It appears you have Macports or Fink installed"
230 puts "Although, unlikely, this can break builds or cause obscure runtime issues."
231 puts "If you experience problems try uninstalling these tools."
232 end
233
234 ################################################################# install!
235 installer = FormulaInstaller.new
236 installer.install_deps = !ARGV.include?('--ignore-dependencies')
237
238 ARGV.formulae.each do |f|
239 if not f.installed? or ARGV.force?
240 installer.install f
241 else
242 puts "Formula already installed: #{f.prefix}"
243 end
244 end
245
f2a6979 @mxcl brew log command
mxcl authored
246 when 'log'
a772101 @mxcl Use HOMEBREW_REPOSITORY for brew log
mxcl authored
247 Dir.chdir HOMEBREW_REPOSITORY
f2a6979 @mxcl brew log command
mxcl authored
248 exec "git", "log", ARGV.formulae.first.path, *ARGV.options
62cef23 @adamv Add brew command 'uses'
adamv authored
249
250 when 'uses'
251 # For each formula given, show which other formulas depend on it.
252 # We only go one level up, direct dependencies.
253 require 'formula'
254 require 'utils'
255
256 deps = Formula.get_used_by
257
258 ARGV.formulae.each do |f|
259 name = f.name
260 our_deps = deps[name]
261 if our_deps == nil
262 puts "#{name} is not a dependency."
263 else
264 puts "#{name} is a dependency for #{our_deps.join(', ')}."
265 end
266 end
b6ca4dc @adamv New command 'brew deps [formula]'
adamv authored
267
268 when 'deps'
269 require 'formula'
270
271 ARGV.formulae.each do |f|
272 name = f.name
273
274 our_deps = []
275 checked = {}
276 to_check = [name]
277
5e56502 @adamv Some small style reformats
adamv authored
278 until to_check.empty?
b6ca4dc @adamv New command 'brew deps [formula]'
adamv authored
279 item = to_check.pop
280 checked[item] = true
281
282 formula = Formulary.read item
283 next if formula == nil || formula.deps == nil || formula.deps.empty?
284
285 our_deps.push(*formula.deps)
286 to_check.push(*formula.deps.select{|g| !checked[g]})
287 end
288
289 if our_deps.empty?
290 puts "#{name} has no dependencies."
291 else
292 our_deps.sort!
293 puts "#{name} depends on #{our_deps.join(", ")}"
294 end
295 end
f2a6979 @mxcl brew log command
mxcl authored
296
8a7b9ea @adamv Add extra message for unknown commands that are git commands.
adamv authored
297 when 'pull', 'push', 'checkout', 'branch'
298 onoe "Unknown command: #{arg} (did you mean 'git #{arg}'?)"
299
f2a6979 @mxcl brew log command
mxcl authored
300 else
178d31b @mxcl Better error for unknown brew commands
mxcl authored
301 onoe "Unknown command: #{arg}"
d614113 @mxcl Refactor Formulae
mxcl authored
302 end
2a5a754 @mxcl brew prefix command
mxcl authored
303
1b066d7 @mxcl Better errors if missing keg or formula arguments
mxcl authored
304 rescue FormulaUnspecifiedError
a785a5e @mxcl dump_config for certain exceptions
mxcl authored
305 abort "This command requires a formula argument"
1b066d7 @mxcl Better errors if missing keg or formula arguments
mxcl authored
306 rescue KegUnspecifiedError
a785a5e @mxcl dump_config for certain exceptions
mxcl authored
307 abort "This command requires a keg argument"
ea7c891 @mxcl Raise if ARGV.named and no named arguments
mxcl authored
308 rescue UsageError
309 onoe "Invalid usage"
a785a5e @mxcl dump_config for certain exceptions
mxcl authored
310 abort ARGV.usage
6b6d369 @mxcl Refactor
mxcl authored
311 rescue SystemExit
f0eb547 @mxcl Fixed SIGINT handling, so we can have our newline
mxcl authored
312 puts "Kernel.exit" if ARGV.verbose?
1912cbb @mxcl Re-raise SystemExit so the correct exit code is set
mxcl authored
313 raise
6b6d369 @mxcl Refactor
mxcl authored
314 rescue Interrupt => e
f0eb547 @mxcl Fixed SIGINT handling, so we can have our newline
mxcl authored
315 puts # seemingly a newline is typical
6b6d369 @mxcl Refactor
mxcl authored
316 exit 130
70bed07 @mxcl More tweaking of main exception handler output
mxcl authored
317 rescue BuildError => e
5bae3b5 @mxcl Puts URL for failed build line
mxcl authored
318 e.backtrace[1] =~ %r{Library/Formula/(.+)\.rb:(\d+)}
319 puts "http://github.com/mxcl/homebrew/blob/master/Library/Formula/#{$1}.rb#L#{$2}"
70bed07 @mxcl More tweaking of main exception handler output
mxcl authored
320 ohai "Environment"
321 dump_config
a997d2c @mxcl Show exit status properly
mxcl authored
322 puts "Exit status: #{e.status.exitstatus}"
70bed07 @mxcl More tweaking of main exception handler output
mxcl authored
323 onoe e
324 puts PLEASE_REPORT_BUG
325 exit 1
326 rescue RuntimeError, SystemCallError => e
327 onoe e
328 puts e.backtrace if ARGV.debug?
329 exit 1
6b6d369 @mxcl Refactor
mxcl authored
330 rescue Exception => e
a785a5e @mxcl dump_config for certain exceptions
mxcl authored
331 onoe e
70bed07 @mxcl More tweaking of main exception handler output
mxcl authored
332 puts PLEASE_REPORT_BUG
333 puts e.backtrace
419cf71 @mxcl Return non-zero error code on errors
mxcl authored
334 exit 1
118b41b @mxcl Refactor $foo into HOMEBREW_FOO
mxcl authored
335 end
Something went wrong with that request. Please try again.