253 lines
7.2 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
2016-08-18 22:11:42 +03:00
require "optparse"
require "shellwords"
2016-10-04 15:24:58 +02:00
require "extend/optparse"
require "cask/config"
2018-09-03 20:17:29 +01:00
require "cask/cmd/options"
require "cask/cmd/abstract_command"
require "cask/cmd/--cache"
2018-09-03 20:17:29 +01:00
require "cask/cmd/audit"
require "cask/cmd/cat"
require "cask/cmd/create"
require "cask/cmd/doctor"
require "cask/cmd/edit"
require "cask/cmd/fetch"
2020-04-07 08:32:30 +02:00
require "cask/cmd/help"
2018-09-03 20:17:29 +01:00
require "cask/cmd/home"
require "cask/cmd/info"
require "cask/cmd/install"
require "cask/cmd/list"
require "cask/cmd/outdated"
require "cask/cmd/reinstall"
require "cask/cmd/style"
require "cask/cmd/uninstall"
require "cask/cmd/upgrade"
require "cask/cmd/zap"
require "cask/cmd/abstract_internal_command"
require "cask/cmd/internal_help"
require "cask/cmd/internal_stanza"
2016-08-18 22:11:42 +03:00
2018-09-06 08:29:14 +02:00
module Cask
2018-09-04 08:45:48 +01:00
class Cmd
2016-09-24 13:52:43 +02:00
ALIASES = {
2016-10-14 20:33:16 +02:00
"ls" => "list",
"homepage" => "home",
2020-04-07 08:32:30 +02:00
"instal" => "install", # gem does the same
"uninstal" => "uninstall",
2016-10-14 20:33:16 +02:00
"rm" => "uninstall",
"remove" => "uninstall",
"abv" => "info",
"dr" => "doctor",
}.freeze
2016-08-18 22:11:42 +03:00
2017-05-21 00:15:56 +02:00
include Options
2017-12-03 09:06:23 +01:00
option "--appdir=PATH", ->(value) { Config.global.appdir = value }
option "--colorpickerdir=PATH", ->(value) { Config.global.colorpickerdir = value }
option "--prefpanedir=PATH", ->(value) { Config.global.prefpanedir = value }
option "--qlplugindir=PATH", ->(value) { Config.global.qlplugindir = value }
2020-04-05 15:30:37 +02:00
option "--mdimporterdir=PATH", ->(value) { Config.global.mdimporterdir = value }
2017-12-03 09:06:23 +01:00
option "--dictionarydir=PATH", ->(value) { Config.global.dictionarydir = value }
option "--fontdir=PATH", ->(value) { Config.global.fontdir = value }
option "--servicedir=PATH", ->(value) { Config.global.servicedir = value }
option "--input_methoddir=PATH", ->(value) { Config.global.input_methoddir = value }
option "--internet_plugindir=PATH", ->(value) { Config.global.internet_plugindir = value }
option "--audio_unit_plugindir=PATH", ->(value) { Config.global.audio_unit_plugindir = value }
option "--vst_plugindir=PATH", ->(value) { Config.global.vst_plugindir = value }
option "--vst3_plugindir=PATH", ->(value) { Config.global.vst3_plugindir = value }
option "--screen_saverdir=PATH", ->(value) { Config.global.screen_saverdir = value }
2017-05-21 00:15:56 +02:00
option "--help", :help, false
# handled in OS::Mac
2017-06-12 19:07:52 +02:00
option "--language a,b,c", ->(*) {}
2017-05-21 00:15:56 +02:00
# override default handling of --version
option "--version", ->(*) { raise OptionParser::InvalidOption }
2017-03-06 20:37:13 +01:00
2016-09-24 13:52:43 +02:00
def self.command_classes
2016-10-14 20:55:09 +02:00
@command_classes ||= constants.map(&method(:const_get))
2017-05-20 19:08:03 +02:00
.select { |klass| klass.respond_to?(:run) }
.reject(&:abstract?)
.sort_by(&:command_name)
2016-09-24 13:52:43 +02:00
end
2016-08-18 22:11:42 +03:00
2016-09-24 13:52:43 +02:00
def self.commands
@commands ||= command_classes.map(&:command_name)
end
2016-08-18 22:11:42 +03:00
2017-05-21 00:15:56 +02:00
def self.lookup_command(command_name)
2016-09-24 13:52:43 +02:00
@lookup ||= Hash[commands.zip(command_classes)]
2017-05-21 00:15:56 +02:00
command_name = ALIASES.fetch(command_name, command_name)
2020-04-07 08:32:30 +02:00
@lookup.fetch(command_name, nil)
2016-09-24 13:52:43 +02:00
end
2016-08-18 22:11:42 +03:00
2020-04-07 08:32:30 +02:00
def self.run(*args)
new(*args).run
end
2020-04-07 08:32:30 +02:00
def initialize(*args)
@args = process_options(*args)
end
2020-04-07 08:32:30 +02:00
def find_external_command(command)
@tap_cmd_directories ||= Tap.cmd_directories
@path ||= PATH.new(@tap_cmd_directories, ENV["HOMEBREW_PATH"])
2020-04-07 08:32:30 +02:00
external_ruby_cmd = @tap_cmd_directories.map { |d| d/"brewcask-#{command}.rb" }
.find(&:file?)
external_ruby_cmd ||= which("brewcask-#{command}.rb", @path)
if external_ruby_cmd
2020-04-07 08:32:30 +02:00
ExternalRubyCommand.new(command, external_ruby_cmd)
elsif external_command = which("brewcask-#{command}", @path)
ExternalCommand.new(external_command)
2016-08-18 22:11:42 +03:00
end
end
2020-04-07 08:32:30 +02:00
def detect_internal_command(*args)
args.each_with_index do |arg, i|
if command = self.class.lookup_command(arg)
args.delete_at(i)
return [command, args]
elsif !arg.start_with?("-")
break
end
end
2017-05-21 00:15:56 +02:00
2020-04-07 08:32:30 +02:00
nil
2017-05-21 00:15:56 +02:00
end
2020-04-07 08:32:30 +02:00
def detect_external_command(*args)
args.each_with_index do |arg, i|
if command = find_external_command(arg)
args.delete_at(i)
return [command, args]
elsif !arg.start_with?("-")
break
end
end
2020-04-07 08:32:30 +02:00
nil
end
2017-05-21 00:15:56 +02:00
def run
2017-05-29 18:24:52 +01:00
MacOS.full_version = ENV["MACOS_VERSION"] unless ENV["MACOS_VERSION"].nil?
2018-06-09 10:13:28 +02:00
Tap.default_cask_tap.install unless Tap.default_cask_tap.installed?
2020-04-07 08:32:30 +02:00
args = @args.dup
command, args = detect_internal_command(*args) || detect_external_command(*args) || [NullCommand.new, args]
if help?
puts command.help
else
command.run(*args)
end
2018-08-15 12:13:21 +02:00
rescue CaskError, MethodDeprecatedError, ArgumentError, OptionParser::InvalidOption => e
2019-05-01 14:51:19 +02:00
onoe e.message
$stderr.puts e.backtrace if ARGV.debug?
2016-09-24 13:52:43 +02:00
exit 1
rescue StandardError, ScriptError, NoMemoryError => e
2019-05-01 14:51:19 +02:00
onoe e.message
$stderr.puts Utils.error_message_with_suggestions
$stderr.puts e.backtrace
2016-09-24 13:52:43 +02:00
exit 1
2016-08-18 22:11:42 +03:00
end
2016-09-24 13:52:43 +02:00
def self.nice_listing(cask_list)
cask_taps = {}
cask_list.each do |c|
user, repo, token = c.split "/"
repo.sub!(/^homebrew-/i, "")
2016-09-24 13:52:43 +02:00
cask_taps[token] ||= []
cask_taps[token].push "#{user}/#{repo}"
2016-08-18 22:11:42 +03:00
end
2016-09-24 13:52:43 +02:00
list = []
cask_taps.each do |token, taps|
if taps.length == 1
list.push token
else
taps.each { |r| list.push [r, token].join "/" }
end
end
list.sort
2016-08-18 22:11:42 +03:00
end
2017-05-21 00:15:56 +02:00
def process_options(*args)
exclude_regex = /^\-\-#{Regexp.union(*Config::DEFAULT_DIRS.keys.map(&Regexp.public_method(:escape)))}=/
2017-05-21 00:15:56 +02:00
non_options = []
2016-08-18 22:11:42 +03:00
2020-04-07 08:32:30 +02:00
if idx = args.index("--")
non_options += args.drop(idx)
args = args.first(idx)
2016-08-18 22:11:42 +03:00
end
2020-04-07 08:32:30 +02:00
cask_opts = Shellwords.shellsplit(ENV.fetch("HOMEBREW_CASK_OPTS", ""))
.reject { |arg| arg.match?(exclude_regex) }
all_args = cask_opts + args
remaining = all_args.select do |arg|
!process_arguments([arg]).empty?
rescue OptionParser::InvalidOption, OptionParser::MissingArgument, OptionParser::AmbiguousOption
true
2016-08-18 22:11:42 +03:00
end
2017-05-21 00:15:56 +02:00
remaining + non_options
2016-08-18 22:11:42 +03:00
end
2020-04-07 08:32:30 +02:00
class ExternalRubyCommand
def initialize(command, path)
@command_name = command.to_s.capitalize.to_sym
@path = path
2016-09-24 13:52:43 +02:00
end
2020-04-07 08:32:30 +02:00
def run(*args)
require @path
2020-04-07 08:32:30 +02:00
klass = begin
Cmd.const_get(@command_name)
rescue NameError
return
end
2020-04-07 08:32:30 +02:00
klass.run(*args)
2016-08-18 22:11:42 +03:00
end
2020-04-07 08:32:30 +02:00
end
2016-08-18 22:11:42 +03:00
2020-04-07 08:32:30 +02:00
class ExternalCommand
def initialize(path)
@path = path
2016-09-24 13:52:43 +02:00
end
2016-08-18 22:11:42 +03:00
2020-04-07 08:32:30 +02:00
def run(*)
exec @path, *ARGV[1..]
2016-08-18 22:11:42 +03:00
end
2020-04-07 08:32:30 +02:00
end
2016-08-18 22:11:42 +03:00
2020-04-07 08:32:30 +02:00
class NullCommand
def run(*args)
if args.empty?
ofail "No subcommand given.\n"
else
ofail "Unknown subcommand: #{args.first}"
end
2016-08-18 22:11:42 +03:00
2020-04-07 08:32:30 +02:00
$stderr.puts
$stderr.puts Help.usage
2016-09-24 13:52:43 +02:00
end
def help
run
end
2016-08-18 22:11:42 +03:00
end
end
end