From 9e6281c846a12030bb1f1b0b427c40ea14bd4f6a Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 26 Apr 2025 08:34:02 +1200 Subject: [PATCH] autocomplete --- src/main.cpp | 12 ++++++++---- src/services.cpp | 27 ++++++++++++++------------- src/services.hpp | 2 +- src/utils/directories.hpp | 21 ++++++++++++++++++++- src/utils/readmes.cpp | 36 ++++++++++++++++++++++++++++++++++++ src/utils/readmes.hpp | 12 ++++++++++++ src/utils/utils.cpp | 9 +++++++++ src/utils/utils.hpp | 2 ++ 8 files changed, 102 insertions(+), 19 deletions(-) create mode 100644 src/utils/readmes.cpp create mode 100644 src/utils/readmes.hpp diff --git a/src/main.cpp b/src/main.cpp index 568e216..446d325 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,6 +6,7 @@ #include "utils/directories.hpp" #include "templates.hpp" #include "utils/utils.hpp" +#include "utils/readmes.hpp" #include #include @@ -41,7 +42,7 @@ void print_help() { std::cout << "Creation commands: (apply to the first local config directory)"<save_config(); std::cout << "Config directory added: " << cfg->get_local_config_directories().back() << std::endl; + dropshell::create_readme_local_config_dir(cfg->get_local_config_directories().back()); + if (cfg->get_local_config_directories().size() ==1) std::cout << "DropShell is now initialised and you can add a server with 'dropshell create-server '" << std::endl; else @@ -237,11 +240,12 @@ int main(int argc, char* argv[]) { } if (cmd == "create-service") { - if (argc < 4) { - std::cerr << "Error: create-service requires a server name and service name" << std::endl; + if (argc < 5) { + std::cerr << "Error: not enough arguments." << std::endl; + std::cerr << "dropshell create-service server template service" << std::endl; return 1; } - dropshell::create_service(argv[2], argv[3]); + dropshell::create_service(argv[2], argv[3], argv[4]); return 0; } diff --git a/src/services.cpp b/src/services.cpp index a192220..98b48da 100644 --- a/src/services.cpp +++ b/src/services.cpp @@ -132,18 +132,12 @@ std::vector list_backups(const std::string &server_name, const std: return backups; } -bool create_service(const std::string &server_name, const std::string &service_name) +bool create_service(const std::string &server_name, const std::string &template_name, const std::string &service_name) { - if (server_name.empty() || service_name.empty()) + if (server_name.empty() || template_name.empty() || service_name.empty()) return false; std::string service_dir = get_local_service_path(server_name, service_name); - if (!service_dir.empty() && fs::exists(service_dir)) - { - std::cerr << "Error: Service already exists: " << service_name << std::endl; - std::cerr << "Current service path: " << service_dir << std::endl; - return false; - } if (service_dir.empty()) { @@ -154,13 +148,20 @@ bool create_service(const std::string &server_name, const std::string &service_n return false; } - template_info tinfo; - if (!get_template_info(service_name, tinfo)) + if (fs::exists(service_dir)) { - std::cerr << "Error: Template for service '" << service_name << "' not found" << std::endl; - std::cerr << "Please check the service name is correct and try again" << std::endl; + std::cerr << "Error: Service already exists: " << service_name << std::endl; + std::cerr << "Current service path: " << service_dir << std::endl; + return false; + } + + template_info tinfo; + if (!get_template_info(template_name, tinfo)) + { + std::cerr << "Error: Template '" << template_name << "' not found" << std::endl; + std::cerr << "Please check the template name is correct and try again" << std::endl; std::cerr << "You can list all templates with 'dropshell templates'" << std::endl; - std::cerr << "You can create a new template with 'dropshell create-template " << service_name << "'" << std::endl; + std::cerr << "You can create a new template with 'dropshell create-template " << template_name << "'" << std::endl; return false; } diff --git a/src/services.hpp b/src/services.hpp index cd4010e..c2d1932 100644 --- a/src/services.hpp +++ b/src/services.hpp @@ -21,7 +21,7 @@ namespace dropshell { // list all backups for a given server and service std::vector list_backups(const std::string& server_name, const std::string& service_name); - bool create_service(const std::string& server_name, const std::string& service_name); + bool create_service(const std::string& server_name, const std::string& template_name, const std::string& service_name); } // namespace dropshell diff --git a/src/utils/directories.hpp b/src/utils/directories.hpp index 871c053..e2d2afa 100644 --- a/src/utils/directories.hpp +++ b/src/utils/directories.hpp @@ -11,6 +11,23 @@ namespace dropshell { std::string get_local_backup_path(); + + // local config directories + // config_path + // |-- servers + // | |-- server_name + // | |-- server.env + // | |-- services + // | |-- service_name + // | |-- service.env + // | |-- (other config files for specific server&service) + // |-- templates + // | |-- template_name + // | |-- (script files) + // | |-- example + // | |-- service.env + // | |-- (other service config files) + int getNumConfigDirectories(); std::string get_local_config_path(int index); std::string get_local_config_templates_path(int index); @@ -30,9 +47,11 @@ namespace dropshell { // |-- service name // |-- config <-- this is passed as argument to all scripts // |-- service.env - // |-- (user config files) // |-- template // |-- (script files) + // |-- example + // |-- service.env + // |-- (other config files for specific server&service) std::string get_remote_DROPSHELL_path(const std::string &server_name); std::string get_remote_services_path(const std::string &server_name); std::string get_remote_service_path(const std::string &server_name, const std::string &service_name); diff --git a/src/utils/readmes.cpp b/src/utils/readmes.cpp new file mode 100644 index 0000000..902a133 --- /dev/null +++ b/src/utils/readmes.cpp @@ -0,0 +1,36 @@ +#include "readmes.hpp" + +#include +#include +void dropshell::create_readme_local_config_dir(const std::string &readme_path) +{ + if (std::filesystem::exists(readme_path)) + return; // already exists + + std::ofstream readme_file(readme_path); + // use heredoc to write the readme + readme_file << R"( + +use this directory to store your local config files for your servers and services. + dropshell create-server + dropshell create-template + dropshell create-service + +config_path + |-- servers + | |-- server_name + | |-- server.env + | |-- services + | |-- service_name + | |-- service.env + | |-- (other config files for specific server&service) + |-- templates + | |-- template_name + | |-- (script files) + | |-- example + | |-- service.env + | |-- (other service config files) + + )" << std::endl; + readme_file.close(); +} \ No newline at end of file diff --git a/src/utils/readmes.hpp b/src/utils/readmes.hpp new file mode 100644 index 0000000..7125c1d --- /dev/null +++ b/src/utils/readmes.hpp @@ -0,0 +1,12 @@ +#ifndef READMES_HPP +#define READMES_HPP + +#include + +namespace dropshell { + + void create_readme_local_config_dir(const std::string &readme_path); + +} // namespace dropshell + +#endif \ No newline at end of file diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp index 76f0819..fd39a09 100644 --- a/src/utils/utils.cpp +++ b/src/utils/utils.cpp @@ -158,4 +158,13 @@ void recursive_copy(const std::string & source, const std::string & destination) } } +void ensure_directories_exist(std::vector directories) +{ + for (const auto& directory : directories) { + if (!std::filesystem::exists(directory)) { + std::filesystem::create_directories(directory); + } + } +} + } // namespace dropshell \ No newline at end of file diff --git a/src/utils/utils.hpp b/src/utils/utils.hpp index bd85ac2..778a8df 100644 --- a/src/utils/utils.hpp +++ b/src/utils/utils.hpp @@ -26,4 +26,6 @@ int str2int(const std::string & str); void recursive_copy(const std::string & source, const std::string & destination); +void ensure_directories_exist(std::vector directories); + } // namespace dropshell \ No newline at end of file