Browse Source

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.
Brad King 10 years ago
parent
commit
44fd71decb

+ 6 - 0
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=<file>`` option to specify file names using
+  lines in a file to overcome command-line length limits.

+ 53 - 0
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<std::string>& 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<std::string>& args)
 {
   // IF YOU ADD A NEW COMMAND, DOCUMENT IT ABOVE and in cmakemain.cxx
@@ -744,6 +789,14 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& 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());

+ 1 - 0
Tests/RunCMake/CommandLine/E_tar-bad-from1-result.txt

@@ -0,0 +1 @@
+1

+ 1 - 0
Tests/RunCMake/CommandLine/E_tar-bad-from1-stderr.txt

@@ -0,0 +1 @@
+^CMake Error: -E tar --files-from= file 'bad' not found$

+ 1 - 0
Tests/RunCMake/CommandLine/E_tar-bad-from2-result.txt

@@ -0,0 +1 @@
+1

+ 1 - 0
Tests/RunCMake/CommandLine/E_tar-bad-from2-stderr.txt

@@ -0,0 +1 @@
+^CMake Error: -E tar --files-from= file '\.' is a directory$

+ 1 - 0
Tests/RunCMake/CommandLine/E_tar-bad-from3-result.txt

@@ -0,0 +1 @@
+1

+ 2 - 0
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$

+ 1 - 0
Tests/RunCMake/CommandLine/E_tar-bad-from3.txt

@@ -0,0 +1 @@
+-add-file=option-typo

+ 1 - 0
Tests/RunCMake/CommandLine/E_tar-bad-from4-result.txt

@@ -0,0 +1 @@
+1

+ 2 - 0
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$

+ 2 - 0
Tests/RunCMake/CommandLine/E_tar-bad-from4.txt

@@ -0,0 +1,2 @@
+
+does-not-exist

+ 1 - 0
Tests/RunCMake/CommandLine/E_tar-bad-from5-result.txt

@@ -0,0 +1 @@
+1

+ 2 - 0
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$

+ 2 - 0
Tests/RunCMake/CommandLine/E_tar-bad-from5.txt

@@ -0,0 +1,2 @@
+
+--add-file=does-not-exist

+ 5 - 0
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")