diff --git a/src/main.cpp b/src/main.cpp index f1c2935..b21a78f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -244,8 +244,6 @@ int main(int argc, char* argv[]) { std::cerr << command << " "; } std::cerr << std::endl; - // print help - dropshell::print_help(); return 1; } catch (const std::exception& e) { diff --git a/src/services.cpp b/src/services.cpp index 8a52583..5b2789c 100644 --- a/src/services.cpp +++ b/src/services.cpp @@ -95,7 +95,7 @@ ServiceInfo get_service_info(const std::string &server_name, const std::string & // find the template path service.local_template_path = tinfo.local_template_path; - service.local_template_default_env_path = tinfo.local_template_default_env_path; + service.local_template_default_env_path = tinfo.local_template_path + "/_default.env"; return service; } diff --git a/src/templates.cpp b/src/templates.cpp index 09a853d..0ddf03f 100644 --- a/src/templates.cpp +++ b/src/templates.cpp @@ -1,188 +1,193 @@ -#include "templates.hpp" -#include "config.hpp" -#include "utils/directories.hpp" -#include "utils/utils.hpp" -#include -#include -#include -#include -#include -#include -#include + #include "templates.hpp" + #include "config.hpp" + #include "utils/directories.hpp" + #include "utils/utils.hpp" + #include + #include + #include + #include + #include + #include + #include -namespace dropshell { + namespace dropshell { -bool get_templates(std::vector& templates) { - templates.clear(); + bool get_templates(std::vector& templates) { + templates.clear(); + + // Helper function to add templates from a directory + auto add_templates_from_dir = [&templates](const std::string& dir_path) { + if (!std::filesystem::exists(dir_path)) + return; + + for (const auto& entry : std::filesystem::directory_iterator(dir_path)) + if (entry.is_directory()) { + + template_info info(entry.path().filename().string(), entry.path().string()); + + // Check if template with same name already exists + bool duplicate = false; + auto it = std::find_if(templates.begin(), templates.end(), + [&info](const template_info& t) { return t.template_name == info.template_name; }); + duplicate = (it!=templates.end()); + + if (!duplicate) + templates.push_back(info); + } + }; + + // add templates from the local config directories + std::vector template_config_directories; + get_all_template_config_directories(template_config_directories); + for (const auto& path : template_config_directories) { + add_templates_from_dir(path); + } - // Helper function to add templates from a directory - auto add_templates_from_dir = [&templates](const std::string& dir_path) { - if (!std::filesystem::exists(dir_path)) { + return true; + } + + + bool get_template_info(const std::string& template_name, template_info& info) { + // add templates from the local config directories + std::vector paths_to_search; + get_all_template_config_directories(paths_to_search); + + for (const auto& path : paths_to_search) { + std::filesystem::path full_path = path + "/" + template_name; + if (std::filesystem::exists(full_path)) + { + info.template_name = template_name; + info.local_template_path = full_path.string(); + return true; + } + } + std::cout << "Warning: Template '" << template_name << "' not found" << std::endl; + return false; + } + + bool template_command_exists(const std::string &template_name, const std::string &command) + { + template_info info; + if (!get_template_info(template_name, info)) { + return false; + } + + std::string path = info.local_template_path + "/" + command + ".sh"; + return (std::filesystem::exists(path)); + } + + void list_templates() { + std::vector templates; + + if (!get_templates(templates)) { + std::cerr << "Error: Failed to get templates" << std::endl; return; } - for (const auto& entry : std::filesystem::directory_iterator(dir_path)) { - if (entry.is_directory()) { - template_info info; - info.template_name = entry.path().filename().string(); - info.local_template_path = entry.path().string(); - info.local_template_default_env_path = entry.path() / "_default.env"; - - // Check if template with same name already exists - bool duplicate = false; - auto it = std::find_if(templates.begin(), templates.end(), - [&info](const template_info& t) { return t.template_name == info.template_name; }); - duplicate = (it!=templates.end()); - //duplicate |= (info.template_name=="example"); // don't include the example template! + if (templates.empty()) { + std::cout << "No templates found." << std::endl; + return; + } + + std::cout << "Available templates:" << std::endl; + std::cout << std::left << std::setw(20) << "Name" << "Path" << std::endl; + std::cout << std::string(60, '-') << std::endl; + + for (const auto& t : templates) { + std::cout << std::left << std::setw(20) << t.template_name << t.local_template_path << std::endl; + } + } - if (!duplicate) { - templates.push_back(info); - } + void create_template(const std::string& template_name) { + // 1. Create a new directory in the user templates directory + std::vector local_config_directories = get_global_config()->get_local_config_directories(); + + if (local_config_directories.empty()) { + std::cerr << "Error: No local config directories found" << std::endl; + std::cerr << "Run 'dropshell init' to initialise DropShell" << std::endl; + return; + } + + template_info info; + if (get_template_info(template_name, info)) { + std::cerr << "Error: Template '" << template_name << "' already exists at " << info.local_template_path << std::endl; + return; + } + + std::string user_templates_dir = local_config_directories[0] + "/templates"; + std::string new_template_path = user_templates_dir + "/" + template_name; + + // Create the new template directory + std::filesystem::create_directories(new_template_path); + + // 2. Copy the example template from the system templates directory + std::string system_templates_dir = get_local_system_templates_path(); + std::string example_template_path = system_templates_dir + "/example"; + + if (!std::filesystem::exists(example_template_path)) { + std::cerr << "Error: Example template not found at " << example_template_path << std::endl; + return; + } + + // Copy all files from example template to new template + for (const auto& entry : std::filesystem::recursive_directory_iterator(example_template_path)) { + std::string relative_path = entry.path().string().substr(example_template_path.length()); + std::string target_path = new_template_path + relative_path; + + if (entry.is_directory()) { + std::filesystem::create_directory(target_path); + } else { + std::filesystem::copy_file(entry.path(), target_path); } } - }; - // add templates from the local config directories - for (int i = 0; i < getNumConfigDirectories(); i++) { - std::string path = get_local_config_templates_path(i); - if (path.empty()) { - std::cerr << "Error: Templates directory not found: " << path << std::endl; - return false; + // modify the TEMPLATE=example line in the service.env file to TEMPLATE= + std::string search_string = "TEMPLATE="; + std::string replacement_line = "TEMPLATE=" + template_name; + // replace the line in the example/service.env file with the replacement line + std::string service_env_path = new_template_path + "/example/service.env"; + if (!replace_line_in_file(service_env_path, search_string, replacement_line)) { + std::cerr << "Error: Failed to replace TEMPLATE= line in service.env file" << std::endl; + return; } - add_templates_from_dir(path); + + // 3. Print out the README.txt file and the path + std::string readme_path = new_template_path + "/README.txt"; + if (std::filesystem::exists(readme_path)) { + std::cout << "\nREADME contents:" << std::endl; + std::cout << std::string(60, '-') << std::endl; + + std::ifstream readme_file(readme_path); + if (readme_file.is_open()) { + std::string line; + while (std::getline(readme_file, line)) { + std::cout << line << std::endl; + } + readme_file.close(); + } + std::cout << std::string(60, '-') << std::endl; + } else { + std::cout << "No README.txt file found in the template." << std::endl; + } + + std::cout << std::endl; + std::cout << "Template '" << template_name << "' created at " << new_template_path << std::endl; } - // add templates from the system templates directory - add_templates_from_dir(get_local_system_templates_path()); - - return true; -} - -bool get_template_info(const std::string& template_name, template_info& info) { - std::vector templates; - if (!get_templates(templates)) { - return false; - } - - auto it = std::find_if(templates.begin(), templates.end(), - [&template_name](const template_info& t) { return t.template_name == template_name; }); - - if (it != templates.end()) { - info = *it; + bool get_all_template_config_directories(std::vector &template_config_directories) + { + template_config_directories.clear(); + for (int i = 0; i < getNumConfigDirectories(); i++) { + std::string config_templates_path = get_local_config_templates_path(i); + if (config_templates_path.empty()) { + std::cerr << "Error: Templates directory not found: " << config_templates_path << std::endl; + return false; + } + template_config_directories.push_back(config_templates_path); + } + template_config_directories.push_back(get_local_system_templates_path()); return true; } - - return false; -} -bool template_command_exists(const std::string &template_name, const std::string &command) -{ - template_info info; - if (!get_template_info(template_name, info)) { - return false; - } - - std::string path = info.local_template_path + "/" + command + ".sh"; - return (std::filesystem::exists(path)); -} - -void list_templates() { - std::vector templates; - - if (!get_templates(templates)) { - std::cerr << "Error: Failed to get templates" << std::endl; - return; - } - - if (templates.empty()) { - std::cout << "No templates found." << std::endl; - return; - } - - std::cout << "Available templates:" << std::endl; - std::cout << std::left << std::setw(20) << "Name" << "Path" << std::endl; - std::cout << std::string(60, '-') << std::endl; - - for (const auto& t : templates) { - std::cout << std::left << std::setw(20) << t.template_name << t.local_template_path << std::endl; - } -} - -void create_template(const std::string& template_name) { - // 1. Create a new directory in the user templates directory - std::vector local_config_directories = get_global_config()->get_local_config_directories(); - - if (local_config_directories.empty()) { - std::cerr << "Error: No local config directories found" << std::endl; - std::cerr << "Run 'dropshell init' to initialise DropShell" << std::endl; - return; - } - - template_info info; - if (get_template_info(template_name, info)) { - std::cerr << "Error: Template '" << template_name << "' already exists at " << info.local_template_path << std::endl; - return; - } - - std::string user_templates_dir = local_config_directories[0] + "/templates"; - std::string new_template_path = user_templates_dir + "/" + template_name; - - // Create the new template directory - std::filesystem::create_directories(new_template_path); - - // 2. Copy the example template from the system templates directory - std::string system_templates_dir = get_local_system_templates_path(); - std::string example_template_path = system_templates_dir + "/example"; - - if (!std::filesystem::exists(example_template_path)) { - std::cerr << "Error: Example template not found at " << example_template_path << std::endl; - return; - } - - // Copy all files from example template to new template - for (const auto& entry : std::filesystem::recursive_directory_iterator(example_template_path)) { - std::string relative_path = entry.path().string().substr(example_template_path.length()); - std::string target_path = new_template_path + relative_path; - - if (entry.is_directory()) { - std::filesystem::create_directory(target_path); - } else { - std::filesystem::copy_file(entry.path(), target_path); - } - } - - // modify the TEMPLATE=example line in the service.env file to TEMPLATE= - std::string search_string = "TEMPLATE="; - std::string replacement_line = "TEMPLATE=" + template_name; - // replace the line in the example/service.env file with the replacement line - std::string service_env_path = new_template_path + "/example/service.env"; - if (!replace_line_in_file(service_env_path, search_string, replacement_line)) { - std::cerr << "Error: Failed to replace TEMPLATE= line in service.env file" << std::endl; - return; - } - - // 3. Print out the README.txt file and the path - std::string readme_path = new_template_path + "/README.txt"; - if (std::filesystem::exists(readme_path)) { - std::cout << "\nREADME contents:" << std::endl; - std::cout << std::string(60, '-') << std::endl; - - std::ifstream readme_file(readme_path); - if (readme_file.is_open()) { - std::string line; - while (std::getline(readme_file, line)) { - std::cout << line << std::endl; - } - readme_file.close(); - } - std::cout << std::string(60, '-') << std::endl; - } else { - std::cout << "No README.txt file found in the template." << std::endl; - } - - std::cout << std::endl; - std::cout << "Template '" << template_name << "' created at " << new_template_path << std::endl; -} - -} // namespace dropshell \ No newline at end of file + } // namespace dropshell diff --git a/src/templates.hpp b/src/templates.hpp index 6babee8..fc44d36 100644 --- a/src/templates.hpp +++ b/src/templates.hpp @@ -1,35 +1,36 @@ #include #include +#include namespace dropshell { class template_info { public: + template_info() {} + template_info(std::string n, std::string p) : template_name(n), local_template_path(p) {} + std::string template_name; std::string local_template_path; - std::string local_template_default_env_path; }; -// templates are stored in two locations: -// 1. /opt/dropshell/templates -// 2. CONFIG_DIR/usertemplates (if it exists) -// we aggregate the templates from both locations and return them in the order of priority. -// if a template exists in both locations, the one in the user directory takes precedence. -// the template name is just the subfolder name in the templates directory. -// the template path is the path of that subfolder. + // templates are stored in multiple locations: + // 1. /opt/dropshell/templates + // 2. CONFIG_DIR/templates -bool get_templates(std::vector& templates); -bool get_template_info(const std::string& template_name, template_info& info); -bool template_command_exists(const std::string& template_name,const std::string& command); -void list_templates(); + bool get_templates(std::vector& templates); + bool get_template_info(const std::string& template_name, template_info& info); + bool template_command_exists(const std::string& template_name,const std::string& command); + void list_templates(); -// create a template -// 1. create a new directory in the user templates directory -// 2. copy the example template from the system templates directory into the new directory -// 3. print out the README.txt file in the new template directory, and the path to the new template -void create_template(const std::string& template_name); + // create a template + // 1. create a new directory in the user templates directory + // 2. copy the example template from the system templates directory into the new directory + // 3. print out the README.txt file in the new template directory, and the path to the new template + void create_template(const std::string& template_name); + + bool get_all_template_config_directories(std::vector& template_config_directories); } // namespace dropshell