require "thor" require "active_support" # for autoload require "active_support/core_ext" module <%= project_class_name %> class CLI def self.start(given_args=ARGV) new(given_args).start end def self.thor_tasks <%= project_class_name %>::Command.namespaced_commands end def initialize(given_args=ARGV, **config) @given_args = given_args.dup @config = config end def start setup_auto_load command_class = lookup(full_command) if command_class command_class.perform(full_command, thor_args) else main_help end end def setup_auto_load autoload_paths = [File.expand_path("../../", __FILE__)] ActiveSupport::Dependencies.autoload_paths += autoload_paths end # thor_args normalized the args Array to work with our Thor command # subclasses. # 1. The namespace is stripped # 2. The help is shifted in front if a help flag is detected def thor_args args = @given_args.clone # Allow calling for help via: # cli-template command help # cli-template command -h # cli-template command --help # cli-template command -D # # as well thor's normal way: # # cli-template help command help_args = args & help_flags if help_args.empty? args[0] = meth # reassigns the command without the namespace else # Allow using help flags at the end of the command to trigger help menu args -= help_flags # remove "help" and help flags from args args[0] = meth # first command will always be the meth now since # we removed the help flags args.unshift("help") end args.compact end def full_command # Removes any args that starts with -, those are option args. # Also remove "help" flag. args = @given_args.reject {|o| o =~ /^-/ } - help_flags command = args[0] # first argument should always be the command <%= project_class_name %>::Command.autocomplete(command) end # 1. look up Thor tasks # 2. look up Rake tasks - currently disabled # 3. help menu with all commands when both Thor and Rake tasks are not found # # Example: # # lookup("sub:hello") => Sub def lookup(full_command) thor_task_found = <%= project_class_name %>::Command.namespaced_commands.include?(full_command) if thor_task_found return <%= project_class_name %>::Command.klass_from_namespace(namespace) end rake_task_found = <%= project_class_name %>::RakeCommand.namespaced_commands.include?(full_command) if rake_task_found return <%= project_class_name %>::RakeCommand end end def version_flags ["--version", "-v"] end # ["-h", "-?", "--help", "-D", "help"] def help_flags Thor::HELP_MAPPINGS + ["help"] end def namespace return nil unless full_command if full_command.include?(':') words = full_command.split(':') words.pop words.join(':') end end def meth return nil unless full_command if full_command.include?(':') full_command.split(':').pop else full_command end end # Allow calling version via: # <%= project_name %> version # <%= project_name %> --version # <%= project_name %> -v def version_flag? args = @given_args args.length == 1 && !(args & version_flags).empty? end def main_help if version_flag? <%= project_class_name %>::Main.perform("version", ["version"]) return end shell = Thor::Shell::Basic.new shell.say "Commands:" shell.print_table(thor_list, :indent => 2, :truncate => true) # TODO: commenting out for now, feels weird to show the rake tasks # automatically also by default. Maybe add an option for this. # unless rake_list.empty? # shell.say "\nCommands via rake:" # shell.print_table(rake_list, :indent => 2, :truncate => true) # end shell.say "\n" shell.say Help.text(:main) + "\n" end def thor_list <%= project_class_name %>::Command.help_list(show_all_tasks) end def rake_list list = <%= project_class_name %>::RakeCommand.formatted_rake_tasks(show_all_tasks) list.map do |array| array[0] = "<%= project_name %> #{array[0]}" array end end def show_all_tasks @given_args.include?("--all") || @given_args.include?("-A") end end end