From 44fd71decbca329d9cdfc196a073a62668af53f2 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 26 Jan 2015 13:28:31 -0500 Subject: [PATCH] cmake: Teach "-E tar" command a "--files-from=" option Read file names from the lines of a specified file. Reject input lines starting in '-' to leave room for option parsing to be added later. Add just '--add-file=' now to allow files starting in '-' to be specified. --- Help/release/dev/cmake-E-tar-files-from.rst | 6 +++ Source/cmcmd.cxx | 53 +++++++++++++++++++ .../CommandLine/E_tar-bad-from1-result.txt | 1 + .../CommandLine/E_tar-bad-from1-stderr.txt | 1 + .../CommandLine/E_tar-bad-from2-result.txt | 1 + .../CommandLine/E_tar-bad-from2-stderr.txt | 1 + .../CommandLine/E_tar-bad-from3-result.txt | 1 + .../CommandLine/E_tar-bad-from3-stderr.txt | 2 + .../RunCMake/CommandLine/E_tar-bad-from3.txt | 1 + .../CommandLine/E_tar-bad-from4-result.txt | 1 + .../CommandLine/E_tar-bad-from4-stderr.txt | 2 + .../RunCMake/CommandLine/E_tar-bad-from4.txt | 2 + .../CommandLine/E_tar-bad-from5-result.txt | 1 + .../CommandLine/E_tar-bad-from5-stderr.txt | 2 + .../RunCMake/CommandLine/E_tar-bad-from5.txt | 2 + Tests/RunCMake/CommandLine/RunCMakeTest.cmake | 5 ++ 16 files changed, 82 insertions(+) create mode 100644 Help/release/dev/cmake-E-tar-files-from.rst create mode 100644 Tests/RunCMake/CommandLine/E_tar-bad-from1-result.txt create mode 100644 Tests/RunCMake/CommandLine/E_tar-bad-from1-stderr.txt create mode 100644 Tests/RunCMake/CommandLine/E_tar-bad-from2-result.txt create mode 100644 Tests/RunCMake/CommandLine/E_tar-bad-from2-stderr.txt create mode 100644 Tests/RunCMake/CommandLine/E_tar-bad-from3-result.txt create mode 100644 Tests/RunCMake/CommandLine/E_tar-bad-from3-stderr.txt create mode 100644 Tests/RunCMake/CommandLine/E_tar-bad-from3.txt create mode 100644 Tests/RunCMake/CommandLine/E_tar-bad-from4-result.txt create mode 100644 Tests/RunCMake/CommandLine/E_tar-bad-from4-stderr.txt create mode 100644 Tests/RunCMake/CommandLine/E_tar-bad-from4.txt create mode 100644 Tests/RunCMake/CommandLine/E_tar-bad-from5-result.txt create mode 100644 Tests/RunCMake/CommandLine/E_tar-bad-from5-stderr.txt create mode 100644 Tests/RunCMake/CommandLine/E_tar-bad-from5.txt 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")