Browse Source

cmake: tar: Parse 'cmake -E tar' arguments

Bartosz Kosiorek 6 years ago
parent
commit
ea9a2c1759

+ 8 - 0
Help/release/dev/cmake-e-tar-error-handling.rst

@@ -0,0 +1,8 @@
+cmake-e-tar-error-handling
+--------------------------
+
+* The :manual:`cmake(1)` ``-E tar`` tool now parses all flags, and if an
+  invalid flag was provided, a warning is issued.
+* The :manual:`cmake(1)` ``-E tar`` tool now displays an error if no action
+  flag was specified, along with a list of possible actions: ``t`` (list),
+  ``c`` (create) or ``x`` (extract).

+ 9 - 0
Source/cmSystemTools.h

@@ -412,6 +412,14 @@ public:
   /** Setup the environment to enable VS 8 IDE output.  */
   static void EnableVSConsoleOutput();
 
+  enum cmTarAction
+  {
+    TarActionCreate,
+    TarActionList,
+    TarActionExtract,
+    TarActionNone
+  };
+
   /** Create tar */
   enum cmTarCompression
   {
@@ -420,6 +428,7 @@ public:
     TarCompressXZ,
     TarCompressNone
   };
+
   static bool ListTar(const char* outFileName, bool verbose);
   static bool CreateTar(const char* outFileName,
                         const std::vector<std::string>& files,

+ 44 - 18
Source/cmcmd.cxx

@@ -1078,21 +1078,47 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
           files.push_back(arg);
         }
       }
+      cmSystemTools::cmTarAction action = cmSystemTools::TarActionNone;
       cmSystemTools::cmTarCompression compress =
         cmSystemTools::TarCompressNone;
       bool verbose = false;
       int nCompress = 0;
-      if (flags.find_first_of('j') != std::string::npos) {
-        compress = cmSystemTools::TarCompressBZip2;
-        ++nCompress;
-      }
-      if (flags.find_first_of('J') != std::string::npos) {
-        compress = cmSystemTools::TarCompressXZ;
-        ++nCompress;
-      }
-      if (flags.find_first_of('z') != std::string::npos) {
-        compress = cmSystemTools::TarCompressGZip;
-        ++nCompress;
+
+      for (auto flag : flags) {
+        switch (flag) {
+          case '-':
+          case 'f': {
+            // Keep for backward compatibility. Ignored
+          } break;
+          case 'j': {
+            compress = cmSystemTools::TarCompressBZip2;
+            ++nCompress;
+          } break;
+          case 'J': {
+            compress = cmSystemTools::TarCompressXZ;
+            ++nCompress;
+          } break;
+          case 'z': {
+            compress = cmSystemTools::TarCompressGZip;
+            ++nCompress;
+          } break;
+          case 'v': {
+            verbose = true;
+          } break;
+          case 't': {
+            action = cmSystemTools::TarActionList;
+          } break;
+          case 'c': {
+            action = cmSystemTools::TarActionCreate;
+          } break;
+          case 'x': {
+            action = cmSystemTools::TarActionExtract;
+          } break;
+          default: {
+            cmSystemTools::Message(
+              std::string("tar: Unknown argument: ") + flag, "Warning");
+          }
+        }
       }
       if ((format == "7zip" || format == "zip") && nCompress > 0) {
         cmSystemTools::Error("Can not use compression flags with format: " +
@@ -1104,16 +1130,12 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
                              "at most one flag of z, j, or J may be used");
         return 1;
       }
-      if (flags.find_first_of('v') != std::string::npos) {
-        verbose = true;
-      }
-
-      if (flags.find_first_of('t') != std::string::npos) {
+      if (action == cmSystemTools::TarActionList) {
         if (!cmSystemTools::ListTar(outFile.c_str(), verbose)) {
           cmSystemTools::Error("Problem listing tar: " + outFile);
           return 1;
         }
-      } else if (flags.find_first_of('c') != std::string::npos) {
+      } else if (action == cmSystemTools::TarActionCreate) {
         if (files.empty()) {
           cmSystemTools::Message("tar: No files or directories specified",
                                  "Warning");
@@ -1123,7 +1145,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
           cmSystemTools::Error("Problem creating tar: " + outFile);
           return 1;
         }
-      } else if (flags.find_first_of('x') != std::string::npos) {
+      } else if (action == cmSystemTools::TarActionExtract) {
         if (!cmSystemTools::ExtractTar(outFile.c_str(), verbose)) {
           cmSystemTools::Error("Problem extracting tar: " + outFile);
           return 1;
@@ -1144,6 +1166,10 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
           cmSystemTools::Delay(delay);
         }
 #endif
+      } else {
+        cmSystemTools::Error("tar: No action specified. Please choose: 't' "
+                             "(list), 'c' (create) or 'x' (extract)");
+        return 1;
       }
       return 0;
     }

+ 17 - 15
Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake

@@ -4,21 +4,23 @@ function(external_command_test NAME)
   run_cmake_command(${NAME} ${CMAKE_COMMAND} -E ${ARGN})
 endfunction()
 
-external_command_test(without-files tar cvf bad.tar)
-external_command_test(bad-opt1   tar cvf bad.tar --bad)
-external_command_test(bad-mtime1 tar cvf bad.tar --mtime=bad .)
-external_command_test(bad-from1  tar cvf bad.tar --files-from=bad)
-external_command_test(bad-from2  tar cvf bad.tar --files-from=.)
-external_command_test(bad-from3  tar cvf bad.tar --files-from=${CMAKE_CURRENT_LIST_DIR}/bad-from3.txt)
-external_command_test(bad-from4  tar cvf bad.tar --files-from=${CMAKE_CURRENT_LIST_DIR}/bad-from4.txt)
-external_command_test(bad-from5  tar cvf bad.tar --files-from=${CMAKE_CURRENT_LIST_DIR}/bad-from5.txt)
-external_command_test(bad-file   tar cf  bad.tar badfile.txt ${CMAKE_CURRENT_LIST_DIR}/test-file.txt)
-external_command_test(end-opt1   tar cvf bad.tar -- --bad)
-external_command_test(end-opt2   tar cvf bad.tar --)
-external_command_test(mtime      tar cvf bad.tar "--mtime=1970-01-01 00:00:00 UTC" ${CMAKE_CURRENT_LIST_DIR}/test-file.txt)
-external_command_test(bad-format tar cvf bad.tar "--format=bad-format" ${CMAKE_CURRENT_LIST_DIR}/test-file.txt)
-external_command_test(zip-bz2    tar cvjf bad.tar "--format=zip" ${CMAKE_CURRENT_LIST_DIR}/test-file.txt)
-external_command_test(7zip-gz    tar cvzf bad.tar "--format=7zip" ${CMAKE_CURRENT_LIST_DIR}/test-file.txt)
+external_command_test(without-files      tar cvf bad.tar)
+external_command_test(bad-opt1           tar cvf bad.tar --bad)
+external_command_test(bad-mtime1         tar cvf bad.tar --mtime=bad .)
+external_command_test(bad-from1          tar cvf bad.tar --files-from=bad)
+external_command_test(bad-from2          tar cvf bad.tar --files-from=.)
+external_command_test(bad-from3          tar cvf bad.tar --files-from=${CMAKE_CURRENT_LIST_DIR}/bad-from3.txt)
+external_command_test(bad-from4          tar cvf bad.tar --files-from=${CMAKE_CURRENT_LIST_DIR}/bad-from4.txt)
+external_command_test(bad-from5          tar cvf bad.tar --files-from=${CMAKE_CURRENT_LIST_DIR}/bad-from5.txt)
+external_command_test(bad-file           tar cf  bad.tar badfile.txt ${CMAKE_CURRENT_LIST_DIR}/test-file.txt)
+external_command_test(bad-without-action tar f bad.tar ${CMAKE_CURRENT_LIST_DIR}/test-file.txt)
+external_command_test(bad-wrong-flag     tar cvfq bad.tar ${CMAKE_CURRENT_LIST_DIR}/test-file.txt)
+external_command_test(end-opt1           tar cvf bad.tar -- --bad)
+external_command_test(end-opt2           tar cvf bad.tar --)
+external_command_test(mtime              tar cvf bad.tar "--mtime=1970-01-01 00:00:00 UTC" ${CMAKE_CURRENT_LIST_DIR}/test-file.txt)
+external_command_test(bad-format         tar cvf bad.tar "--format=bad-format" ${CMAKE_CURRENT_LIST_DIR}/test-file.txt)
+external_command_test(zip-bz2            tar cvjf bad.tar "--format=zip" ${CMAKE_CURRENT_LIST_DIR}/test-file.txt)
+external_command_test(7zip-gz            tar cvzf bad.tar "--format=7zip" ${CMAKE_CURRENT_LIST_DIR}/test-file.txt)
 
 run_cmake(7zip)
 run_cmake(gnutar)

+ 1 - 0
Tests/RunCMake/CommandLineTar/bad-without-action-result.txt

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

+ 1 - 0
Tests/RunCMake/CommandLineTar/bad-without-action-stderr.txt

@@ -0,0 +1 @@
+^CMake Error: tar: No action specified. Please choose: 't' \(list\), 'c' \(create\) or 'x' \(extract\)$

+ 1 - 0
Tests/RunCMake/CommandLineTar/bad-wrong-flag-stderr.txt

@@ -0,0 +1 @@
+^tar: Unknown argument: q

+ 2 - 2
Tests/RunCMake/CommandLineTar/gnutar-gz.cmake

@@ -1,9 +1,9 @@
 set(OUTPUT_NAME "test.tar.gz")
 
-set(COMPRESSION_FLAGS cvzf)
+set(COMPRESSION_FLAGS -cvzf)
 set(COMPRESSION_OPTIONS --format=gnutar)
 
-set(DECOMPRESSION_FLAGS xvzf)
+set(DECOMPRESSION_FLAGS -xvzf)
 
 include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
 

+ 2 - 2
Tests/RunCMake/CommandLineTar/pax.cmake

@@ -1,9 +1,9 @@
 set(OUTPUT_NAME "test.tar")
 
-set(COMPRESSION_FLAGS cvf)
+set(COMPRESSION_FLAGS -cvf)
 set(COMPRESSION_OPTIONS --format=pax)
 
-set(DECOMPRESSION_FLAGS xvf)
+set(DECOMPRESSION_FLAGS -xvf)
 
 include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)