#include "version.hpp" #include "config.hpp" #include "services.hpp" #include "servers.hpp" #include "utils/directories.hpp" #include "templates.hpp" #include "utils/utils.hpp" #include "autocomplete.hpp" #include "utils/hash.hpp" #include "command_registry.hpp" #include "output.hpp" #include #include #include #include #include #include #include #include #include namespace dropshell { extern const std::string VERSION; extern const std::string RELEASE_DATE; extern const std::string AUTHOR; extern const std::string LICENSE; int main(int argc, char* argv[]) { try { // silently attempt to load the config file and templates. gConfig().load_config(); if (gConfig().is_config_set()) gTemplateManager().load_sources(); // process the command line arguments. std::vector args(argv, argv + argc); if (args.size() < 2) args.push_back("help"); ASSERT(args.size() > 1, "No command provided, logic error."); CommandContext ctx{args[0], args[1], std::vector(args.begin() + 2, args.end())}; if (ctx.command == "autocomplete") { CommandRegistry::instance().autocomplete(ctx); return 0; } const CommandInfo* cmdinfo = CommandRegistry::instance().find_command(ctx.command); if (!cmdinfo) { error << "Unknown command: " << ctx.command << std::endl; return 1; } if (cmdinfo->requires_config && !gConfig().is_config_set()) { error << "Valid dropshell configuration required for command: " << ctx.command << std::endl; info << "Please run 'dropshell edit' to set up the dropshell configuration." << std::endl; return 1; } if (cmdinfo->requires_install && !gConfig().is_agent_installed()) { error << "Dropshell agent not installed for command: " << ctx.command << std::endl; info << "Please run 'dropshell install' to install the local dropshell agent." << std::endl; return 1; } int arg_count = ctx.args.size(); if (arg_count < cmdinfo->min_args || (cmdinfo->max_args != -1 && arg_count > cmdinfo->max_args)) { error << "Invalid number of arguments for command: " << ctx.command << std::endl; debug << "(" << ctx.args.size() << " args provided, " << ctx.command << " requires " << (cmdinfo->min_args) << " to " << (cmdinfo->max_args) << " args)" << std::endl; info << "Usage: " << std::endl; info << " "; info << left_align(cmdinfo->help_usage,30); info << cmdinfo->help_description << std::endl; return 1; } return cmdinfo->handler(ctx); } catch (const std::exception& e) { error << "Uncaught Exception: " << e.what() << std::endl; return 1; } } // ------------------------------------------------------------------------------------------------ struct ServerAndServices { std::string server_name; std::vector servicelist; }; bool getCLIServices(const std::string & arg2, const std::string & arg3, ServerAndServices & server_and_services) { if (arg2.empty()) return false; server_and_services.server_name = arg2; if (arg3.empty()) { server_and_services.servicelist = get_server_services_info(arg2); } else { server_and_services.servicelist.push_back(get_service_info(arg2, arg3)); } return true; } 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; \ } \ } } // namespace dropshell int main(int argc, char* argv[]) { return dropshell::main(argc, argv); }