This commit is contained in:
j
2025-12-30 09:04:06 +13:00
parent 30fa728f96
commit 0917e1e3f3
5 changed files with 130 additions and 14 deletions

View File

@@ -1,4 +1,4 @@
#include "env_validator.hpp"
#include "service_env_validator.hpp"
#include "envmanager.hpp"
#include "ordered_env.hpp"
#include "utils.hpp"
@@ -157,4 +157,96 @@ bool validate_and_fix_service_env(
return false;
}
bool set_env_variable(
const std::string& env_file_path,
const std::string& var_name,
const std::string& var_value,
const std::string& comment
) {
// Read existing file contents
std::vector<std::string> lines;
if (std::filesystem::exists(env_file_path)) {
std::ifstream infile(env_file_path);
if (!infile.is_open()) {
error << "Failed to open env file for reading: " << env_file_path << std::endl;
return false;
}
std::string line;
while (std::getline(infile, line)) {
lines.push_back(line);
}
infile.close();
}
// Build the comment line we're looking for (if comment provided)
std::string comment_line;
if (!comment.empty()) {
comment_line = "# " + comment;
}
// Build the pattern to match variable assignment: VAR_NAME= at start of line
std::string var_pattern = var_name + "=";
// Filter out existing variable definition and matching comment
std::vector<std::string> filtered_lines;
for (size_t i = 0; i < lines.size(); ++i) {
const std::string& line = lines[i];
std::string trimmed = trim(line);
// Check if this line is the exact comment we want to add
if (!comment_line.empty() && trimmed == comment_line) {
// Skip this comment line
continue;
}
// Check if this line defines our variable
if (!trimmed.empty() && trimmed[0] != '#') {
size_t eq_pos = trimmed.find('=');
if (eq_pos != std::string::npos) {
std::string key = trim(trimmed.substr(0, eq_pos));
if (key == var_name) {
// Skip this variable definition
continue;
}
}
}
filtered_lines.push_back(line);
}
// Remove trailing blank lines so we can control spacing
while (!filtered_lines.empty() && trim(filtered_lines.back()).empty()) {
filtered_lines.pop_back();
}
// Add exactly one blank line before our new content (if file is not empty)
if (!filtered_lines.empty()) {
filtered_lines.push_back("");
}
// Add the comment if provided
if (!comment_line.empty()) {
filtered_lines.push_back(comment_line);
}
// Add the variable assignment
filtered_lines.push_back(var_name + "=\"" + var_value + "\"");
// Write the file back
std::ofstream outfile(env_file_path);
if (!outfile.is_open()) {
error << "Failed to open env file for writing: " << env_file_path << std::endl;
return false;
}
for (const auto& l : filtered_lines) {
outfile << l << std::endl;
}
outfile.close();
return true;
}
} // namespace dropshell

View File

@@ -1,5 +1,5 @@
#ifndef ENV_VALIDATOR_HPP
#define ENV_VALIDATOR_HPP
#ifndef SERVICE_ENV_VALIDATOR_HPP
#define SERVICE_ENV_VALIDATOR_HPP
#include <string>
#include <vector>
@@ -24,6 +24,26 @@ bool validate_and_fix_service_env(
const std::string& template_info_env_path = ""
);
// Sets or updates a variable in an env file with an optional comment.
// - If the variable already exists, removes that line
// - If the comment already exists (exact match), removes that line too
// - Adds a single blank line, then the comment (if provided), then the variable assignment
// - The variable value is automatically quoted
//
// Parameters:
// env_file_path: Full path to the .env file
// var_name: Name of the variable to set
// var_value: Value to assign (will be quoted)
// comment: Optional comment to place before the variable (without # prefix)
//
// Returns true on success, false on failure
bool set_env_variable(
const std::string& env_file_path,
const std::string& var_name,
const std::string& var_value,
const std::string& comment = ""
);
} // namespace dropshell
#endif // ENV_VALIDATOR_HPP
#endif // SERVICE_ENV_VALIDATOR_HPP