Refactor command handling code

Don’t rely on having external commands always present in the PATH in
order to find them. Instead, provide an accessory method to Tap so
they can be added and used when needed.

While we’re here, do some general refactoring and cleanup of the
command code in these places.
This commit is contained in:
Mike McQuaid 2017-11-05 15:37:57 +00:00
parent c3006f0f12
commit 7a68b4a3f9
5 changed files with 51 additions and 45 deletions

View File

@ -33,7 +33,6 @@ begin
empty_argv = ARGV.empty? empty_argv = ARGV.empty?
help_flag_list = %w[-h --help --usage -?] help_flag_list = %w[-h --help --usage -?]
help_flag = !ENV["HOMEBREW_HELP"].nil? help_flag = !ENV["HOMEBREW_HELP"].nil?
internal_cmd = true
cmd = nil cmd = nil
ARGV.dup.each_with_index do |arg, i| ARGV.dup.each_with_index do |arg, i|
@ -60,8 +59,9 @@ begin
internal_cmd = require? HOMEBREW_LIBRARY_PATH/"cmd"/cmd internal_cmd = require? HOMEBREW_LIBRARY_PATH/"cmd"/cmd
unless internal_cmd unless internal_cmd
internal_cmd = require? HOMEBREW_LIBRARY_PATH/"dev-cmd"/cmd internal_dev_cmd = require? HOMEBREW_LIBRARY_PATH/"dev-cmd"/cmd
if internal_cmd && !ARGV.homebrew_developer? internal_cmd = internal_dev_cmd
if internal_dev_cmd && !ARGV.homebrew_developer?
system "git", "config", "--file=#{HOMEBREW_REPOSITORY}/.git/config", system "git", "config", "--file=#{HOMEBREW_REPOSITORY}/.git/config",
"--replace-all", "homebrew.devcmdrun", "true" "--replace-all", "homebrew.devcmdrun", "true"
ENV["HOMEBREW_DEV_CMD_RUN"] = "1" ENV["HOMEBREW_DEV_CMD_RUN"] = "1"
@ -90,8 +90,7 @@ begin
unless internal_cmd unless internal_cmd
# Add contributed commands to PATH before checking. # Add contributed commands to PATH before checking.
tap_cmds = Pathname.glob(Tap::TAP_DIRECTORY/"*/*/cmd") homebrew_path.append(Tap.cmd_directories)
homebrew_path.append(tap_cmds)
# External commands expect a normal PATH # External commands expect a normal PATH
ENV["PATH"] = homebrew_path ENV["PATH"] = homebrew_path
@ -100,14 +99,13 @@ begin
if internal_cmd if internal_cmd
Homebrew.send cmd.to_s.tr("-", "_").downcase Homebrew.send cmd.to_s.tr("-", "_").downcase
elsif which "brew-#{cmd}" elsif which "brew-#{cmd}"
%w[CACHE LIBRARY_PATH].each do |e| %w[CACHE LIBRARY_PATH].each do |env|
ENV["HOMEBREW_#{e}"] = Object.const_get("HOMEBREW_#{e}").to_s ENV["HOMEBREW_#{env}"] = Object.const_get("HOMEBREW_#{env}").to_s
end end
exec "brew-#{cmd}", *ARGV exec "brew-#{cmd}", *ARGV
elsif (path = which("brew-#{cmd}.rb")) && require?(path) elsif (path = which("brew-#{cmd}.rb")) && require?(path)
exit Homebrew.failed? ? 1 : 0 exit Homebrew.failed? ? 1 : 0
else else
require "tap"
possible_tap = OFFICIAL_CMD_TAPS.find { |_, cmds| cmds.include?(cmd) } possible_tap = OFFICIAL_CMD_TAPS.find { |_, cmds| cmds.include?(cmd) }
possible_tap = Tap.fetch(possible_tap.first) if possible_tap possible_tap = Tap.fetch(possible_tap.first) if possible_tap

View File

@ -8,15 +8,16 @@ module Homebrew
def command def command
abort "This command requires a command argument" if ARGV.empty? abort "This command requires a command argument" if ARGV.empty?
cmd = ARGV.first
cmd = HOMEBREW_INTERNAL_COMMAND_ALIASES.fetch(cmd, cmd)
if (path = Commands.path(cmd)) cmd = HOMEBREW_INTERNAL_COMMAND_ALIASES.fetch(ARGV.first, ARGV.first)
path = Commands.path(cmd)
cmd_paths = PATH.new(ENV["PATH"]).append(Tap.cmd_directories) unless path
path ||= which("brew-#{cmd}", cmd_paths)
path ||= which("brew-#{cmd}.rb", cmd_paths)
odie "Unknown command: #{cmd}" unless path
puts path puts path
elsif (path = which("brew-#{cmd}") || which("brew-#{cmd}.rb"))
puts path
else
odie "Unknown command: #{cmd}"
end
end end
end end

View File

@ -9,11 +9,14 @@ module Homebrew
def commands def commands
if ARGV.include? "--quiet" if ARGV.include? "--quiet"
cmds = internal_commands + external_commands cmds = internal_commands
cmds += external_commands
cmds += internal_developer_commands cmds += internal_developer_commands
cmds += HOMEBREW_INTERNAL_COMMAND_ALIASES.keys if ARGV.include? "--include-aliases" cmds += HOMEBREW_INTERNAL_COMMAND_ALIASES.keys if ARGV.include? "--include-aliases"
puts Formatter.columns(cmds.sort) puts Formatter.columns(cmds.sort)
else return
end
# Find commands in Homebrew/cmd # Find commands in Homebrew/cmd
puts "Built-in commands" puts "Built-in commands"
puts Formatter.columns(internal_commands.sort) puts Formatter.columns(internal_commands.sort)
@ -23,14 +26,14 @@ module Homebrew
puts "Built-in developer commands" puts "Built-in developer commands"
puts Formatter.columns(internal_developer_commands.sort) puts Formatter.columns(internal_developer_commands.sort)
# Find commands in the path exts = external_commands
unless (exts = external_commands).empty? return if exts.empty?
# Find commands in the PATH
puts puts
puts "External commands" puts "External commands"
puts Formatter.columns(exts) puts Formatter.columns(exts)
end end
end
end
def internal_commands def internal_commands
find_internal_commands HOMEBREW_LIBRARY_PATH/"cmd" find_internal_commands HOMEBREW_LIBRARY_PATH/"cmd"
@ -41,11 +44,13 @@ module Homebrew
end end
def external_commands def external_commands
paths.each_with_object([]) do |path, cmds| cmd_paths = PATH.new(ENV["PATH"]).append(Tap.cmd_directories)
cmd_paths.each_with_object([]) do |path, cmds|
Dir["#{path}/brew-*"].each do |file| Dir["#{path}/brew-*"].each do |file|
next unless File.executable?(file) next unless File.executable?(file)
cmd = File.basename(file, ".rb")[5..-1] cmd = File.basename(file, ".rb")[5..-1]
cmds << cmd unless cmd.include?(".") next if cmd.include?(".")
cmds << cmd
end end
end.sort end.sort
end end

View File

@ -1,13 +1,10 @@
module Commands module Commands
def self.path(cmd) def self.path(cmd)
if File.exist?(HOMEBREW_LIBRARY_PATH/"cmd/#{cmd}.sh") [
HOMEBREW_LIBRARY_PATH/"cmd/#{cmd}.sh" HOMEBREW_LIBRARY_PATH/"cmd/#{cmd}.sh",
elsif File.exist?(HOMEBREW_LIBRARY_PATH/"dev-cmd/#{cmd}.sh") HOMEBREW_LIBRARY_PATH/"dev-cmd/#{cmd}.sh",
HOMEBREW_LIBRARY_PATH/"dev-cmd/#{cmd}.sh" HOMEBREW_LIBRARY_PATH/"cmd/#{cmd}.rb",
elsif File.exist?(HOMEBREW_LIBRARY_PATH/"cmd/#{cmd}.rb") HOMEBREW_LIBRARY_PATH/"dev-cmd/#{cmd}.rb",
HOMEBREW_LIBRARY_PATH/"cmd/#{cmd}.rb" ].find(&:exist?)
elsif File.exist?(HOMEBREW_LIBRARY_PATH/"dev-cmd/#{cmd}.rb")
HOMEBREW_LIBRARY_PATH/"dev-cmd/#{cmd}.rb"
end
end end
end end

View File

@ -503,6 +503,11 @@ class Tap
map(&:name).sort map(&:name).sort
end end
# an array of all tap cmd directory {Pathname}s
def self.cmd_directories
Pathname.glob TAP_DIRECTORY/"*/*/cmd"
end
# @private # @private
def formula_file_to_name(file) def formula_file_to_name(file)
"#{name}/#{file.basename(".rb")}" "#{name}/#{file.basename(".rb")}"