Fairly big refactor...
This commit is contained in:
160
src/utils/directories.cpp
Normal file
160
src/utils/directories.cpp
Normal file
@@ -0,0 +1,160 @@
|
||||
#include "directories.hpp"
|
||||
#include "config.hpp"
|
||||
#include "server_env.hpp"
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace dropshell {
|
||||
|
||||
|
||||
|
||||
std::string get_local_dropshell_config_path()
|
||||
{
|
||||
// Try ~/.config/dropshell/dropshell.conf
|
||||
const char* home = std::getenv("HOME");
|
||||
if (home) {
|
||||
fs::path user_path = fs::path(home) / ".config" / "dropshell" / "dropshell.env";
|
||||
return user_path.string();
|
||||
}
|
||||
std::cerr << "Warning: Couldn't determine user directory" << std::endl;
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string get_local_system_templates_path()
|
||||
{
|
||||
return "/opt/dropshell/templates";
|
||||
}
|
||||
|
||||
std::string get_local_config_path()
|
||||
{
|
||||
config *cfg = get_global_config();
|
||||
std::string user_dir;
|
||||
if (!cfg->get_local_config_directory(user_dir)) {
|
||||
return std::string();
|
||||
}
|
||||
return user_dir;
|
||||
}
|
||||
|
||||
std::string get_local_config_templates_path()
|
||||
{
|
||||
std::string config_path = get_local_config_path();
|
||||
if (config_path.empty()) {
|
||||
return std::string();
|
||||
}
|
||||
return config_path + "/templates";
|
||||
}
|
||||
|
||||
std::string get_local_config_servers_path()
|
||||
{
|
||||
std::string config_path = get_local_config_path();
|
||||
if (config_path.empty()) {
|
||||
return std::string();
|
||||
}
|
||||
return config_path + "/servers";
|
||||
}
|
||||
|
||||
std::string get_local_config_backups_path()
|
||||
{
|
||||
std::string config_path = get_local_config_path();
|
||||
if (config_path.empty()) {
|
||||
return std::string();
|
||||
}
|
||||
return config_path + "/backups";
|
||||
}
|
||||
|
||||
std::string get_local_server_path(const std::string &server_name)
|
||||
{
|
||||
std::string config_path = get_local_config_path();
|
||||
if (config_path.empty())
|
||||
return std::string();
|
||||
return config_path + "/servers/" + server_name;
|
||||
}
|
||||
|
||||
std::string get_local_server_env_path(const std::string &server_name)
|
||||
{
|
||||
std::string serverpath = get_local_server_path(server_name);
|
||||
if (serverpath.empty())
|
||||
return std::string();
|
||||
return (fs::path(serverpath) / "server.env").string();
|
||||
}
|
||||
|
||||
std::string get_local_service_path(const std::string &server_name, const std::string &service_name)
|
||||
{
|
||||
std::string serverpath = get_local_server_path(server_name);
|
||||
if (serverpath.empty())
|
||||
return std::string();
|
||||
return (fs::path(serverpath) / service_name).string();
|
||||
}
|
||||
|
||||
std::string get_local_service_env_path(const std::string &server_name, const std::string &service_name)
|
||||
{
|
||||
std::string servicepath = get_local_service_path(server_name, service_name);
|
||||
if (servicepath.empty())
|
||||
return std::string();
|
||||
return (fs::path(servicepath) / "service.env").string();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
||||
// remote paths
|
||||
// DROPSHELL_DIR
|
||||
// |-- service name
|
||||
// |-- config
|
||||
// |-- service.env
|
||||
// |-- (user config files)
|
||||
// |-- template
|
||||
// |-- (script files)
|
||||
// |-- backups
|
||||
|
||||
std::string get_remote_DROPSHELL_path(const std::string &server_name)
|
||||
{
|
||||
server_env env(server_name);
|
||||
if (!env.is_valid())
|
||||
return std::string();
|
||||
return env.get_DROPSHELL_DIR();
|
||||
}
|
||||
|
||||
std::string get_remote_service_path(const std::string &server_name, const std::string &service_name)
|
||||
{
|
||||
std::string dropshell_path = get_remote_DROPSHELL_path(server_name);
|
||||
if (dropshell_path.empty())
|
||||
return std::string();
|
||||
return (fs::path(dropshell_path) / service_name).string();
|
||||
}
|
||||
|
||||
std::string get_remote_service_config_path(const std::string &server_name, const std::string &service_name)
|
||||
{
|
||||
std::string service_path = get_remote_service_path(server_name, service_name);
|
||||
if (service_path.empty())
|
||||
return std::string();
|
||||
return (fs::path(service_path) / "config").string();
|
||||
}
|
||||
|
||||
std::string get_remote_service_template_path(const std::string &server_name, const std::string &service_name)
|
||||
{
|
||||
std::string service_path = get_remote_service_path(server_name, service_name);
|
||||
if (service_path.empty())
|
||||
return std::string();
|
||||
return (fs::path(service_path) / "template").string();
|
||||
}
|
||||
|
||||
std::string get_remote_service_backups_path(const std::string &server_name, const std::string &service_name)
|
||||
{
|
||||
std::string service_path = get_remote_service_path(server_name, service_name);
|
||||
if (service_path.empty())
|
||||
return std::string();
|
||||
return (fs::path(service_path) / "backups").string();
|
||||
}
|
||||
|
||||
std::string get_remote_service_env_file(const std::string &server_name, const std::string &service_name)
|
||||
{
|
||||
std::string service_path = get_remote_service_config_path(server_name, service_name);
|
||||
if (service_path.empty())
|
||||
return std::string();
|
||||
return (fs::path(service_path) / "service.env").string();
|
||||
}
|
||||
|
||||
} // namespace dropshell
|
40
src/utils/directories.hpp
Normal file
40
src/utils/directories.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef DIRECTORIES_HPP
|
||||
#define DIRECTORIES_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace dropshell {
|
||||
|
||||
// local paths - return empty string on failure
|
||||
std::string get_local_dropshell_config_path();
|
||||
std::string get_local_system_templates_path();
|
||||
std::string get_local_config_path();
|
||||
std::string get_local_config_templates_path();
|
||||
std::string get_local_config_servers_path();
|
||||
std::string get_local_config_backups_path();
|
||||
|
||||
std::string get_local_server_path(const std::string &server_name);
|
||||
std::string get_local_server_env_path(const std::string &server_name);
|
||||
|
||||
std::string get_local_service_path(const std::string &server_name, const std::string &service_name);
|
||||
std::string get_local_service_env_path(const std::string &server_name, const std::string &service_name);
|
||||
|
||||
// remote paths
|
||||
// DROPSHELL_DIR
|
||||
// |-- service name
|
||||
// |-- config
|
||||
// |-- service.env
|
||||
// |-- (user config files)
|
||||
// |-- template
|
||||
// |-- (script files)
|
||||
// |-- backups
|
||||
std::string get_remote_DROPSHELL_path(const std::string &server_name);
|
||||
std::string get_remote_service_path(const std::string &server_name, const std::string &service_name);
|
||||
std::string get_remote_service_config_path(const std::string &server_name, const std::string &service_name);
|
||||
std::string get_remote_service_template_path(const std::string &server_name, const std::string &service_name);
|
||||
std::string get_remote_service_backups_path(const std::string &server_name, const std::string &service_name);
|
||||
|
||||
std::string get_remote_service_env_file(const std::string &server_name, const std::string &service_name);
|
||||
} // namespace dropshell
|
||||
|
||||
#endif
|
135
src/utils/envmanager.cpp
Normal file
135
src/utils/envmanager.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
#include "envmanager.hpp"
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <regex>
|
||||
#include <cstdlib> // For std::getenv
|
||||
|
||||
namespace dropshell {
|
||||
|
||||
envmanager::envmanager(std::string path) : m_path(path) {
|
||||
}
|
||||
|
||||
envmanager::~envmanager() {
|
||||
}
|
||||
|
||||
bool envmanager::load() {
|
||||
std::ifstream file(m_path);
|
||||
if (!file.is_open()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_variables.clear();
|
||||
std::string line;
|
||||
while (std::getline(file, line)) {
|
||||
line=trim(line);
|
||||
// Skip empty lines and comments
|
||||
if (line.empty() || line[0] == '#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t pos = line.find('=');
|
||||
if (pos != std::string::npos) {
|
||||
std::string key = line.substr(0, pos);
|
||||
std::string value = line.substr(pos + 1);
|
||||
|
||||
// trim whitespace from the key and value
|
||||
m_variables[trim(key)] = trim(value);
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
void envmanager::save() {
|
||||
std::ofstream file(m_path);
|
||||
if (!file.is_open()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& pair : m_variables) {
|
||||
file << pair.first << "=" << pair.second << std::endl;
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
std::string envmanager::get_variable(std::string key) const {
|
||||
key = trim(key);
|
||||
|
||||
// Use case-insensitive comparison to find the key
|
||||
for (const auto& pair : m_variables) {
|
||||
if (pair.first == key) {
|
||||
return pair.second;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void envmanager::get_all_variables(std::map<std::string, std::string>& variables) const {
|
||||
variables = m_variables;
|
||||
}
|
||||
|
||||
std::string envmanager::get_variable_substituted(std::string key) const {
|
||||
std::string value = get_variable(key);
|
||||
return expand_patterns(value);
|
||||
}
|
||||
|
||||
void envmanager::get_all_variables_substituted(std::map<std::string, std::string>& variables) const {
|
||||
variables.clear();
|
||||
for (const auto& pair : m_variables) {
|
||||
variables[pair.first] = expand_patterns(pair.second);
|
||||
}
|
||||
}
|
||||
|
||||
void envmanager::add_variables(std::map<std::string, std::string> variables) {
|
||||
for (auto& pair : variables) {
|
||||
set_variable(pair.first, pair.second);
|
||||
}
|
||||
}
|
||||
|
||||
void envmanager::set_variable(std::string key, std::string value) {
|
||||
m_variables[trim(key)] = trim(value);
|
||||
}
|
||||
|
||||
void envmanager::clear_variables() {
|
||||
m_variables.clear();
|
||||
}
|
||||
|
||||
std::string envmanager::trim(std::string str) const {
|
||||
// Trim leading whitespace
|
||||
str.erase(str.begin(), std::find_if(str.begin(), str.end(), [](unsigned char ch) {
|
||||
return !std::isspace(ch);
|
||||
}));
|
||||
|
||||
// Trim trailing whitespace
|
||||
str.erase(std::find_if(str.rbegin(), str.rend(), [](unsigned char ch) {
|
||||
return !std::isspace(ch);
|
||||
}).base(), str.end());
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string envmanager::expand_patterns(std::string str) const {
|
||||
// Combined regex pattern for both ${var} and $var formats
|
||||
std::regex var_pattern("\\$(?:\\{([^}]+)\\}|([a-zA-Z0-9_]+))");
|
||||
std::string result = str;
|
||||
std::smatch match;
|
||||
|
||||
while (std::regex_search(result, match, var_pattern)) {
|
||||
// match[1] will contain capture from ${var} format
|
||||
// match[2] will contain capture from $var format
|
||||
std::string var_name = match[1].matched ? match[1].str() : match[2].str();
|
||||
|
||||
// Get value from system environment variables
|
||||
const char* env_value = std::getenv(var_name.c_str());
|
||||
std::string value = env_value ? env_value : "";
|
||||
|
||||
result = result.replace(match.position(), match.length(), value);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace dropshell
|
49
src/utils/envmanager.hpp
Normal file
49
src/utils/envmanager.hpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#ifndef ENV_MANAGER_HPP
|
||||
#define ENV_MANAGER_HPP
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
namespace dropshell {
|
||||
|
||||
// envmanager is a class that manages the environment files for the application.
|
||||
// it is responsible for loading the environment files, and providing a class to access the variables.
|
||||
// it can also save the environment files.
|
||||
class envmanager {
|
||||
public:
|
||||
envmanager(std::string path);
|
||||
~envmanager();
|
||||
|
||||
// load all variables from the environment file
|
||||
bool load();
|
||||
|
||||
// save all variables to the environment file
|
||||
void save();
|
||||
|
||||
// get variables from the environment files. Trim whitespace from the values.
|
||||
// keys are case-sensitive.
|
||||
std::string get_variable(std::string key) const;
|
||||
void get_all_variables(std::map<std::string, std::string>& variables) const;
|
||||
|
||||
// get variables, but replace patterns ${var} and $var with the actual environment variable in the returned string.
|
||||
// trim whitespace from the values.
|
||||
std::string get_variable_substituted(std::string key) const;
|
||||
void get_all_variables_substituted(std::map<std::string, std::string>& variables) const;
|
||||
|
||||
// add variables to the environment files.
|
||||
// trim whitespace from the values.
|
||||
void add_variables(std::map<std::string, std::string> variables);
|
||||
void set_variable(std::string key, std::string value);
|
||||
void clear_variables();
|
||||
|
||||
private:
|
||||
std::string trim(std::string str) const;
|
||||
std::string expand_patterns(std::string str) const;
|
||||
|
||||
private:
|
||||
std::string m_path;
|
||||
std::map<std::string, std::string> m_variables;
|
||||
};
|
||||
|
||||
} // namespace dropshell
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user