diff --git a/src/autocomplete.cpp b/src/autocomplete.cpp index 7cab974..66e70fa 100644 --- a/src/autocomplete.cpp +++ b/src/autocomplete.cpp @@ -14,15 +14,21 @@ namespace autocomplete { const std::set system_commands_noargs = {"templates","autocomplete_list_servers","autocomplete_list_services","autocomplete_list_commands"}; const std::set system_commands_always_available = {"help","edit"}; const std::set system_commands_require_config = {"server","templates","create-service","create-template","create-server","ssh","list"}; + const std::set system_commands_hidden = {"nuke","_allservicesstatus"}; + + const std::set service_commands_require_config = {"ssh","edit","nuke","_allservicesstatus"}; + + void merge_commands(std::set &commands, const std::set &new_commands) + { + commands.insert(new_commands.begin(), new_commands.end()); + } bool is_no_arg_cmd(std::string cmd) { return system_commands_noargs.find(cmd) != system_commands_noargs.end(); } -} - -bool dropshell::autocomplete(const std::vector &args) +bool autocomplete(const std::vector &args) { if (args.size() < 3) // dropshell autocomplete ??? { @@ -94,16 +100,16 @@ bool dropshell::autocomplete(const std::vector &args) return false; // catch-all. } -bool dropshell::autocomplete_list_commands() +bool autocomplete_list_commands() { std::set commands; dropshell::get_all_used_commands(commands); // add in commmands hard-coded and handled in main - commands.insert(autocomplete::system_commands_always_available.begin(), autocomplete::system_commands_always_available.end()); + autocomplete::merge_commands(commands, autocomplete::system_commands_always_available); if (dropshell::gConfig().is_config_set()) - commands.insert(autocomplete::system_commands_require_config.begin(), autocomplete::system_commands_require_config.end()); + autocomplete::merge_commands(commands, autocomplete::system_commands_require_config); for (const auto& command : commands) { std::cout << command << std::endl; @@ -111,3 +117,4 @@ bool dropshell::autocomplete_list_commands() return true; } +} // namespace autocomplete \ No newline at end of file diff --git a/src/autocomplete.hpp b/src/autocomplete.hpp index 8b30147..2150830 100644 --- a/src/autocomplete.hpp +++ b/src/autocomplete.hpp @@ -3,14 +3,26 @@ #include #include +#include +namespace autocomplete { -namespace dropshell { + extern const std::set system_commands_noargs; + extern const std::set system_commands_always_available; + extern const std::set system_commands_require_config; + extern const std::set system_commands_hidden; + + extern const std::set service_commands_require_config; + + void merge_commands(std::set &commands, const std::set &new_commands); + + bool is_no_arg_cmd(std::string cmd); bool autocomplete(const std::vector &args); bool autocomplete_list_commands(); -} // namespace dropshell +} + #endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index b19e33b..677db78 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,6 +16,7 @@ #include #include #include +#include namespace dropshell { @@ -45,7 +46,7 @@ bool print_help() { std::cout << std::endl; std::cout << " install SERVER [SERVICE] Install/reinstall/update service(s). Safe/non-destructive." << std::endl; std::cout << " uninstall SERVER [SERVICE] Uninstalls the service on the remote server. Leaves data intact." << std::endl; - std::cout << " nuke SERVER SERVICE Nuke the service on the remote server, deleting all remote data." << std::endl; + std::cout << " nuke SERVER SERVICE Nuke the service, deleting ALL local and remote data." << std::endl; std::cout << std::endl; std::cout << " COMMAND SERVER [SERVICE] Run a command on service(s), e.g." << std::endl; std::cout << " backup, restore, start, stop, logs" << std::endl; @@ -103,59 +104,84 @@ void printversion() { std::cout << "License: " << LICENSE << std::endl; } -#define HAPPYEXIT(CMD, RUNCMD) {if (safearg(argc,argv,1) == CMD) {RUNCMD; return 0;}} -#define BOOLEXIT(CMD, RUNCMD) {if (safearg(argc,argv,1) == CMD) {return (RUNCMD) ? 0 : 1;}} +auto command_match = [](const std::string& cmd_list, int argc, char* argv[]) -> bool { + std::istringstream iss(cmd_list); + std::string cmd_item; + while (iss >> cmd_item) { + if (cmd_item == safearg(argc, argv, 1)) { + return true; + } + } + return false; +}; + +#define BOOLEXIT(CMD_LIST, RUNCMD) { \ + if (command_match(CMD_LIST, argc, argv)) { \ + return (RUNCMD) ? 0 : 1; \ + } \ +} + +#define HAPPYEXIT(CMD_LIST, RUNCMD) { \ + if (command_match(CMD_LIST, argc, argv)) { \ + RUNCMD; \ + return 0; \ + } \ +} + +int edit_config() +{ + if (!gConfig().is_config_set()) + gConfig().save_config(false); // save defaults. + + std::string config_file = localfile::dropshell_json(); + if (!service_runner::edit_file(config_file) || !std::filesystem::exists(config_file)) + return die("Error: Failed to edit config file."); + + gConfig().load_config(); + if (!gConfig().is_config_set()) + return die("Error: Failed to load and parse edited config file!"); + + gConfig().save_config(true); + std::cout << "Successfully edited config file at " << config_file << std::endl; + return 0; +} int main(int argc, char* argv[]) { HAPPYEXIT("hash", hash_demo_raw(safearg(argc,argv,2))) HAPPYEXIT("makesafecmd", std::cout< argvec; - for (int i=0; i & server_definition_paths = gConfig().get_local_server_definition_paths(); if (server_definition_paths.size()>1) { // only show if there are multiple. std::cout << "Server definition paths: "; @@ -182,10 +208,7 @@ int main(int argc, char* argv[]) { return die("dropshell server: too many arguments"); } - if (cmd == "templates") { - gTemplateManager().list_templates(); - return 0; - } + HAPPYEXIT("templates", gTemplateManager().list_templates()); if (cmd == "create-template") { if (argc < 3) return die("Error: create-template requires a template name"); @@ -217,7 +240,8 @@ int main(int argc, char* argv[]) { // handle running a command. std::set commands; get_all_used_commands(commands); - commands.merge(std::set{"ssh","edit","_allservicesstatus","fullnuke"}); // handled by service_runner, but not in template_shell_commands. + + autocomplete::merge_commands(commands, autocomplete::service_commands_require_config); // handled by service_runner, but not in template_shell_commands. if (commands.count(cmd)) { std::set safe_commands = {"nuke", "fullnuke"};