fix env variable load and subst order
This commit is contained in:
@@ -56,7 +56,7 @@ bool envmanager::load() {
|
||||
}
|
||||
|
||||
// trim whitespace from the key and value
|
||||
m_variables[dequote(trim(key))] = dequote(trim(value));
|
||||
set_var(m_variables, dequote(trim(key)), dequote(trim(value)));
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
@@ -77,29 +77,21 @@ void envmanager::save() {
|
||||
|
||||
std::string envmanager::get_variable(std::string key) const {
|
||||
key = dequote(trim(key));
|
||||
|
||||
// Use case-insensitive comparison to find the key
|
||||
for (const auto& pair : m_variables) {
|
||||
if (pair.first == key) {
|
||||
return pair.second;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
return get_var(m_variables, key);
|
||||
}
|
||||
|
||||
void envmanager::get_all_variables(std::map<std::string, std::string>& variables) const {
|
||||
void envmanager::get_all_variables(ordered_env_vars& variables) const {
|
||||
variables = m_variables;
|
||||
}
|
||||
|
||||
void envmanager::add_variables(std::map<std::string, std::string> variables) {
|
||||
for (auto& pair : variables) {
|
||||
void envmanager::add_variables(const ordered_env_vars& variables) {
|
||||
for (const auto& pair : variables) {
|
||||
set_variable(pair.first, pair.second);
|
||||
}
|
||||
}
|
||||
|
||||
void envmanager::set_variable(std::string key, std::string value) {
|
||||
m_variables[dequote(trim(key))] = dequote(trim(value));
|
||||
set_var(m_variables, dequote(trim(key)), dequote(trim(value)));
|
||||
}
|
||||
|
||||
void envmanager::clear_variables() {
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include "ordered_env.hpp"
|
||||
|
||||
namespace dropshell {
|
||||
|
||||
// envmanager is a class that manages the environment files for the application.
|
||||
@@ -23,17 +25,17 @@ class envmanager {
|
||||
// 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;
|
||||
void get_all_variables(ordered_env_vars& variables) const;
|
||||
|
||||
// add variables to the environment files.
|
||||
// trim whitespace from the values.
|
||||
void add_variables(std::map<std::string, std::string> variables);
|
||||
void add_variables(const ordered_env_vars& variables);
|
||||
void set_variable(std::string key, std::string value);
|
||||
void clear_variables();
|
||||
|
||||
private:
|
||||
std::string m_path;
|
||||
std::map<std::string, std::string> m_variables;
|
||||
ordered_env_vars m_variables;
|
||||
};
|
||||
|
||||
// utility functions
|
||||
|
||||
@@ -113,7 +113,7 @@ namespace dropshell
|
||||
sColour currentColour_;
|
||||
};
|
||||
|
||||
bool execute_local_command(std::string directory_to_run_in, std::string command_to_run, const std::map<std::string, std::string> &env_vars, std::string *output, cMode mode)
|
||||
bool execute_local_command(std::string directory_to_run_in, std::string command_to_run, const ordered_env_vars& env_vars, std::string *output, cMode mode)
|
||||
{
|
||||
sCommand command(directory_to_run_in, command_to_run, env_vars);
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "ordered_env.hpp"
|
||||
|
||||
namespace dropshell {
|
||||
|
||||
@@ -44,7 +45,7 @@ class sSSHInfo {
|
||||
std::string user_dir; // dropshell directory for the user.
|
||||
};
|
||||
|
||||
bool execute_local_command(std::string directory_to_run_in, std::string command_to_run, const std::map<std::string, std::string> & env_vars, std::string * output = nullptr, cMode mode = cMode::Defaults);
|
||||
bool execute_local_command(std::string directory_to_run_in, std::string command_to_run, const ordered_env_vars& env_vars, std::string * output = nullptr, cMode mode = cMode::Defaults);
|
||||
bool execute_ssh_command(const sSSHInfo & ssh_info, const sCommand & remote_command, cMode mode = cMode::Defaults, std::string * output = nullptr);
|
||||
|
||||
|
||||
@@ -54,17 +55,17 @@ bool execute_ssh_command(const sSSHInfo & ssh_info, const sCommand & remote_comm
|
||||
// class to hold a command to run on the remote server.
|
||||
class sCommand {
|
||||
public:
|
||||
sCommand(std::string directory_to_run_in, std::string command_to_run, const std::map<std::string, std::string> & env_vars) :
|
||||
sCommand(std::string directory_to_run_in, std::string command_to_run, const ordered_env_vars& env_vars) :
|
||||
mDir(directory_to_run_in), mCmd(command_to_run), mVars(env_vars) {}
|
||||
|
||||
std::string get_directory_to_run_in() const { return mDir; }
|
||||
std::string get_command_to_run() const { return mCmd; }
|
||||
const std::map<std::string, std::string>& get_env_vars() const { return mVars; }
|
||||
const ordered_env_vars& get_env_vars() const { return mVars; }
|
||||
|
||||
void add_env_var(const std::string& key, const std::string& value) { mVars.emplace_back(key, value); }
|
||||
|
||||
void add_env_var(const std::string& key, const std::string& value) { mVars[key] = value; }
|
||||
|
||||
bool empty() const { return mCmd.empty(); }
|
||||
|
||||
|
||||
std::string construct_cmd(std::string bb64path) const;
|
||||
|
||||
private:
|
||||
@@ -73,7 +74,7 @@ class sCommand {
|
||||
private:
|
||||
std::string mDir;
|
||||
std::string mCmd;
|
||||
std::map<std::string, std::string> mVars;
|
||||
ordered_env_vars mVars;
|
||||
};
|
||||
|
||||
bool EXITSTATUSCHECK(int ret);
|
||||
|
||||
64
source/src/utils/ordered_env.hpp
Normal file
64
source/src/utils/ordered_env.hpp
Normal file
@@ -0,0 +1,64 @@
|
||||
#ifndef ORDERED_ENV_HPP
|
||||
#define ORDERED_ENV_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
|
||||
namespace dropshell {
|
||||
|
||||
// Type alias for insertion-ordered environment variables
|
||||
using ordered_env_vars = std::vector<std::pair<std::string, std::string>>;
|
||||
|
||||
// Helper functions for working with ordered_env_vars like a map
|
||||
|
||||
// Find a variable by key (returns iterator)
|
||||
inline auto find_var(ordered_env_vars& vars, const std::string& key) {
|
||||
return std::find_if(vars.begin(), vars.end(),
|
||||
[&](const auto& p) { return p.first == key; });
|
||||
}
|
||||
|
||||
inline auto find_var(const ordered_env_vars& vars, const std::string& key) {
|
||||
return std::find_if(vars.begin(), vars.end(),
|
||||
[&](const auto& p) { return p.first == key; });
|
||||
}
|
||||
|
||||
// Get a variable value (returns empty string if not found)
|
||||
inline std::string get_var(const ordered_env_vars& vars, const std::string& key) {
|
||||
auto it = find_var(vars, key);
|
||||
return (it != vars.end()) ? it->second : "";
|
||||
}
|
||||
|
||||
// Set a variable (updates if exists, appends if new)
|
||||
inline void set_var(ordered_env_vars& vars, const std::string& key, const std::string& value) {
|
||||
auto it = find_var(vars, key);
|
||||
if (it != vars.end()) {
|
||||
it->second = value;
|
||||
} else {
|
||||
vars.emplace_back(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if a variable exists
|
||||
inline bool has_var(const ordered_env_vars& vars, const std::string& key) {
|
||||
return find_var(vars, key) != vars.end();
|
||||
}
|
||||
|
||||
// Merge variables from another ordered_env_vars (appends new, skips existing)
|
||||
inline void merge_vars(ordered_env_vars& dest, const ordered_env_vars& src) {
|
||||
for (const auto& [key, value] : src) {
|
||||
if (!has_var(dest, key)) {
|
||||
dest.emplace_back(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear all variables
|
||||
inline void clear_vars(ordered_env_vars& vars) {
|
||||
vars.clear();
|
||||
}
|
||||
|
||||
} // namespace dropshell
|
||||
|
||||
#endif
|
||||
@@ -376,25 +376,24 @@ std::string replace_with_environment_variables_like_bash(std::string str) {
|
||||
}
|
||||
|
||||
|
||||
std::string substitute_provided_key_value_pairs(std::string str, const std::map<std::string, std::string> &env_vars)
|
||||
std::string substitute_provided_key_value_pairs(std::string str, const ordered_env_vars& env_vars)
|
||||
{
|
||||
// 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 environment variables map
|
||||
auto it = env_vars.find(var_name);
|
||||
std::string value = (it != env_vars.end()) ? it->second : "";
|
||||
|
||||
|
||||
// Get value from environment variables
|
||||
std::string value = get_var(env_vars, var_name);
|
||||
|
||||
result = result.replace(match.position(), match.length(), value);
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <map>
|
||||
|
||||
#include "output.hpp"
|
||||
#include "ordered_env.hpp"
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace dropshell {
|
||||
@@ -54,7 +55,7 @@ std::string right_align(const std::string & str, int width);
|
||||
std::string center_align(const std::string & str, int width);
|
||||
|
||||
std::string replace_with_environment_variables_like_bash(std::string str);
|
||||
std::string substitute_provided_key_value_pairs(std::string str, const std::map<std::string, std::string> & env_vars);
|
||||
std::string substitute_provided_key_value_pairs(std::string str, const ordered_env_vars& env_vars);
|
||||
|
||||
int get_console_width();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user