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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
unless ENV["HOMEBREW_BREW_FILE"]
raise "HOMEBREW_BREW_FILE was not exported! Please call bin/brew directly!"
end
std_trap = trap("INT") { exit! 130 } # no backtrace thanks
# check ruby version before requiring any modules.
RUBY_VERSION_SPLIT = RUBY_VERSION.split "."
RUBY_X = RUBY_VERSION_SPLIT[0].to_i
RUBY_Y = RUBY_VERSION_SPLIT[1].to_i
if RUBY_X < 2 || (RUBY_X == 2 && RUBY_Y < 3)
raise "Homebrew must be run under Ruby 2.3!"
end
require "pathname"
HOMEBREW_LIBRARY_PATH = Pathname.new(__FILE__).realpath.parent
require "English"
unless $LOAD_PATH.include?(HOMEBREW_LIBRARY_PATH.to_s)
$LOAD_PATH.unshift(HOMEBREW_LIBRARY_PATH.to_s)
end
require "global"
require "tap"
if ARGV == %w[--version] || ARGV == %w[-v]
puts "Homebrew #{HOMEBREW_VERSION}"
puts "Homebrew/homebrew-core #{CoreTap.instance.version_string}"
exit 0
end
begin
trap("INT", std_trap) # restore default CTRL-C handler
empty_argv = ARGV.empty?
help_flag_list = %w[-h --help --usage -?]
help_flag = !ENV["HOMEBREW_HELP"].nil?
internal_cmd = true
cmd = nil
ARGV.dup.each_with_index do |arg, i|
break if help_flag && cmd
if arg == "help" && !cmd
# Command-style help: `help <cmd>` is fine, but `<cmd> help` is not.
help_flag = true
elsif !cmd && !help_flag_list.include?(arg)
cmd = ARGV.delete_at(i)
elsif help_flag_list.include?(arg) && cmd
# cmd determined, and it needs help
help_flag = true
end
end
path = PATH.new(ENV["PATH"])
homebrew_path = PATH.new(ENV["HOMEBREW_PATH"])
# Add contributed commands to PATH before checking.
tap_cmds = Pathname.glob(Tap::TAP_DIRECTORY/"*/*/cmd")
path.append(tap_cmds)
homebrew_path.append(tap_cmds)
# Add SCM wrappers.
path.append(HOMEBREW_SHIMS_PATH/"scm")
homebrew_path.append(HOMEBREW_SHIMS_PATH/"scm")
ENV["PATH"] = path
if cmd
internal_cmd = require? HOMEBREW_LIBRARY_PATH/"cmd"/cmd
unless internal_cmd
internal_cmd = require? HOMEBREW_LIBRARY_PATH/"dev-cmd"/cmd
if internal_cmd && !ARGV.homebrew_developer?
system "git", "config", "--file=#{HOMEBREW_REPOSITORY}/.git/config",
"--replace-all", "homebrew.devcmdrun", "true"
ENV["HOMEBREW_DEV_CMD_RUN"] = "1"
end
end
end
# Usage instructions should be displayed if and only if one of:
# - a help flag is passed AND a command is matched
# - a help flag is passed AND there is no command specified
# - no arguments are passed
if empty_argv || help_flag
require "cmd/help"
Homebrew.help cmd, empty_argv: empty_argv
# `Homebrew.help` never returns, except for external/unknown commands.
end
# Migrate LinkedKegs/PinnedKegs if update didn't already do so
migrate_legacy_keg_symlinks_if_necessary
# Uninstall old brew-cask if it's still around; we just use the tap now.
if cmd == "cask" && (HOMEBREW_CELLAR/"brew-cask").exist?
system(HOMEBREW_BREW_FILE, "uninstall", "--force", "brew-cask")
end
# External commands expect a normal PATH
ENV["PATH"] = homebrew_path unless internal_cmd
if internal_cmd
Homebrew.send cmd.to_s.tr("-", "_").downcase
elsif which "brew-#{cmd}"
%w[CACHE LIBRARY_PATH].each do |e|
ENV["HOMEBREW_#{e}"] = Object.const_get("HOMEBREW_#{e}").to_s
end
exec "brew-#{cmd}", *ARGV
elsif (path = which("brew-#{cmd}.rb")) && require?(path)
exit Homebrew.failed? ? 1 : 0
else
require "tap"
possible_tap = OFFICIAL_CMD_TAPS.find { |_, cmds| cmds.include?(cmd) }
possible_tap = Tap.fetch(possible_tap.first) if possible_tap
odie "Unknown command: #{cmd}" if !possible_tap || possible_tap.installed?
brew_uid = HOMEBREW_BREW_FILE.stat.uid
tap_commands = []
if Process.uid.zero? && !brew_uid.zero?
tap_commands += %W[/usr/bin/sudo -u ##{brew_uid}]
end
if help_flag
# Unset HOMEBREW_HELP to avoid confusing the tap
ENV["HOMEBREW_HELP"] = nil
end
tap_commands += %W[#{HOMEBREW_BREW_FILE} tap #{possible_tap}]
safe_system(*tap_commands)
if help_flag
# Restore HOMEBREW_HELP after the tap
ENV["HOMEBREW_HELP"] = 1
end
exec HOMEBREW_BREW_FILE, cmd, *ARGV
end
rescue UsageError => e
require "cmd/help"
Homebrew.help cmd, usage_error: e.message
rescue SystemExit => e
onoe "Kernel.exit" if ARGV.verbose? && !e.success?
$stderr.puts e.backtrace if ARGV.debug?
raise
rescue Interrupt
$stderr.puts # seemingly a newline is typical
exit 130
rescue BuildError => e
Utils::Analytics.report_build_error(e)
e.dump
exit 1
rescue RuntimeError, SystemCallError => e
raise if e.message.empty?
onoe e
$stderr.puts e.backtrace if ARGV.debug?
exit 1
rescue MethodDeprecatedError => e
onoe e
if e.issues_url
$stderr.puts "If reporting this issue please do so at (not Homebrew/brew or Homebrew/core):"
$stderr.puts " #{Formatter.url(e.issues_url)}"
end
exit 1
rescue Exception => e
onoe e
if internal_cmd && defined?(OS::ISSUES_URL) &&
!ENV["HOMEBREW_NO_AUTO_UPDATE"]
$stderr.puts "#{Tty.bold}Please report this bug:#{Tty.reset}"
$stderr.puts " #{Formatter.url(OS::ISSUES_URL)}"
end
$stderr.puts e.backtrace
exit 1
else
exit 1 if Homebrew.failed?
end
|