diff options
author | Alex Reinking <alex.reinking@gmail.com> | 2022-08-14 02:28:24 -0400 |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2022-08-15 14:11:47 -0400 |
commit | bfa1c5285b0db8f7dfe8e7c5ac546312723f59db (patch) | |
tree | 86c2c1d1c7d4139910a71db9b163aa06bd20caa8 /Source/CTest | |
parent | a0b1c4ee907ee135fdb5727084fc90a07f525470 (diff) | |
download | cmake-bfa1c5285b0db8f7dfe8e7c5ac546312723f59db.tar.gz |
cmSystemTools: Add EnvDiff class to hold ENVIRONMENT_MODIFICATION logic
Prepare to re-use this logic when enhancing `cmake -E env`.
Diffstat (limited to 'Source/CTest')
-rw-r--r-- | Source/CTest/cmCTestRunTest.cxx | 127 |
1 files changed, 6 insertions, 121 deletions
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index 88b45df6ca..11be1322fb 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -8,16 +8,12 @@ #include <cstdint> #include <cstdio> #include <cstring> -#include <functional> #include <iomanip> #include <ratio> #include <sstream> #include <utility> #include <cm/memory> -#include <cm/optional> -#include <cm/string_view> -#include <cmext/string_view> #include "cmsys/RegularExpression.hxx" @@ -793,7 +789,7 @@ bool cmCTestRunTest::ForkProcess( if (environment && !environment->empty()) { // Environment modification works on the assumption that the environment is // actually modified here. If another strategy is used, there will need to - // be updates below in `apply_diff`. + // be updates in `EnvDiff::ParseOperation`. cmSystemTools::AppendEnv(*environment); for (auto const& var : *environment) { envMeasurement << var << std::endl; @@ -801,129 +797,18 @@ bool cmCTestRunTest::ForkProcess( } if (environment_modification && !environment_modification->empty()) { - std::map<std::string, cm::optional<std::string>> env_application; - - char path_sep = cmSystemTools::GetSystemPathlistSeparator(); - - auto apply_diff = - [&env_application](const std::string& name, - std::function<void(std::string&)> const& apply) { - cm::optional<std::string> old_value = env_application[name]; - std::string output; - if (old_value) { - output = *old_value; - } else { - // This only works because the environment is actually modified above - // (`AppendEnv`). If CTest ever just creates an environment block - // directly, that block will need to be queried for the subprocess' - // value instead. - const char* curval = cmSystemTools::GetEnv(name); - if (curval) { - output = curval; - } - } - apply(output); - env_application[name] = output; - }; - - bool err_occurred = false; + cmSystemTools::EnvDiff diff; + bool env_ok = true; for (auto const& envmod : *environment_modification) { - // Split on `=` - auto const eq_loc = envmod.find_first_of('='); - if (eq_loc == std::string::npos) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Error: Missing `=` after the variable name in: " - << envmod << std::endl); - err_occurred = true; - continue; - } - auto const name = envmod.substr(0, eq_loc); - - // Split value on `:` - auto const op_value_start = eq_loc + 1; - auto const colon_loc = envmod.find_first_of(':', op_value_start); - if (colon_loc == std::string::npos) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Error: Missing `:` after the operation in: " << envmod - << std::endl); - err_occurred = true; - continue; - } - auto const op = - envmod.substr(op_value_start, colon_loc - op_value_start); - - auto const value_start = colon_loc + 1; - auto const value = envmod.substr(value_start); - - // Determine what to do with the operation. - if (op == "reset"_s) { - auto entry = env_application.find(name); - if (entry != env_application.end()) { - env_application.erase(entry); - } - } else if (op == "set"_s) { - env_application[name] = value; - } else if (op == "unset"_s) { - env_application[name] = {}; - } else if (op == "string_append"_s) { - apply_diff(name, [&value](std::string& output) { output += value; }); - } else if (op == "string_prepend"_s) { - apply_diff(name, - [&value](std::string& output) { output.insert(0, value); }); - } else if (op == "path_list_append"_s) { - apply_diff(name, [&value, path_sep](std::string& output) { - if (!output.empty()) { - output += path_sep; - } - output += value; - }); - } else if (op == "path_list_prepend"_s) { - apply_diff(name, [&value, path_sep](std::string& output) { - if (!output.empty()) { - output.insert(output.begin(), path_sep); - } - output.insert(0, value); - }); - } else if (op == "cmake_list_append"_s) { - apply_diff(name, [&value](std::string& output) { - if (!output.empty()) { - output += ';'; - } - output += value; - }); - } else if (op == "cmake_list_prepend"_s) { - apply_diff(name, [&value](std::string& output) { - if (!output.empty()) { - output.insert(output.begin(), ';'); - } - output.insert(0, value); - }); - } else { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Error: Unrecognized environment manipulation argument: " - << op << std::endl); - err_occurred = true; - continue; - } + env_ok &= diff.ParseOperation(envmod); } - if (err_occurred) { + if (!env_ok) { return false; } - for (auto const& env_apply : env_application) { - if (env_apply.second) { - auto const env_update = - cmStrCat(env_apply.first, '=', *env_apply.second); - cmSystemTools::PutEnv(env_update); - envMeasurement << env_update << std::endl; - } else { - cmSystemTools::UnsetEnv(env_apply.first.c_str()); - // Signify that this variable is being actively unset - envMeasurement << "#" << env_apply.first << "=" << std::endl; - } - } + diff.ApplyToCurrentEnv(&envMeasurement); } if (this->UseAllocatedResources) { |