diff --git a/Help/release/dev/cmake-E-tar-files-from.rst b/Help/release/dev/cmake-E-tar-files-from.rst new file mode 100644 index 000000000..f6087ff87 --- /dev/null +++ b/Help/release/dev/cmake-E-tar-files-from.rst @@ -0,0 +1,6 @@ +cmake-E-tar-files-from +---------------------- + +* The :manual:`cmake(1)` ``-E tar`` command learned a new + ``--files-from=`` option to specify file names using + lines in a file to overcome command-line length limits. diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 7ca3eb3ac..28fcd27f7 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -94,6 +94,51 @@ void CMakeCommandUsage(const char* program) cmSystemTools::Error(errorStream.str().c_str()); } +static bool cmTarFilesFrom(std::string const& file, + std::vector& files) +{ + if (cmSystemTools::FileIsDirectory(file)) + { + std::ostringstream e; + e << "-E tar --files-from= file '" << file << "' is a directory"; + cmSystemTools::Error(e.str().c_str()); + return false; + } + cmsys::ifstream fin(file.c_str()); + if (!fin) + { + std::ostringstream e; + e << "-E tar --files-from= file '" << file << "' not found"; + cmSystemTools::Error(e.str().c_str()); + return false; + } + std::string line; + while (cmSystemTools::GetLineFromStream(fin, line)) + { + if (line.empty()) + { + continue; + } + if (cmHasLiteralPrefix(line, "--add-file=")) + { + files.push_back(line.substr(11)); + } + else if (cmHasLiteralPrefix(line, "-")) + { + std::ostringstream e; + e << "-E tar --files-from='" << file << "' file invalid line:\n" + << line << "\n"; + cmSystemTools::Error(e.str().c_str()); + return false; + } + else + { + files.push_back(line); + } + } + return true; +} + int cmcmd::ExecuteCMakeCommand(std::vector& args) { // IF YOU ADD A NEW COMMAND, DOCUMENT IT ABOVE and in cmakemain.cxx @@ -744,6 +789,14 @@ int cmcmd::ExecuteCMakeCommand(std::vector& args) { mtime = arg.substr(8); } + else if (cmHasLiteralPrefix(arg, "--files-from=")) + { + std::string const& files_from = arg.substr(13); + if (!cmTarFilesFrom(files_from, files)) + { + return 1; + } + } else { cmSystemTools::Error("Unknown option to -E tar: ", arg.c_str()); diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from1-result.txt b/Tests/RunCMake/CommandLine/E_tar-bad-from1-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_tar-bad-from1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from1-stderr.txt b/Tests/RunCMake/CommandLine/E_tar-bad-from1-stderr.txt new file mode 100644 index 000000000..d67431d40 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_tar-bad-from1-stderr.txt @@ -0,0 +1 @@ +^CMake Error: -E tar --files-from= file 'bad' not found$ diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from2-result.txt b/Tests/RunCMake/CommandLine/E_tar-bad-from2-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_tar-bad-from2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from2-stderr.txt b/Tests/RunCMake/CommandLine/E_tar-bad-from2-stderr.txt new file mode 100644 index 000000000..d1d278c73 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_tar-bad-from2-stderr.txt @@ -0,0 +1 @@ +^CMake Error: -E tar --files-from= file '\.' is a directory$ diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from3-result.txt b/Tests/RunCMake/CommandLine/E_tar-bad-from3-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_tar-bad-from3-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from3-stderr.txt b/Tests/RunCMake/CommandLine/E_tar-bad-from3-stderr.txt new file mode 100644 index 000000000..147bd8042 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_tar-bad-from3-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: -E tar --files-from='.*/Tests/RunCMake/CommandLine/E_tar-bad-from3.txt' file invalid line: +-add-file=option-typo$ diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from3.txt b/Tests/RunCMake/CommandLine/E_tar-bad-from3.txt new file mode 100644 index 000000000..5bad1c3f3 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_tar-bad-from3.txt @@ -0,0 +1 @@ +-add-file=option-typo diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from4-result.txt b/Tests/RunCMake/CommandLine/E_tar-bad-from4-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_tar-bad-from4-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from4-stderr.txt b/Tests/RunCMake/CommandLine/E_tar-bad-from4-stderr.txt new file mode 100644 index 000000000..1417d4d32 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_tar-bad-from4-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: archive_read_disk_entry_from_file 'does-not-exist':.* +CMake Error: Problem creating tar: bad.tar$ diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from4.txt b/Tests/RunCMake/CommandLine/E_tar-bad-from4.txt new file mode 100644 index 000000000..4b97f796c --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_tar-bad-from4.txt @@ -0,0 +1,2 @@ + +does-not-exist diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from5-result.txt b/Tests/RunCMake/CommandLine/E_tar-bad-from5-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_tar-bad-from5-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from5-stderr.txt b/Tests/RunCMake/CommandLine/E_tar-bad-from5-stderr.txt new file mode 100644 index 000000000..1417d4d32 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_tar-bad-from5-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: archive_read_disk_entry_from_file 'does-not-exist':.* +CMake Error: Problem creating tar: bad.tar$ diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from5.txt b/Tests/RunCMake/CommandLine/E_tar-bad-from5.txt new file mode 100644 index 000000000..9ea755b26 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_tar-bad-from5.txt @@ -0,0 +1,2 @@ + +--add-file=does-not-exist diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake index 2994f160f..2be6651fa 100644 --- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake @@ -2,6 +2,11 @@ include(RunCMake) run_cmake_command(E_tar-bad-opt1 ${CMAKE_COMMAND} -E tar cvf bad.tar --bad) run_cmake_command(E_tar-bad-mtime1 ${CMAKE_COMMAND} -E tar cvf bad.tar --mtime=bad .) +run_cmake_command(E_tar-bad-from1 ${CMAKE_COMMAND} -E tar cvf bad.tar --files-from=bad) +run_cmake_command(E_tar-bad-from2 ${CMAKE_COMMAND} -E tar cvf bad.tar --files-from=.) +run_cmake_command(E_tar-bad-from3 ${CMAKE_COMMAND} -E tar cvf bad.tar --files-from=${CMAKE_CURRENT_LIST_DIR}/E_tar-bad-from3.txt) +run_cmake_command(E_tar-bad-from4 ${CMAKE_COMMAND} -E tar cvf bad.tar --files-from=${CMAKE_CURRENT_LIST_DIR}/E_tar-bad-from4.txt) +run_cmake_command(E_tar-bad-from5 ${CMAKE_COMMAND} -E tar cvf bad.tar --files-from=${CMAKE_CURRENT_LIST_DIR}/E_tar-bad-from5.txt) run_cmake_command(E_tar-end-opt1 ${CMAKE_COMMAND} -E tar cvf bad.tar -- --bad) run_cmake_command(E_tar-end-opt2 ${CMAKE_COMMAND} -E tar cvf bad.tar --) run_cmake_command(E_tar-mtime ${CMAKE_COMMAND} -E tar cvf bad.tar "--mtime=1970-01-01 00:00:00 UTC")