Hello. Here is the patch with tests. ________________________________________ From: Brad King <brad.k...@kitware.com> Sent: Thursday, December 3, 2015 7:07 PM To: Bartosz Kosiorek Cc: cmake-developers@cmake.org Subject: Re: [cmake-developers] [PATCH] Extend copy and copy_if_different commands with support multiple files
On 12/03/2015 12:31 PM, Bartosz Kosiorek wrote: > When I'm trying to run test with wildcard: > run_cmake_command(E_copy-wildcard-source-files-target-is-directory > ${CMAKE_COMMAND} -E copy > ${RunCMake_copy_TEST_SOURCE_DIR}/directory1/* > ${RunCMake_copy_TEST_BINARY_DIR}) > > I've got an error: The command is not running through a shell in that case so there is no step that expands the wildcard. This feature is not about wildcard expansion, but about multiple inputs to the copy. They can be spelled out explicitly in the command invocation, or passed through a variable containing a list populated by file(GLOB). -Brad
From 8225688074386ac8633bad5e6f9fdb4a7caf9775 Mon Sep 17 00:00:00 2001 From: "Bartosz Kosiorek bartosz.kosio...@tomtom.com" <bartosz.kosio...@tomtom.com> Date: Thu, 3 Dec 2015 00:43:37 +0100 Subject: [PATCH 1/2] Extend copy and copy_if_different command with support multiple files This patch allows to use multiple files in command copy and copy_if_different. Input files could be merged with wildcards. If multipile input files were provided, then destination must be directory. If only one input file was provided, then destination could be either file or directory. This path is starting point for fixing bug 15703 --- Help/manual/cmake.1.rst | 12 ++++---- Source/cmcmd.cxx | 73 +++++++++++++++++++++++++++++++++++-------------- 2 files changed, 58 insertions(+), 27 deletions(-) diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index dac16bf..086f259 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -169,14 +169,14 @@ Available commands are: ``compare_files <file1> <file2>`` Check if file1 is same as file2. -``copy <file> <destination>`` - Copy file to destination (either file or directory). +``copy <file>... <destination>`` + Copy files to 'destination' (either file or directory). ``copy_directory <source> <destination>`` Copy directory 'source' content to directory 'destination'. -``copy_if_different <in-file> <out-file>`` - Copy file if input has changed. +``copy_if_different <file>... <destination>`` + Copy files if input has changed. Destination could be file or directory. ``echo [<string>...]`` Displays arguments as text. @@ -193,10 +193,10 @@ Available commands are: ``make_directory <dir>`` Create a directory. -``md5sum [<file>...]`` +``md5sum <file>...`` Compute md5sum of files. -``remove [-f] [<file>...]`` +``remove [-f] <file>...`` Remove the file(s), use ``-f`` to force it. ``remove_directory <dir>`` diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 21b126b..0dc5a9a 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -52,25 +52,25 @@ void CMakeCommandUsage(const char* program) // If you add new commands, change here, // and in cmakemain.cxx in the options table errorStream - << "Usage: " << program << " -E [command] [arguments ...]\n" + << "Usage: " << program << " -E <command> [arguments...]\n" << "Available commands: \n" << " chdir dir cmd [args]... - run command in a given directory\n" << " compare_files file1 file2 - check if file1 is same as file2\n" - << " copy file destination - copy file to destination (either file " - "or directory)\n" + << " copy <file>... destination - copy files to destination " + "(either file or directory)\n" << " copy_directory source destination - copy directory 'source' " "content to directory 'destination'\n" - << " copy_if_different in-file out-file - copy file if input has " + << " copy_if_different <file>... destination - copy files if it has " "changed\n" - << " echo [string]... - displays arguments as text\n" - << " echo_append [string]... - displays arguments as text but no new " + << " 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" - << " remove [-f] file1 file2 ... - remove the file(s), use -f to force " + << " md5sum <file>... - compute md5sum of files\n" + << " remove [-f] <file>... - remove the file(s), use -f to force " "it\n" << " remove_directory dir - remove a directory and its contents\n" << " rename oldname newname - rename a file or directory " @@ -78,7 +78,7 @@ void CMakeCommandUsage(const char* program) << " tar [cxt][vf][zjJ] file.tar [file/dir1 file/dir2 ...]\n" << " - create or extract a tar or zip archive\n" << " sleep <number>... - sleep for given number of seconds\n" - << " time command [args] ... - run command and return elapsed time\n" + << " time command [args...] - run command and return elapsed time\n" << " touch file - touch a file.\n" << " touch_nocreate file - touch a file but do not create it.\n" #if defined(_WIN32) && !defined(__CYGWIN__) @@ -149,29 +149,60 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) if (args.size() > 1) { // Copy file - if (args[1] == "copy" && args.size() == 4) + if (args[1] == "copy" && args.size() > 3) { - if(!cmSystemTools::cmCopyFile(args[2].c_str(), args[3].c_str())) + // If multiple source files specified, + // then destination must be directory + if ((args.size() > 4) && + (!cmSystemTools::FileIsDirectory(args[args.size() - 1]))) { - std::cerr << "Error copying file \"" << args[2] - << "\" to \"" << args[3] << "\".\n"; + std::cerr << "Error: Target (for copy command) \"" + << args[args.size() - 1] + << "\" is not a directory.\n"; return 1; } - return 0; + // If error occurs we want to continue copying next files. + bool return_value = 0; + for (std::string::size_type cc = 2; cc < args.size() - 1; cc ++) + { + if(!cmSystemTools::cmCopyFile(args[cc].c_str(), + args[args.size() - 1].c_str())) + { + std::cerr << "Error copying file \"" << args[cc] + << "\" to \"" << args[args.size() - 1] << "\".\n"; + return_value = 1; + } + } + return return_value; } // Copy file if different. - if (args[1] == "copy_if_different" && args.size() == 4) + if (args[1] == "copy_if_different" && args.size() > 3) { - if(!cmSystemTools::CopyFileIfDifferent(args[2].c_str(), - args[3].c_str())) + // If multiple source files specified, + // then destination must be directory + if ((args.size() > 4) && + (!cmSystemTools::FileIsDirectory(args[args.size() - 1]))) { - std::cerr << "Error copying file (if different) from \"" - << args[2] << "\" to \"" << args[3] - << "\".\n"; + std::cerr << "Error: Target (for copy_if_different command) \"" + << args[args.size() - 1] + << "\" is not a directory.\n"; return 1; } - return 0; + // If error occurs we want to continue copying next files. + bool return_value = 0; + for (std::string::size_type cc = 2; cc < args.size() - 1; cc ++) + { + if(!cmSystemTools::CopyFileIfDifferent(args[cc].c_str(), + args[args.size() - 1].c_str())) + { + std::cerr << "Error copying file (if different) from \"" + << args[cc] << "\" to \"" << args[args.size() - 1] + << "\".\n"; + return_value = 1; + } + } + return return_value; } // Copy directory content -- 2.5.0
From 3774ba18d8e193b68685c84f4ccb0b0e4ea2b5a9 Mon Sep 17 00:00:00 2001 From: "Bartosz Kosiorek bartosz.kosio...@tomtom.com" <bartosz.kosio...@tomtom.com> Date: Thu, 3 Dec 2015 21:29:30 +0100 Subject: [PATCH 2/2] Add unit tests for "copy" and "copy_if_different" commands --- ...source-directory-target-is-directory-result.txt | 1 + ...source-directory-target-is-directory-stderr.txt | 0 .../CommandLine/E_copy-one-source-file-result.txt | 1 + .../CommandLine/E_copy-one-source-file-stderr.txt | 1 + ...ree-source-files-target-is-directory-result.txt | 1 + ...ree-source-files-target-is-directory-stderr.txt | 0 ...py-three-source-files-target-is-file-result.txt | 1 + ...py-three-source-files-target-is-file-stderr.txt | 1 + ...bad-source-files-target-is-directory-result.txt | 1 + ...bad-source-files-target-is-directory-stderr.txt | 1 + ...source-directory-target-is-directory-result.txt | 1 + ...source-directory-target-is-directory-stderr.txt | 0 ...ree-source-files-target-is-directory-result.txt | 1 + ...ree-source-files-target-is-directory-stderr.txt | 0 ...nt-three-source-files-target-is-file-result.txt | 1 + ...nt-three-source-files-target-is-file-stderr.txt | 1 + Tests/RunCMake/CommandLine/RunCMakeTest.cmake | 44 ++++++++++++++++++++++ .../CommandLine/test_copy_command_dir/file1.txt | 0 .../CommandLine/test_copy_command_dir/file2.txt | 0 .../CommandLine/test_copy_command_dir/file3.txt | 0 20 files changed, 56 insertions(+) create mode 100644 Tests/RunCMake/CommandLine/E_copy-one-source-directory-target-is-directory-result.txt create mode 100644 Tests/RunCMake/CommandLine/E_copy-one-source-directory-target-is-directory-stderr.txt create mode 100644 Tests/RunCMake/CommandLine/E_copy-one-source-file-result.txt create mode 100644 Tests/RunCMake/CommandLine/E_copy-one-source-file-stderr.txt create mode 100644 Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-directory-result.txt create mode 100644 Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-directory-stderr.txt create mode 100644 Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-file-result.txt create mode 100644 Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-file-stderr.txt create mode 100644 Tests/RunCMake/CommandLine/E_copy-two-good-and-one-bad-source-files-target-is-directory-result.txt create mode 100644 Tests/RunCMake/CommandLine/E_copy-two-good-and-one-bad-source-files-target-is-directory-stderr.txt create mode 100644 Tests/RunCMake/CommandLine/E_copy_if_different-one-source-directory-target-is-directory-result.txt create mode 100644 Tests/RunCMake/CommandLine/E_copy_if_different-one-source-directory-target-is-directory-stderr.txt create mode 100644 Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-directory-result.txt create mode 100644 Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-directory-stderr.txt create mode 100644 Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-file-result.txt create mode 100644 Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-file-stderr.txt create mode 100644 Tests/RunCMake/CommandLine/test_copy_command_dir/file1.txt create mode 100644 Tests/RunCMake/CommandLine/test_copy_command_dir/file2.txt create mode 100644 Tests/RunCMake/CommandLine/test_copy_command_dir/file3.txt diff --git a/Tests/RunCMake/CommandLine/E_copy-one-source-directory-target-is-directory-result.txt b/Tests/RunCMake/CommandLine/E_copy-one-source-directory-target-is-directory-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_copy-one-source-directory-target-is-directory-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CommandLine/E_copy-one-source-directory-target-is-directory-stderr.txt b/Tests/RunCMake/CommandLine/E_copy-one-source-directory-target-is-directory-stderr.txt new file mode 100644 index 0000000..e69de29 diff --git a/Tests/RunCMake/CommandLine/E_copy-one-source-file-result.txt b/Tests/RunCMake/CommandLine/E_copy-one-source-file-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_copy-one-source-file-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/E_copy-one-source-file-stderr.txt b/Tests/RunCMake/CommandLine/E_copy-one-source-file-stderr.txt new file mode 100644 index 0000000..9a9301d --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_copy-one-source-file-stderr.txt @@ -0,0 +1 @@ +^CMake Error: .* diff --git a/Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-directory-result.txt b/Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-directory-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-directory-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-directory-stderr.txt b/Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-directory-stderr.txt new file mode 100644 index 0000000..e69de29 diff --git a/Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-file-result.txt b/Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-file-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-file-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-file-stderr.txt b/Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-file-stderr.txt new file mode 100644 index 0000000..2e23d0a --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_copy-three-source-files-target-is-file-stderr.txt @@ -0,0 +1 @@ +^Error: Target \(copy\).* is not a directory.$ diff --git a/Tests/RunCMake/CommandLine/E_copy-two-good-and-one-bad-source-files-target-is-directory-result.txt b/Tests/RunCMake/CommandLine/E_copy-two-good-and-one-bad-source-files-target-is-directory-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_copy-two-good-and-one-bad-source-files-target-is-directory-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/E_copy-two-good-and-one-bad-source-files-target-is-directory-stderr.txt b/Tests/RunCMake/CommandLine/E_copy-two-good-and-one-bad-source-files-target-is-directory-stderr.txt new file mode 100644 index 0000000..2d0d986 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_copy-two-good-and-one-bad-source-files-target-is-directory-stderr.txt @@ -0,0 +1 @@ +^Error copying file .*not_existing_file.bad\" to .* diff --git a/Tests/RunCMake/CommandLine/E_copy_if_different-one-source-directory-target-is-directory-result.txt b/Tests/RunCMake/CommandLine/E_copy_if_different-one-source-directory-target-is-directory-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_copy_if_different-one-source-directory-target-is-directory-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CommandLine/E_copy_if_different-one-source-directory-target-is-directory-stderr.txt b/Tests/RunCMake/CommandLine/E_copy_if_different-one-source-directory-target-is-directory-stderr.txt new file mode 100644 index 0000000..e69de29 diff --git a/Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-directory-result.txt b/Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-directory-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-directory-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-directory-stderr.txt b/Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-directory-stderr.txt new file mode 100644 index 0000000..e69de29 diff --git a/Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-file-result.txt b/Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-file-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-file-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-file-stderr.txt b/Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-file-stderr.txt new file mode 100644 index 0000000..fe20f8c --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_copy_if_different-three-source-files-target-is-file-stderr.txt @@ -0,0 +1 @@ +^Error: Target \(copy_if_different\).* is not a directory.$ diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake index 6b4b384..1fffa46 100644 --- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake @@ -101,6 +101,50 @@ if(UNIX) ) endif() +set(RunCMake_copy_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/test_copy_command_dir) +set(RunCMake_copy_TEST_SOURCE_DIR ${RunCMake_SOURCE_DIR}/test_copy_command_dir) +run_cmake_command(E_copy-one-source-file ${CMAKE_COMMAND} -E copy + ${RunCMake_copy_TEST_BINARY_DIR}/file1.txt) +run_cmake_command(E_copy-one-source-directory-target-is-directory + ${CMAKE_COMMAND} -E copy + ${RunCMake_copy_TEST_SOURCE_DIR}/file1.txt + ${RunCMake_copy_TEST_BINARY_DIR}) +run_cmake_command(E_copy-three-source-files-target-is-directory + ${CMAKE_COMMAND} -E copy + ${RunCMake_copy_TEST_SOURCE_DIR}/file1.txt + ${RunCMake_copy_TEST_SOURCE_DIR}/file2.txt + ${RunCMake_copy_TEST_SOURCE_DIR}/file3.txt + ${RunCMake_copy_TEST_BINARY_DIR}) +run_cmake_command(E_copy-three-source-files-target-is-file + ${CMAKE_COMMAND} -E copy + ${RunCMake_copy_TEST_SOURCE_DIR}/file1.txt + ${RunCMake_copy_TEST_SOURCE_DIR}/file2.txt + ${RunCMake_copy_TEST_SOURCE_DIR}/file3.txt + ${RunCMake_copy_TEST_BINARY_DIR}/file1.txt) +run_cmake_command(E_copy-two-good-and-one-bad-source-files-target-is-directory + ${CMAKE_COMMAND} -E copy + ${RunCMake_copy_TEST_SOURCE_DIR}/file1.txt + ${RunCMake_copy_TEST_SOURCE_DIR}/not_existing_file.bad + ${RunCMake_copy_TEST_SOURCE_DIR}/file3.txt + ${RunCMake_copy_TEST_BINARY_DIR}) + +run_cmake_command(E_copy_if_different-one-source-directory-target-is-directory + ${CMAKE_COMMAND} -E copy_if_different + ${RunCMake_copy_TEST_SOURCE_DIR}/file1.txt + ${RunCMake_copy_TEST_BINARY_DIR}) +run_cmake_command(E_copy_if_different-three-source-files-target-is-directory + ${CMAKE_COMMAND} -E copy_if_different + ${RunCMake_copy_TEST_SOURCE_DIR}/file1.txt + ${RunCMake_copy_TEST_SOURCE_DIR}/file2.txt + ${RunCMake_copy_TEST_SOURCE_DIR}/file3.txt + ${RunCMake_copy_TEST_BINARY_DIR}) +run_cmake_command(E_copy_if_different-three-source-files-target-is-file + ${CMAKE_COMMAND} -E copy_if_different + ${RunCMake_copy_TEST_SOURCE_DIR}/file1.txt + ${RunCMake_copy_TEST_SOURCE_DIR}/file2.txt + ${RunCMake_copy_TEST_SOURCE_DIR}/file3.txt + ${RunCMake_copy_TEST_BINARY_DIR}/file1.txt) + 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) diff --git a/Tests/RunCMake/CommandLine/test_copy_command_dir/file1.txt b/Tests/RunCMake/CommandLine/test_copy_command_dir/file1.txt new file mode 100644 index 0000000..e69de29 diff --git a/Tests/RunCMake/CommandLine/test_copy_command_dir/file2.txt b/Tests/RunCMake/CommandLine/test_copy_command_dir/file2.txt new file mode 100644 index 0000000..e69de29 diff --git a/Tests/RunCMake/CommandLine/test_copy_command_dir/file3.txt b/Tests/RunCMake/CommandLine/test_copy_command_dir/file3.txt new file mode 100644 index 0000000..e69de29 -- 2.5.0
-- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers