Merge topic 'cmake-E-env-modify'

c9d70a7cc3 cmake -E env: Add --modify flag

Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: buildbot <buildbot@kitware.com>
Merge-request: !7571
This commit is contained in:
Brad King 2022-08-18 12:03:53 +00:00 committed by Kitware Robot
commit 36d35d4eb1
19 changed files with 152 additions and 6 deletions

View File

@ -862,11 +862,29 @@ Available commands are:
Displays arguments as text but no new line.
.. option:: env [--unset=NAME ...] [NAME=VALUE ...] [--] <command> [<arg>...]
.. option:: env [<options>] [--] <command> [<arg>...]
.. versionadded:: 3.1
Run command in a modified environment.
Run command in a modified environment. Options are:
``NAME=VALUE``
Replaces the current value of ``NAME`` with ``VALUE``.
``--unset=NAME``
Unsets the current value of ``NAME``.
``--modify ENVIRONMENT_MODIFICATION``
.. versionadded:: 3.25
Apply a single :prop_test:`ENVIRONMENT_MODIFICATION` operation to the
modified environment.
The ``NAME=VALUE`` and ``--unset=NAME`` options are equivalent to
``--modify NAME=set:VALUE`` and ``--modify NAME=unset:``, respectively.
Note that ``--modify NAME=reset:`` resets ``NAME`` to the value it had
when ``cmake`` launched (or unsets it), not to the most recent
``NAME=VALUE`` option.
.. versionadded:: 3.24
Added support for the double dash argument ``--``. Use ``--`` to stop

View File

@ -0,0 +1,5 @@
cmake-E-env-modify
------------------
* A new ``--modify`` flag was added to :option:`cmake -E env <cmake_E env>` to support :prop_test:`ENVIRONMENT_MODIFICATION`
operations.

View File

@ -1578,10 +1578,15 @@ void cmSystemTools::EnvDiff::PutEnv(const std::string& env)
std::string name = env.substr(0, eq_loc);
diff[name] = env.substr(eq_loc + 1);
} else {
diff[env] = {};
this->UnPutEnv(env);
}
}
void cmSystemTools::EnvDiff::UnPutEnv(const std::string& env)
{
diff[env] = {};
}
bool cmSystemTools::EnvDiff::ParseOperation(const std::string& envmod)
{
char path_sep = GetSystemPathlistSeparator();

View File

@ -397,6 +397,9 @@ public:
*/
void PutEnv(const std::string& env);
/** Remove a single variable from the current environment diff. */
void UnPutEnv(const std::string& env);
/**
* Apply an ENVIRONMENT_MODIFICATION operation to this diff. Returns
* false and issues an error on parse failure.

View File

@ -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;

View File

@ -0,0 +1,15 @@
if (NOT DEFINED ENV{TEST_ENV_EXPECTED})
if (NOT DEFINED ENV{TEST_ENV})
message(STATUS "TEST_ENV is correctly not set in environment")
else ()
message(FATAL_ERROR "TEST_ENV is incorrectly set in environment")
endif ()
else ()
if (NOT DEFINED ENV{TEST_ENV})
message(FATAL_ERROR "TEST_ENV is incorrectly not set in environment")
elseif ("$ENV{TEST_ENV}" STREQUAL "$ENV{TEST_ENV_EXPECTED}")
message(STATUS "TEST_ENV is correctly set in environment: $ENV{TEST_ENV}")
else ()
message(FATAL_ERROR "TEST_ENV is incorrectly set in environment!\n\tactual: $ENV{TEST_ENV}\n\texpected: $ENV{TEST_ENV_EXPECTED}")
endif ()
endif ()

View File

@ -0,0 +1,3 @@
^CMake Error: Error: Unrecognized environment manipulation argument: unknown
cmake -E env: invalid parameter to --modify: TEST_ENV=unknown:$

View File

@ -0,0 +1 @@
^-- TEST_ENV is correctly set in environment: exp;ect;ed$

View File

@ -0,0 +1 @@
^-- TEST_ENV is correctly set in environment: exp[;:]ect[;:]ed$

View File

@ -0,0 +1 @@
^-- TEST_ENV is correctly set in environment: expected$

View File

@ -0,0 +1 @@
^-- TEST_ENV is correctly not set in environment$

View File

@ -0,0 +1 @@
^-- TEST_ENV is correctly set in environment: 1$

View File

@ -0,0 +1 @@
^-- TEST_ENV is correctly set in environment: expected$

View File

@ -0,0 +1 @@
^-- TEST_ENV is correctly not set in environment$

View File

@ -744,6 +744,10 @@ run_cmake_command(E_cat-without-double-dash ${CMAKE_COMMAND} -E cat "-file-start
unset(RunCMake_TEST_COMMAND_WORKING_DIRECTORY)
unset(out)
# Unset environment variables that are used for testing cmake -E
unset(ENV{TEST_ENV})
unset(ENV{TEST_ENV_EXPECTED})
run_cmake_command(E_env-no-command0 ${CMAKE_COMMAND} -E env)
run_cmake_command(E_env-no-command1 ${CMAKE_COMMAND} -E env TEST_ENV=1)
run_cmake_command(E_env-bad-arg1 ${CMAKE_COMMAND} -E env -bad-arg1)
@ -758,6 +762,56 @@ file(COPY_FILE "${EXIT_CODE_EXE}" "${RunCMake_BINARY_DIR}/env=${exit_code}")
run_cmake_command(E_env-with-double-dash ${CMAKE_COMMAND} -E env TEST_ENV=1 -- "${RunCMake_BINARY_DIR}/env=${exit_code}" zero_exit)
run_cmake_command(E_env-without-double-dash ${CMAKE_COMMAND} -E env TEST_ENV=1 "${RunCMake_BINARY_DIR}/env=${exit_code}" zero_exit)
## Tests of env --modify
# Repeat the same tests as above
run_cmake_command(E_env_modify-set ${CMAKE_COMMAND} -E env --modify TEST_ENV=set:1 ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/E_env-set.cmake)
run_cmake_command(E_env_modify-unset ${CMAKE_COMMAND} -E env --modify TEST_ENV=set:1 ${CMAKE_COMMAND} -E env --modify TEST_ENV=unset: ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/E_env-unset.cmake)
run_cmake_command(E_env_modify-with-double-dash ${CMAKE_COMMAND} -E env --modify TEST_ENV=set:1 -- "${RunCMake_BINARY_DIR}/env=${exit_code}" zero_exit)
run_cmake_command(E_env_modify-without-double-dash ${CMAKE_COMMAND} -E env --modify TEST_ENV=set:1 "${RunCMake_BINARY_DIR}/env=${exit_code}" zero_exit)
# Test environment modification commands
run_cmake_command(E_env_modify-reset
${CMAKE_COMMAND} -E env TEST_ENV=expected
${CMAKE_COMMAND} -E env TEST_ENV_EXPECTED=expected TEST_ENV=bad_value --modify TEST_ENV=reset:
${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/E_env-equal.cmake)
run_cmake_command(E_env_modify-reset-to-unset
${CMAKE_COMMAND} -E env --unset=TEST_ENV --unset=TEST_ENV_EXPECTED
${CMAKE_COMMAND} -E env TEST_ENV=bad_value --modify TEST_ENV=reset:
${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/E_env-equal.cmake)
run_cmake_command(E_env_modify-string
${CMAKE_COMMAND} -E env TEST_ENV_EXPECTED=expected
--modify TEST_ENV=unset:
--modify TEST_ENV=string_append:ect
--modify TEST_ENV=string_prepend:exp
--modify TEST_ENV=string_append:ed
${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/E_env-equal.cmake)
if (WIN32)
set(SEP "\\;")
else ()
set(SEP ":")
endif ()
run_cmake_command(E_env_modify-path_list
${CMAKE_COMMAND} -E env "TEST_ENV_EXPECTED=exp${SEP}ect${SEP}ed"
--modify TEST_ENV=unset:
--modify TEST_ENV=path_list_append:ect
--modify TEST_ENV=path_list_prepend:exp
--modify TEST_ENV=path_list_append:ed
${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/E_env-equal.cmake)
run_cmake_command(E_env_modify-cmake_list
${CMAKE_COMMAND} -E env "TEST_ENV_EXPECTED=exp\\;ect\\;ed"
--modify TEST_ENV=unset:
--modify TEST_ENV=cmake_list_append:ect
--modify TEST_ENV=cmake_list_prepend:exp
--modify TEST_ENV=cmake_list_append:ed
${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/E_env-equal.cmake)
run_cmake_command(E_env_modify-bad-operation ${CMAKE_COMMAND} -E env --modify TEST_ENV=unknown:)
run_cmake_command(E_md5sum-dir ${CMAKE_COMMAND} -E md5sum .)
run_cmake_command(E_sha1sum-dir ${CMAKE_COMMAND} -E sha1sum .)
run_cmake_command(E_sha224sum-dir ${CMAKE_COMMAND} -E sha224sum .)