Project

General

Profile

Bug #15197 » brew.rb

 
1
unless ENV["HOMEBREW_BREW_FILE"]
2
  raise "HOMEBREW_BREW_FILE was not exported! Please call bin/brew directly!"
3
end
4

    
5
std_trap = trap("INT") { exit! 130 } # no backtrace thanks
6

    
7
# check ruby version before requiring any modules.
8
RUBY_VERSION_SPLIT = RUBY_VERSION.split "."
9
RUBY_X = RUBY_VERSION_SPLIT[0].to_i
10
RUBY_Y = RUBY_VERSION_SPLIT[1].to_i
11
if RUBY_X < 2 || (RUBY_X == 2 && RUBY_Y < 3)
12
  raise "Homebrew must be run under Ruby 2.3! You're running #{RUBY_VERSION}."
13
end
14

    
15
require_relative "global"
16

    
17
require "update_migrator"
18

    
19
begin
20
  trap("INT", std_trap) # restore default CTRL-C handler
21

    
22
  empty_argv = ARGV.empty?
23
  help_flag_list = %w[-h --help --usage -?]
24
  help_flag = !ENV["HOMEBREW_HELP"].nil?
25
  cmd = nil
26

    
27
  ARGV.dup.each_with_index do |arg, i|
28
    break if help_flag && cmd
29

    
30
    if arg == "help" && !cmd
31
      # Command-style help: `help <cmd>` is fine, but `<cmd> help` is not.
32
      help_flag = true
33
    elsif !cmd && !help_flag_list.include?(arg)
34
      cmd = ARGV.delete_at(i)
35
    end
36
  end
37

    
38
  path = PATH.new(ENV["PATH"])
39
  homebrew_path = PATH.new(ENV["HOMEBREW_PATH"])
40

    
41
  # Add SCM wrappers.
42
  path.append(HOMEBREW_SHIMS_PATH/"scm")
43
  homebrew_path.append(HOMEBREW_SHIMS_PATH/"scm")
44

    
45
  ENV["PATH"] = path
46

    
47
  if cmd
48
    internal_cmd = require? HOMEBREW_LIBRARY_PATH/"cmd"/cmd
49

    
50
    unless internal_cmd
51
      internal_dev_cmd = require? HOMEBREW_LIBRARY_PATH/"dev-cmd"/cmd
52
      internal_cmd = internal_dev_cmd
53
      if internal_dev_cmd && !ARGV.homebrew_developer?
54
        if (HOMEBREW_REPOSITORY/".git/config").exist?
55
          system "git", "config", "--file=#{HOMEBREW_REPOSITORY}/.git/config",
56
                                  "--replace-all", "homebrew.devcmdrun", "true"
57
        end
58
        ENV["HOMEBREW_DEV_CMD_RUN"] = "1"
59
      end
60
    end
61
  end
62

    
63
  unless internal_cmd
64
    # Add contributed commands to PATH before checking.
65
    homebrew_path.append(Tap.cmd_directories)
66

    
67
    # External commands expect a normal PATH
68
    ENV["PATH"] = homebrew_path
69
  end
70

    
71
  # Usage instructions should be displayed if and only if one of:
72
  # - a help flag is passed AND a command is matched
73
  # - a help flag is passed AND there is no command specified
74
  # - no arguments are passed
75
  # - if cmd is Cask, let Cask handle the help command instead
76
  if (empty_argv || help_flag) && cmd != "cask"
77
    require "help"
78
    Homebrew::Help.help cmd, empty_argv: empty_argv
79
    # `Homebrew.help` never returns, except for external/unknown commands.
80
  end
81

    
82
  # Migrate LinkedKegs/PinnedKegs if update didn't already do so
83
  UpdateMigrator.migrate_legacy_keg_symlinks_if_necessary
84

    
85
  # Uninstall old brew-cask if it's still around; we just use the tap now.
86
  if cmd == "cask" && (HOMEBREW_CELLAR/"brew-cask").exist?
87
    system(HOMEBREW_BREW_FILE, "uninstall", "--force", "brew-cask")
88
  end
89

    
90
  if internal_cmd
91
    Homebrew.send cmd.to_s.tr("-", "_").downcase
92
  elsif which "brew-#{cmd}"
93
    %w[CACHE LIBRARY_PATH].each do |env|
94
      ENV["HOMEBREW_#{env}"] = Object.const_get("HOMEBREW_#{env}").to_s
95
    end
96
    exec "brew-#{cmd}", *ARGV
97
  elsif (path = which("brew-#{cmd}.rb")) && require?(path)
98
    exit Homebrew.failed? ? 1 : 0
99
  else
100
    possible_tap = OFFICIAL_CMD_TAPS.find { |_, cmds| cmds.include?(cmd) }
101
    possible_tap = Tap.fetch(possible_tap.first) if possible_tap
102

    
103
    odie "Unknown command: #{cmd}" if !possible_tap || possible_tap.installed?
104

    
105
    brew_uid = HOMEBREW_BREW_FILE.stat.uid
106
    tap_commands = []
107
    if Process.uid.zero? && !brew_uid.zero?
108
      tap_commands += %W[/usr/bin/sudo -u ##{brew_uid}]
109
    end
110
    # Unset HOMEBREW_HELP to avoid confusing the tap
111
    ENV.delete("HOMEBREW_HELP") if help_flag
112
    tap_commands += %W[#{HOMEBREW_BREW_FILE} tap #{possible_tap}]
113
    safe_system(*tap_commands)
114
    ENV["HOMEBREW_HELP"] = "1" if help_flag
115
    exec HOMEBREW_BREW_FILE, cmd, *ARGV
116
  end
117
rescue UsageError => e
118
  require "help"
119
  Homebrew::Help.help cmd, usage_error: e.message
120
rescue SystemExit => e
121
  onoe "Kernel.exit" if ARGV.debug? && !e.success?
122
  $stderr.puts e.backtrace if ARGV.debug?
123
  raise
124
rescue Interrupt
125
  $stderr.puts # seemingly a newline is typical
126
  exit 130
127
rescue BuildError => e
128
  Utils::Analytics.report_build_error(e)
129
  e.dump
130
  exit 1
131
rescue RuntimeError, SystemCallError => e
132
  raise if e.message.empty?
133

    
134
  onoe e
135
  $stderr.puts e.backtrace if ARGV.debug?
136
  exit 1
137
rescue MethodDeprecatedError => e
138
  onoe e
139
  if e.issues_url
140
    $stderr.puts "If reporting this issue please do so at (not Homebrew/brew or Homebrew/core):"
141
    $stderr.puts "  #{Formatter.url(e.issues_url)}"
142
  end
143
  $stderr.puts e.backtrace if ARGV.debug?
144
  exit 1
145
rescue Exception => e # rubocop:disable Lint/RescueException
146
  onoe e
147
  if internal_cmd && defined?(OS::ISSUES_URL) &&
148
     !ENV["HOMEBREW_NO_AUTO_UPDATE"]
149
    $stderr.puts "#{Tty.bold}Please report this bug:#{Tty.reset}"
150
    $stderr.puts "  #{Formatter.url(OS::ISSUES_URL)}"
151
  end
152
  $stderr.puts e.backtrace
153
  exit 1
154
else
155
  exit 1 if Homebrew.failed?
156
end