.
Some checks failed
Dropshell Test / Build_and_Test (push) Failing after 21s

This commit is contained in:
Your Name 2025-05-11 12:48:30 +12:00
parent 78dbf4aff3
commit 46396369d7
6 changed files with 229 additions and 53 deletions

View File

@ -29,7 +29,9 @@ struct EditCommandRegister {
false, // hidden
false, // requires_config
0, // min_args (after command)
2 // max_args (after command)
2, // max_args (after command)
"edit [SERVER] [SERVICE]",
"Edit dropshell, server or service configuration"
});
}
} edit_command_register;

136
src/commands/help.cpp Normal file
View File

@ -0,0 +1,136 @@
#include "command_registry.hpp"
#include "config.hpp"
#include "utils/utils.hpp"
#include "service_runner.hpp"
#include "utils/directories.hpp"
#include "standard_autocomplete.hpp"
#include "version.hpp"
#include <unistd.h>
#include <cstring>
#include <iostream>
#include <sstream>
#include <filesystem>
#include <libassert/assert.hpp>
namespace dropshell {
void help_autocomplete(const CommandContext& ctx);
int help_handler(const CommandContext& ctx);
static std::vector<std::string> help_name_list={"help","h","--help","-h"};
// Static registration
struct HelpCommandRegister {
HelpCommandRegister() {
CommandRegistry::instance().register_command({
help_name_list,
help_handler,
help_autocomplete,
false, // hidden
false, // requires_config
0, // min_args (after command)
0, // max_args (after command)
"help",
"Show help for dropshell"
});
}
} help_command_register;
void help_autocomplete(const CommandContext& ctx) {
if (ctx.args.size() == 1) {
std::cout << "help" << std::endl;
}
return;
}
void show_command(const std::string& cmd) {
const auto& cmd_info = CommandRegistry::instance().find_command(cmd);
if (!cmd_info)
std::cout << "Unknown command: " << cmd << std::endl;
std::cout << " ";
print_left_aligned(cmd_info->help_usage, 30);
std::cout << cmd_info->help_description << std::endl;
}
extern const std::string VERSION;
extern const std::string RELEASE_DATE;
extern const std::string AUTHOR;
extern const std::string LICENSE;
int help_handler(const CommandContext& ctx) {
std::cout << std::endl;
maketitle("DropShell version " + VERSION);
std::cout << std::endl;
std::cout << "A tool for managing remote servers, by " << AUTHOR << std::endl;
std::cout << std::endl;
std::cout << "dropshell ..." << std::endl;
show_command("help");
show_command("edit");
if (gConfig().is_config_set()) {
// show more!
}
return 0;
}
// void show_command(const std::string& cmd) {
// const auto& cmd_info = CommandRegistry::instance().find_command(cmd);
// if (cmd_info) {
// std::cout << " " << cmd_info->help_usage
// << std::string(' ', std::min(1,(int)(30-cmd_info->help_usage.length())))
// << cmd_info->help_description << std::endl;
// }
// }
// bool print_help() {
// std::cout << std::endl;
// maketitle("DropShell version " + VERSION);
// std::cout << std::endl;
// std::cout << "A tool for managing server configurations" << std::endl;
// std::cout << std::endl;
// std::cout << "dropshell ..." << std::endl;
// show_command("help");
// show_command("edit");
// if (gConfig().is_config_set()) {
// std::cout << " templates List all available templates" << std::endl;
// std::cout << std::endl;
// std::cout << std::endl;
// std::cout << "Service commands: (if no service is specified, all services for the server are affected)" << std::endl;
// std::cout << " list [SERVER] [SERVICE] List status/details of all servers/server/service." << std::endl;
// std::cout << " edit [SERVER] [SERVICE] Edit the configuration of dropshell/server/service." << std::endl;
// 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, 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;
// std::cout << std::endl;
// std::cout << " ssh SERVER SERVICE Launch an interactive shell on a server or service" << std::endl;
// std::cout << std::endl;
// std::cout << "Creation commands: (apply to the first local config directory)"<<std::endl;
// std::cout << " create-template TEMPLATE" << std::endl;
// std::cout << " create-server SERVER" << std::endl;
// std::cout << " create-service SERVER TEMPLATE SERVICE" << std::endl;
// }
// else {
// show_command("help");
// show_command("edit");
// std::cout << std::endl;
// std::cout << "Other commands available once initialised." << std::endl;
// }
// return true;
// }
} // namespace dropshell

View File

@ -26,55 +26,69 @@ extern const std::string RELEASE_DATE;
extern const std::string AUTHOR;
extern const std::string LICENSE;
void show_command(const std::string& cmd) {
const auto& cmd_info = CommandRegistry::instance().find_command(cmd);
if (cmd_info) {
std::cout << " " << cmd_info->help_usage
<< std::string(' ', std::min(1,(int)(30-cmd_info->help_usage.length())))
<< cmd_info->help_description << std::endl;
}
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<std::string> args(argv, argv + argc);
if (args.size() < 2)
args.push_back("help");
std::string cmd = args[1];
if (cmd == "autocomplete") {
CommandRegistry::instance().autocomplete(args);
return 0;
}
const CommandInfo* info = CommandRegistry::instance().find_command(cmd);
if (!info) {
std::cerr << "Unknown command: " << cmd << std::endl;
return 1;
}
if (info->requires_config && !gConfig().is_config_set()) {
std::cerr << "Configuration required for command: " << cmd << std::endl;
std::cerr << "Please run 'dropshell edit' to set up the dropshell configuration." << std::endl;
return 1;
}
int arg_count = args.size() - 2;
if (arg_count < info->min_args || (info->max_args != -1 && arg_count > info->max_args)) {
std::cerr << "Invalid number of arguments for command: " << cmd << std::endl;
std::cerr << "Usage: " << std::endl;
std::cout << " " << info->help_usage
<< std::string(' ', std::max(1, (int)(30 - info->help_usage.length())))
<< info->help_description << std::endl;
return 1;
}
CommandContext ctx{args};
return info->handler(ctx);
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}
}
bool print_help() {
std::cout << std::endl;
maketitle("DropShell version " + VERSION);
std::cout << std::endl;
std::cout << "A tool for managing server configurations" << std::endl;
std::cout << std::endl;
std::cout << "dropshell ..." << std::endl;
show_command("help");
show_command("edit");
if (gConfig().is_config_set()) {
std::cout << " templates List all available templates" << std::endl;
std::cout << std::endl;
std::cout << std::endl;
std::cout << "Service commands: (if no service is specified, all services for the server are affected)" << std::endl;
std::cout << " list [SERVER] [SERVICE] List status/details of all servers/server/service." << std::endl;
std::cout << " edit [SERVER] [SERVICE] Edit the configuration of dropshell/server/service." << std::endl;
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, 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;
std::cout << std::endl;
std::cout << " ssh SERVER SERVICE Launch an interactive shell on a server or service" << std::endl;
std::cout << std::endl;
std::cout << "Creation commands: (apply to the first local config directory)"<<std::endl;
std::cout << " create-template TEMPLATE" << std::endl;
std::cout << " create-server SERVER" << std::endl;
std::cout << " create-service SERVER TEMPLATE SERVICE" << std::endl;
}
else {
show_command("help");
show_command("edit");
std::cout << std::endl;
std::cout << "Other commands available once initialised." << std::endl;
}
return true;
}
// ------------------------------------------------------------------------------------------------
struct ServerAndServices {
std::string server_name;
@ -127,12 +141,13 @@ auto command_match = [](const std::string& cmd_list, int argc, char* argv[]) ->
}
int main(int argc, char* argv[]) {
int old_main(int argc, char* argv[]) {
HAPPYEXIT("hash", hash_demo_raw(safearg(argc,argv,2)))
HAPPYEXIT("makesafecmd", std::cout<<makesafecmd(safearg(argc,argv,2))<<std::endl)
HAPPYEXIT("version", printversion())
BOOLEXIT("test-template", gTemplateManager().test_template(safearg(argc,argv,2)))
BOOLEXIT("help -h --help h halp", print_help())
ASSERT(safearg(argc,argv,1) != "assert", "Hello! Here is an assert.");
try {
@ -141,9 +156,6 @@ int main(int argc, char* argv[]) {
if (gConfig().is_config_set())
gTemplateManager().load_sources();
if (argc < 2)
return print_help() ? 0 : 1;
std::string cmd = argv[1];
if (cmd == "autocomplete")

View File

@ -16,7 +16,7 @@
#include "services.hpp"
#include "utils/directories.hpp"
#include "utils/utils.hpp"
#include "command_registry.hpp"
namespace fs = std::filesystem;

View File

@ -334,4 +334,26 @@ std::string safearg(int argc, char *argv[], int index)
return argv[index];
}
void print_left_aligned(const std::string & str, int width) {
std::cout << str;
if (static_cast<int>(str.size()) < width)
std::cout << std::string(width - str.size(), ' ');
}
void print_centered(const std::string & str, int width) {
int pad = width - static_cast<int>(str.size());
int pad_left = pad > 0 ? pad / 2 : 0;
int pad_right = pad > 0 ? pad - pad_left : 0;
std::cout << std::string(pad_left, ' ') << str << std::string(pad_right, ' ');
}
void print_right_aligned(const std::string & str, int width) {
if (static_cast<int>(str.size()) < width)
std::cout << std::string(width - str.size(), ' ');
std::cout << str;
}
} // namespace dropshell

View File

@ -45,4 +45,8 @@ int die(const std::string & msg);
std::string safearg(int argc, char *argv[], int index);
std::string safearg(const std::vector<std::string> & args, int index);
void print_left_aligned(const std::string & str, int width);
void print_centered(const std::string & str, int width);
void print_right_aligned(const std::string & str, int width);
} // namespace dropshell