summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2014-06-23 20:33:33 (GMT)
committerBrad King <brad.king@kitware.com>2014-06-23 20:47:49 (GMT)
commit7abd574798f9900abfe502f3941cffaa774062b1 (patch)
treec930e472ac4fdb02b18b1ea3743d56013c3e4bf5
parent0474aa4a78d74f971f6be5d3c4209c46bd6e02e9 (diff)
downloadCMake-7abd574798f9900abfe502f3941cffaa774062b1.zip
CMake-7abd574798f9900abfe502f3941cffaa774062b1.tar.gz
CMake-7abd574798f9900abfe502f3941cffaa774062b1.tar.bz2
cmake: Add '-E env' command-line tool
Extend the cmake command-line interface to support cmake -E env [--unset=NAME]... [NAME=VALUE]... COMMAND [ARG]... This will be useful to run processes with modified environments without using a shell or a full "cmake -P" script to wrap it. Extend the RunCMake.CommandLine test to cover success and failure cases. Inspired-by: Jonathan Bohren <jbo@jhu.edu>
-rw-r--r--Help/manual/cmake.1.rst2
-rw-r--r--Help/release/dev/cmake-E-env.rst4
-rw-r--r--Source/cmcmd.cxx51
-rw-r--r--Tests/RunCMake/CommandLine/E_env-bad-arg1-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env-bad-arg1-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env-no-command0-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env-no-command0-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env-no-command1-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env-no-command1-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env-set-stdout.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env-set.cmake5
-rw-r--r--Tests/RunCMake/CommandLine/E_env-unset-stdout.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env-unset.cmake5
-rw-r--r--Tests/RunCMake/CommandLine/RunCMakeTest.cmake6
14 files changed, 80 insertions, 1 deletions
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index 5743ab7..8dfc16a 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -38,7 +38,7 @@ Options
For true platform independence, CMake provides a list of commands
that can be used on all systems. Run with -E help for the usage
information. Commands available are: chdir, compare_files, copy,
- copy_directory, copy_if_different, echo, echo_append, environment,
+ copy_directory, copy_if_different, echo, echo_append, env, environment,
make_directory, md5sum, remove, remove_directory, rename, sleep, tar, time,
touch, touch_nocreate. In addition, some platform specific commands
are available. On Windows: delete_regv, write_regv. On
diff --git a/Help/release/dev/cmake-E-env.rst b/Help/release/dev/cmake-E-env.rst
new file mode 100644
index 0000000..4bdcd0c
--- /dev/null
+++ b/Help/release/dev/cmake-E-env.rst
@@ -0,0 +1,4 @@
+cmake-E-env
+-----------
+
+* The :manual:`cmake(1)` ``-E`` option learned a new ``env`` command.
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 9aee975..a0c67e0 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -61,6 +61,8 @@ void CMakeCommandUsage(const char* program)
<< " echo [string]... - displays arguments as text\n"
<< " echo_append [string]... - displays arguments as text but no new "
"line\n"
+ << " env [--unset=NAME]... [NAME=VALUE]... COMMAND [ARG]...\n"
+ << " - run command in a modified environment\n"
<< " environment - display the current environment\n"
<< " make_directory dir - create a directory\n"
<< " md5sum file1 [...] - compute md5sum of files\n"
@@ -190,6 +192,55 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
return 0;
}
+ else if (args[1] == "env" )
+ {
+ std::vector<std::string>::const_iterator ai = args.begin() + 2;
+ std::vector<std::string>::const_iterator ae = args.end();
+ for(; ai != ae; ++ai)
+ {
+ std::string const& a = *ai;
+ if(cmHasLiteralPrefix(a, "--unset="))
+ {
+ // Unset environment variable.
+ cmSystemTools::UnPutEnv(a.c_str() + 8);
+ }
+ 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;
+ return 1;
+ }
+ else if(a.find("=") != a.npos)
+ {
+ // Set environment variable.
+ cmSystemTools::PutEnv(a.c_str());
+ }
+ else
+ {
+ // This is the beginning of the command.
+ break;
+ }
+ }
+
+ if(ai == ae)
+ {
+ std::cerr << "cmake -E env: no command given" << std::endl;
+ return 1;
+ }
+
+ // Execute command from remaining arguments.
+ std::vector<std::string> cmd(ai, ae);
+ int retval;
+ if(cmSystemTools::RunSingleCommand(
+ cmd, 0, &retval, NULL, cmSystemTools::OUTPUT_PASSTHROUGH))
+ {
+ return retval;
+ }
+ return 1;
+ }
+
#if defined(CMAKE_BUILD_WITH_CMAKE)
// Command to create a symbolic link. Fails on platforms not
// supporting them.
diff --git a/Tests/RunCMake/CommandLine/E_env-bad-arg1-result.txt b/Tests/RunCMake/CommandLine/E_env-bad-arg1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env-bad-arg1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_env-bad-arg1-stderr.txt b/Tests/RunCMake/CommandLine/E_env-bad-arg1-stderr.txt
new file mode 100644
index 0000000..2143ba4
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env-bad-arg1-stderr.txt
@@ -0,0 +1 @@
+^cmake -E env: unknown option '-bad-arg1'$
diff --git a/Tests/RunCMake/CommandLine/E_env-no-command0-result.txt b/Tests/RunCMake/CommandLine/E_env-no-command0-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env-no-command0-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_env-no-command0-stderr.txt b/Tests/RunCMake/CommandLine/E_env-no-command0-stderr.txt
new file mode 100644
index 0000000..d2efa53
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env-no-command0-stderr.txt
@@ -0,0 +1 @@
+^cmake -E env: no command given$
diff --git a/Tests/RunCMake/CommandLine/E_env-no-command1-result.txt b/Tests/RunCMake/CommandLine/E_env-no-command1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env-no-command1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_env-no-command1-stderr.txt b/Tests/RunCMake/CommandLine/E_env-no-command1-stderr.txt
new file mode 100644
index 0000000..d2efa53
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env-no-command1-stderr.txt
@@ -0,0 +1 @@
+^cmake -E env: no command given$
diff --git a/Tests/RunCMake/CommandLine/E_env-set-stdout.txt b/Tests/RunCMake/CommandLine/E_env-set-stdout.txt
new file mode 100644
index 0000000..feff117
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env-set-stdout.txt
@@ -0,0 +1 @@
+^-- TEST_ENV is correctly set in environment: 1$
diff --git a/Tests/RunCMake/CommandLine/E_env-set.cmake b/Tests/RunCMake/CommandLine/E_env-set.cmake
new file mode 100644
index 0000000..c2639b6
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env-set.cmake
@@ -0,0 +1,5 @@
+if(DEFINED ENV{TEST_ENV})
+ message(STATUS "TEST_ENV is correctly set in environment: $ENV{TEST_ENV}")
+else()
+ message(FATAL_ERROR "TEST_ENV is incorrectly not set in environment")
+endif()
diff --git a/Tests/RunCMake/CommandLine/E_env-unset-stdout.txt b/Tests/RunCMake/CommandLine/E_env-unset-stdout.txt
new file mode 100644
index 0000000..a1d5c01
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env-unset-stdout.txt
@@ -0,0 +1 @@
+^-- TEST_ENV is correctly not set in environment$
diff --git a/Tests/RunCMake/CommandLine/E_env-unset.cmake b/Tests/RunCMake/CommandLine/E_env-unset.cmake
new file mode 100644
index 0000000..04976fb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env-unset.cmake
@@ -0,0 +1,5 @@
+if(DEFINED ENV{TEST_ENV})
+ message(FATAL_ERROR "TEST_ENV is incorrectly set in environment")
+else()
+ message(STATUS "TEST_ENV is correctly not set in environment")
+endif()
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index f3d9637..5622a5b 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -31,6 +31,12 @@ if(UNIX)
)
endif()
+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)
+run_cmake_command(E_env-set ${CMAKE_COMMAND} -E env TEST_ENV=1 ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/E_env-set.cmake)
+run_cmake_command(E_env-unset ${CMAKE_COMMAND} -E env TEST_ENV=1 ${CMAKE_COMMAND} -E env --unset=TEST_ENV ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/E_env-unset.cmake)
+
run_cmake_command(E_sleep-no-args ${CMAKE_COMMAND} -E sleep)
run_cmake_command(E_sleep-bad-arg1 ${CMAKE_COMMAND} -E sleep x)
run_cmake_command(E_sleep-bad-arg2 ${CMAKE_COMMAND} -E sleep 1 -1)