require 'hammer_cli/abstract' require 'readline' module HammerCLI class ShellMainCommand < AbstractCommand class HelpCommand < AbstractCommand command_name "help" desc "Print help for commands" parameter "[COMMAND] ...", "command" def execute ShellMainCommand.run('', command_list << '-h') HammerCLI::EX_OK end end class ExitCommand < AbstractCommand command_name "exit" desc "Exit interactive shell" def execute exit HammerCLI::EX_OK end end class AuthCommand < AbstractCommand command_name "auth" desc "Login and logout actions" class LoginCommand < AbstractCommand command_name "login" desc "Set credentials" def execute context[:username] = ask_username context[:password] = ask_password HammerCLI::EX_OK end end class LogoutCommand < AbstractCommand command_name "logout" desc "Wipe your credentials" def execute context[:username] = nil context[:password] = nil if username(false) print_message("Credentials deleted, using defaults now.") print_message("You are logged in as [ %s ]." % username(false)) else print_message("Credentials deleted.") end HammerCLI::EX_OK end end class InfoCommand < AbstractCommand command_name "status" desc "Information about current user" def execute if username(false) print_message("You are logged in as [ %s ]." % username(false)) else print_message("You are currently not logged in.\nUse 'auth login' to set credentials.") end HammerCLI::EX_OK end end autoload_subcommands end def self.load_commands(main_cls) cmds = main_cls.recognised_subcommands.select do |sub_cmd| !(sub_cmd.subcommand_class <= HammerCLI::ShellCommand) end self.recognised_subcommands.push(*cmds) end autoload_subcommands end class ShellCommand < AbstractCommand def execute ShellMainCommand.load_commands(HammerCLI::MainCommand) Readline.completion_append_character = '' Readline.completer_word_break_characters = ' ' Readline.completion_proc = complete_proc stty_save = `stty -g`.chomp begin print_welcome_message while line = Readline.readline(prompt, true) ShellMainCommand.run('', line.split, context) unless line.start_with? 'shell' or line.strip.empty? end rescue Interrupt => e puts system('stty', stty_save) # Restore exit end end private def prompt 'hammer> ' end def print_welcome_message print_message("Welcome to the hammer interactive shell") print_message("Type 'help' for usage information") end def common_prefix(results) results.delete_if{ |r| !r[0].start_with?(results[0][0][0]) }.length == results.length end def complete_proc completer = Completer.new(ShellMainCommand) Proc.new do |last_word| completer.complete(Readline.line_buffer) end end end HammerCLI::MainCommand.subcommand "shell", "Interactive shell", HammerCLI::ShellCommand end