summaryrefslogtreecommitdiffstats
path: root/Source/cmcmd.cxx
diff options
context:
space:
mode:
authorAlex Reinking <alex.reinking@gmail.com>2022-08-14 08:42:11 (GMT)
committerAlex Reinking <alex.reinking@gmail.com>2022-08-17 16:54:39 (GMT)
commitc9d70a7cc32bd023c92fd9eac19cb907b86ada8f (patch)
tree551a9588a3f1daaefc62134d892fa30ca4c1560e /Source/cmcmd.cxx
parent5b949bbb9114379120c29134b5effd77e39dd134 (diff)
downloadCMake-c9d70a7cc32bd023c92fd9eac19cb907b86ada8f.zip
CMake-c9d70a7cc32bd023c92fd9eac19cb907b86ada8f.tar.gz
CMake-c9d70a7cc32bd023c92fd9eac19cb907b86ada8f.tar.bz2
cmake -E env: Add --modify flag
When `cmake -E env` is given the `--modify` flag, try to parse the following argument as an `ENVIRONMENT_MODIFICATION` operation and apply it to the environment. This generalizes `--unset=`: 1. When implementing `ENVIRONMENT_MODIFICATION` features for other CMake commands, the `MYVAR=OP:VALUE` strings do not need to be translated to OP-specific flags. 2. This provides a natural and consistent extension point to introduce new operations without introducing very many flags. 3. Users need to learn only one syntax to access the same functionality. There is one difference between the behavior here as compared to CTest's interpretation of the `ENVIRONMENT_MODIFICATION` test property. The `MYVAR=reset:` command when run in `cmake -E env` will reset `MYVAR` to whatever its value was when `cmake -E env` launched, rather than try to checkpoint after plain `MYVAR=VALUE` options. This makes `MYVAR=VALUE` and `--modify MYVAR=set:VALUE` semantically equivalent.
Diffstat (limited to 'Source/cmcmd.cxx')
-rw-r--r--Source/cmcmd.cxx38
1 files changed, 35 insertions, 3 deletions
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index b1f1bcf..00c9bda 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -791,6 +791,10 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
}
if (args[1] == "env") {
+#ifndef CMAKE_BOOTSTRAP
+ cmSystemTools::EnvDiff env;
+#endif
+
auto ai = args.cbegin() + 2;
auto ae = args.cend();
for (; ai != ae; ++ai) {
@@ -803,16 +807,40 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
}
if (cmHasLiteralPrefix(a, "--unset=")) {
// Unset environment variable.
+#ifdef CMAKE_BOOTSTRAP
cmSystemTools::UnPutEnv(a.substr(8));
+#else
+ env.UnPutEnv(a.substr(8));
+#endif
+ } else if (a == "--modify") {
+#ifdef CMAKE_BOOTSTRAP
+ std::cerr
+ << "cmake -E env: --modify not available during bootstrapping\n";
+ return 1;
+#else
+ if (++ai == ae) {
+ std::cerr << "cmake -E env: --modify missing a parameter\n";
+ return 1;
+ }
+ std::string const& op = *ai;
+ if (!env.ParseOperation(op)) {
+ std::cerr << "cmake -E env: invalid parameter to --modify: " << op
+ << '\n';
+ return 1;
+ }
+#endif
} else if (!a.empty() && a[0] == '-') {
// Environment variable and command names cannot start in '-',
// so this must be an unknown option.
- std::cerr << "cmake -E env: unknown option '" << a << '\''
- << std::endl;
+ std::cerr << "cmake -E env: unknown option '" << a << "'\n";
return 1;
} else if (a.find('=') != std::string::npos) {
// Set environment variable.
+#ifdef CMAKE_BOOTSTRAP
cmSystemTools::PutEnv(a);
+#else
+ env.PutEnv(a);
+#endif
} else {
// This is the beginning of the command.
break;
@@ -820,10 +848,14 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
}
if (ai == ae) {
- std::cerr << "cmake -E env: no command given" << std::endl;
+ std::cerr << "cmake -E env: no command given\n";
return 1;
}
+#ifndef CMAKE_BOOTSTRAP
+ env.ApplyToCurrentEnv();
+#endif
+
// Execute command from remaining arguments.
std::vector<std::string> cmd(ai, ae);
int retval;