require "magellan/cli" require 'thor' module Magellan module Cli class Base < Thor class_option :verbose, type: :boolean, aliases: "-V" class_option :dryrun , type: :boolean, aliases: "-D" class_option :version, type: :boolean, aliases: "-v" no_commands do def sub(klass) task = klass.new task.options = self.options task end def opts @opts ||= options || {} end def dryrun? opts[:dryrun] end def verbose? opts[:verbose] end def verbose(msg) self.class.verbose(msg) if verbose? end def info(msg) self.class.info(msg) end def success(msg) self.class.success(msg) end def error(msg) self.class.error(msg) end def fatal(msg) verbose(caller.join("\n ")) raise Cli::Error, msg end end class << self def puts_with_color(color_no, msg) $stderr.puts("\e[#{color_no}m#{msg}\e[0m") end def verbose(msg, flag = true) puts_with_color(34, msg) if flag end def info(msg) puts_with_color(0, msg) end def success(msg) puts_with_color(32, msg) end def error(msg) puts_with_color(31, msg) end def sorted_commands(all = true) cmd_hash = all_commands.dup Thor::Util.thor_classes_in(self).each do |klass| cmd_hash.update(klass.commands) end if order = self.const_get(:COMMAND_ORDER) rescue nil result = order.map{|i| cmd_hash[i]} result += (cmd_hash.keys - order).map{|i| cmd_hash[i]} else result = cmd_hash.values end if idx = result.index{|cmd| cmd.name == "help" } h = result.delete_at(idx) result << h end return result end def sorted_printable_commands(all = true, subcommand = false) list = printable_commands(all, subcommand) Thor::Util.thor_classes_in(self).each do |klass| list += klass.printable_commands(false) end order = self.const_get(:COMMAND_ORDER) rescue nil if order orig = list list = order.map do |ptn| idx = orig.index{|t| t.first =~ /\b#{ptn}\b/} raise "#{ptn} not found" unless idx orig.delete_at(idx) end list += orig # add items not in COMMAND_ORDER end # # don't sort in alphabetical order # list.sort! { |a, b| a[0] <=> b[0] } # move help to the end of list if idx = list.index{|t| t.first =~ /\bhelp\b/ } h = list.delete_at(idx) list << h end return list end # overwrite Thor.help method def help(shell, subcommand = false) if defined?(@package_name) && @package_name shell.say "#{@package_name} commands:" else shell.say "Commands:" end shell.print_table(sorted_printable_commands(true, subcommand), :indent => 2, :truncate => true) shell.say class_options_help(shell) end # override Thor.command_help def command_help(shell, command_name) meth = normalize_command_name(command_name) command = all_commands[meth] handle_no_command_error(meth) unless command shell.say "Usage:" shell.say " #{banner(command)}" shell.say class_options_help(shell, nil => command.options.map { |_, o| o }) if command.long_description shell.say "Description:" shell.print_wrapped(command.long_description, :indent => 2) else shell.say command.description end end end end end end