diff --git a/lib/cask/cli.rb b/lib/cask/cli.rb index 455e1b4c1c6..64dcf6e7c74 100644 --- a/lib/cask/cli.rb +++ b/lib/cask/cli.rb @@ -3,6 +3,7 @@ class Cask::CLI; end require 'optparse' require 'shellwords' +require 'cask/cli/base' require 'cask/cli/alfred' require 'cask/cli/audit' require 'cask/cli/cat' @@ -20,36 +21,46 @@ require 'cask/cli/search' require 'cask/cli/uninstall' require 'cask/cli/update' +require 'cask/cli/internal_use_base' +require 'cask/cli/internal_dump' +require 'cask/cli/internal_help' + class Cask::CLI + ISSUES_URL = "https://github.com/caskroom/homebrew-cask/issues" + + ALIASES = { + 'ls' => 'list', + 'homepage' => 'home', + '-S' => 'search', # verb starting with "-" is questionable + 'up' => 'update', + 'instal' => 'install', # gem does the same + 'rm' => 'uninstall', + 'remove' => 'uninstall', + 'abv' => 'info', + 'dr' => 'doctor', + # aliases from Homebrew that we don't (yet) support + # 'ln' => 'link', + # 'configure' => 'diy', + # '--repo' => '--repository', + # 'environment' => '--env', + # '-c1' => '--config', + } + + def self.command_classes + @@command_classes ||= Cask::CLI.constants. + map { |sym| Cask::CLI.const_get sym }. + select { |sym| sym.respond_to?(:run) } + end + def self.commands - Cask::CLI.constants - [:NullCommand, :ISSUES_URL, "NullCommand", "ISSUES_URL"] + @@commands ||= command_classes.map { |sym| sym.command_name } end def self.lookup_command(command_string) - aliases = { - 'ls' => 'list', - 'homepage' => 'home', - '-S' => 'search', - 'up' => 'update', - 'instal' => 'install', # gem does the same - 'rm' => 'uninstall', - 'remove' => 'uninstall', - 'abv' => 'info', - 'dr' => 'doctor', - # aliases from Homebrew that we don't (yet) support - # 'ln' => 'link', - # 'configure' => 'diy', - # '--repo' => '--repository', - # 'environment' => '--env', - # '-c1' => '--config', - } - command_string = aliases[command_string] if aliases.key?(command_string) - if command_string && Cask::CLI.const_defined?(command_string.capitalize) - Cask::CLI.const_get(command_string.capitalize) - else - command_string - end + @@lookup ||= Hash[commands.zip(command_classes)] + command_string = ALIASES.fetch(command_string, command_string) + @@lookup.fetch(command_string, command_string) end def self.run_command(command, *rest) @@ -175,7 +186,7 @@ class Cask::CLI if @attempted_name and @attempted_name != "help" puts "!! " puts "!! no command with name: #{@attempted_name}" - puts "!! " + puts "!! \n\n" end usage end @@ -189,12 +200,12 @@ class Cask::CLI end def usage - longest_command_size = Cask::CLI.commands.map(&:length).max + max_command_len = Cask::CLI.commands.map(&:length).max puts "Commands:\n\n" - Cask::CLI.commands.each do |c| - command = "#{c.downcase}".ljust(longest_command_size) - puts " #{command} #{_help_for(c)}" + Cask::CLI.command_classes.each do |klass| + next unless klass.visible + puts " #{klass.command_name.ljust(max_command_len)} #{_help_for(klass)}" end puts %Q{\nSee also "man brew-cask"} end @@ -203,11 +214,8 @@ class Cask::CLI '' end - def _help_for(command_string) - command = Cask::CLI.lookup_command(command_string) - if command.respond_to?(:help) - command.help - end + def _help_for(klass) + klass.respond_to?(:help) ? klass.help : nil end end end diff --git a/lib/cask/cli/alfred.rb b/lib/cask/cli/alfred.rb index 925321ba093..55ff8ff9a74 100644 --- a/lib/cask/cli/alfred.rb +++ b/lib/cask/cli/alfred.rb @@ -1,4 +1,4 @@ -class Cask::CLI::Alfred +class Cask::CLI::Alfred < Cask::CLI::Base DEFAULT_SCOPES = [ '/Applications', '/Applications/Xcode.app/Contents/Applications', diff --git a/lib/cask/cli/audit.rb b/lib/cask/cli/audit.rb index a184507b4d5..ac00786508a 100644 --- a/lib/cask/cli/audit.rb +++ b/lib/cask/cli/audit.rb @@ -1,4 +1,4 @@ -class Cask::CLI::Audit +class Cask::CLI::Audit < Cask::CLI::Base def self.help 'verifies installability of casks' end diff --git a/lib/cask/cli/base.rb b/lib/cask/cli/base.rb new file mode 100644 index 00000000000..926571ee60e --- /dev/null +++ b/lib/cask/cli/base.rb @@ -0,0 +1,13 @@ +class Cask::CLI::Base + def self.command_name + @command_name ||= self.name.sub(%r{^.*:}, '').gsub(%r{(.)([A-Z])}, '\1_\2').downcase + end + + def self.visible + true + end + + def self.help + "No help available for the #{command_name} command" + end +end diff --git a/lib/cask/cli/cat.rb b/lib/cask/cli/cat.rb index e1c00cb7103..c23d1704b7a 100644 --- a/lib/cask/cli/cat.rb +++ b/lib/cask/cli/cat.rb @@ -1,4 +1,4 @@ -module Cask::CLI::Cat +class Cask::CLI::Cat < Cask::CLI::Base def self.run(*arguments) # only respects the first argument raise CaskUnspecifiedError if arguments.empty? diff --git a/lib/cask/cli/checklinks.rb b/lib/cask/cli/checklinks.rb index bf4bcc295a1..9e427649f56 100644 --- a/lib/cask/cli/checklinks.rb +++ b/lib/cask/cli/checklinks.rb @@ -1,4 +1,4 @@ -class Cask::CLI::Checklinks +class Cask::CLI::Checklinks < Cask::CLI::Base def self.run(*args) casks_to_check = args.empty? ? Cask.all : args.map { |arg| Cask.load(arg) } casks_to_check.each do |cask| diff --git a/lib/cask/cli/cleanup.rb b/lib/cask/cli/cleanup.rb index ed69378f3d9..4e5568758ce 100644 --- a/lib/cask/cli/cleanup.rb +++ b/lib/cask/cli/cleanup.rb @@ -1,4 +1,4 @@ -class Cask::CLI::Cleanup +class Cask::CLI::Cleanup < Cask::CLI::Base OUTDATED_DAYS = 10 OUTDATED_TIMESTAMP = Time.now - (60 * 60 * 24 * OUTDATED_DAYS) diff --git a/lib/cask/cli/create.rb b/lib/cask/cli/create.rb index 6d3a5b5247e..766c99c955c 100644 --- a/lib/cask/cli/create.rb +++ b/lib/cask/cli/create.rb @@ -1,4 +1,4 @@ -module Cask::CLI::Create +class Cask::CLI::Create < Cask::CLI::Base def self.run(*arguments) raise CaskUnspecifiedError if arguments.empty? cask_name = arguments.first.sub(/\.rb$/i,'') diff --git a/lib/cask/cli/doctor.rb b/lib/cask/cli/doctor.rb index 3c106774ac1..da9f76d54a9 100644 --- a/lib/cask/cli/doctor.rb +++ b/lib/cask/cli/doctor.rb @@ -1,4 +1,4 @@ -class Cask::CLI::Doctor +class Cask::CLI::Doctor < Cask::CLI::Base def self.run ohai 'OS X Version:', render_with_none_as_error( MACOS_FULL_VERSION ) ohai "Hardware Architecture:", render_with_none_as_error( "#{Hardware::CPU.type}-#{Hardware::CPU.bits}" ) diff --git a/lib/cask/cli/edit.rb b/lib/cask/cli/edit.rb index dad1ad6f0c6..48f4db16ef1 100644 --- a/lib/cask/cli/edit.rb +++ b/lib/cask/cli/edit.rb @@ -1,4 +1,4 @@ -module Cask::CLI::Edit +class Cask::CLI::Edit < Cask::CLI::Base def self.run(*arguments) raise CaskUnspecifiedError if arguments.empty? cask_name = arguments.first.sub(/\.rb$/i,'') diff --git a/lib/cask/cli/fetch.rb b/lib/cask/cli/fetch.rb index 9ee32504928..25eca016b11 100644 --- a/lib/cask/cli/fetch.rb +++ b/lib/cask/cli/fetch.rb @@ -1,4 +1,4 @@ -class Cask::CLI::Fetch +class Cask::CLI::Fetch < Cask::CLI::Base def self.run(*args) raise CaskUnspecifiedError if args.empty? cask_names = args.reject { |a| a.chars.first == '-' } diff --git a/lib/cask/cli/home.rb b/lib/cask/cli/home.rb index 7e8a437a2f6..a75af1cbf9e 100644 --- a/lib/cask/cli/home.rb +++ b/lib/cask/cli/home.rb @@ -1,4 +1,4 @@ -module Cask::CLI::Home +class Cask::CLI::Home < Cask::CLI::Base def self.run(*cask_names) if cask_names.empty? odebug "Opening project homepage" diff --git a/lib/cask/cli/info.rb b/lib/cask/cli/info.rb index 2fb045d69da..6127ed5a010 100644 --- a/lib/cask/cli/info.rb +++ b/lib/cask/cli/info.rb @@ -1,4 +1,4 @@ -class Cask::CLI::Info +class Cask::CLI::Info < Cask::CLI::Base def self.run(*cask_names) raise CaskUnspecifiedError if cask_names.empty? cask_names.each do |cask_name| diff --git a/lib/cask/cli/install.rb b/lib/cask/cli/install.rb index 3faf0988bb2..797ccf849a7 100644 --- a/lib/cask/cli/install.rb +++ b/lib/cask/cli/install.rb @@ -1,4 +1,4 @@ -class Cask::CLI::Install +class Cask::CLI::Install < Cask::CLI::Base def self.run(*args) raise CaskUnspecifiedError if args.empty? cask_names = args.reject { |a| a.chars.first == '-' } diff --git a/lib/cask/cli/internal_dump.rb b/lib/cask/cli/internal_dump.rb new file mode 100644 index 00000000000..b074be0b51d --- /dev/null +++ b/lib/cask/cli/internal_dump.rb @@ -0,0 +1,30 @@ +class Cask::CLI::InternalDump < Cask::CLI::InternalUseBase + def self.run(*arguments) + retval = dump_casks(*arguments) + # retval is ternary: true/false/nil + if retval.nil? + raise CaskError.new("nothing to dump") + elsif ! retval + raise CaskError.new("dump incomplete") + end + end + + def self.dump_casks(*cask_names) + Cask.debug = true # Yuck. At the moment this is the only way to make dumps visible + count = 0 + cask_names.each do |cask_name| + begin + cask = Cask.load(cask_name) + count += 1 + cask.dumpcask + rescue StandardError + opoo "#{cask} was not found" + end + end + count == 0 ? nil : count == cask_names.length + end + + def self.help + "Dump the given Cask in YAML format" + end +end diff --git a/lib/cask/cli/internal_help.rb b/lib/cask/cli/internal_help.rb new file mode 100644 index 00000000000..aa9d4eca816 --- /dev/null +++ b/lib/cask/cli/internal_help.rb @@ -0,0 +1,19 @@ +class Cask::CLI::InternalHelp < Cask::CLI::InternalUseBase + def self.run(*_ignored) + max_command_len = Cask::CLI.commands.map(&:length).max + puts "Unstable Internal-use Commands:\n\n" + Cask::CLI.command_classes.each do |klass| + next if klass.visible + puts " #{klass.command_name.ljust(max_command_len)} #{help_for(klass)}" + end + puts "\n" + end + + def self.help_for(klass) + klass.respond_to?(:help) ? klass.help : nil + end + + def self.help + "Print help strings for unstable internal-use commands" + end +end diff --git a/lib/cask/cli/internal_use_base.rb b/lib/cask/cli/internal_use_base.rb new file mode 100644 index 00000000000..4cb8f5105dc --- /dev/null +++ b/lib/cask/cli/internal_use_base.rb @@ -0,0 +1,9 @@ +class Cask::CLI::InternalUseBase < Cask::CLI::Base + def self.command_name + super.sub(%r{^internal_}i, '_') + end + + def self.visible + false + end +end diff --git a/lib/cask/cli/list.rb b/lib/cask/cli/list.rb index 29b98ba47a7..9bd803c7183 100644 --- a/lib/cask/cli/list.rb +++ b/lib/cask/cli/list.rb @@ -1,4 +1,4 @@ -class Cask::CLI::List +class Cask::CLI::List < Cask::CLI::Base def self.run(*arguments) if arguments.any? retval = list_casks(*arguments) diff --git a/lib/cask/cli/search.rb b/lib/cask/cli/search.rb index 76c02cdd6c0..c9b2ed6ff47 100644 --- a/lib/cask/cli/search.rb +++ b/lib/cask/cli/search.rb @@ -1,4 +1,4 @@ -class Cask::CLI::Search +class Cask::CLI::Search < Cask::CLI::Base def self.run(*arguments) render_results *search(*arguments) end diff --git a/lib/cask/cli/uninstall.rb b/lib/cask/cli/uninstall.rb index e4c3f7a6ca6..12d17c2da69 100644 --- a/lib/cask/cli/uninstall.rb +++ b/lib/cask/cli/uninstall.rb @@ -1,4 +1,4 @@ -class Cask::CLI::Uninstall +class Cask::CLI::Uninstall < Cask::CLI::Base def self.run(*args) raise CaskUnspecifiedError if args.empty? cask_names = args.reject { |a| a.chars.first == '-' } diff --git a/lib/cask/cli/update.rb b/lib/cask/cli/update.rb index 4cb36f51f0f..d1c43fd8c76 100644 --- a/lib/cask/cli/update.rb +++ b/lib/cask/cli/update.rb @@ -1,4 +1,4 @@ -module Cask::CLI::Update +class Cask::CLI::Update < Cask::CLI::Base def self.run(*_ignored) ARGV.clear require HOMEBREW_REPOSITORY.join("Library/Homebrew/cmd/update") diff --git a/test/cask/cli/create_test.rb b/test/cask/cli/create_test.rb index c93ecea85bd..070725deafd 100644 --- a/test/cask/cli/create_test.rb +++ b/test/cask/cli/create_test.rb @@ -1,23 +1,20 @@ require 'test_helper' -module RecordCreateorCalls - def exec_editor(*command) +# monkeypatch for testing +class Cask::CLI::Create + def self.exec_editor(*command) editor_commands << command end - def reset! + def self.reset! @editor_commands = [] end - def editor_commands + def self.editor_commands @editor_commands ||= [] end end -module Cask::CLI::Create - extend RecordCreateorCalls -end - describe Cask::CLI::Create do before { Cask::CLI::Create.reset! } diff --git a/test/cask/cli/edit_test.rb b/test/cask/cli/edit_test.rb index 856c83db2ad..32f34f1ba99 100644 --- a/test/cask/cli/edit_test.rb +++ b/test/cask/cli/edit_test.rb @@ -1,23 +1,20 @@ require 'test_helper' -module RecordEditorCalls - def exec_editor(*command) +# monkeypatch for testing +class Cask::CLI::Edit + def self.exec_editor(*command) editor_commands << command end - def reset! + def self.reset! @editor_commands = [] end - def editor_commands + def self.editor_commands @editor_commands ||= [] end end -module Cask::CLI::Edit - extend RecordEditorCalls -end - describe Cask::CLI::Edit do before do Cask::CLI::Edit.reset! diff --git a/test/cask/cli/home_test.rb b/test/cask/cli/home_test.rb index 55002c6e8d4..2cc7666e3fe 100644 --- a/test/cask/cli/home_test.rb +++ b/test/cask/cli/home_test.rb @@ -1,23 +1,20 @@ require 'test_helper' -module RecordSystemCalls - def system(*command) +# monkeypatch for testing +class Cask::CLI::Home + def self.system(*command) system_commands << command end - def reset! + def self.reset! @system_commands = [] end - def system_commands + def self.system_commands @system_commands ||= [] end end -module Cask::CLI::Home - extend RecordSystemCalls -end - describe Cask::CLI::Home do before do Cask::CLI::Home.reset!