Browse Source

Merge topic 'file-ARCHIVE-files-dirs'

bbcff21f71 file(ARCHIVE*): Collapse FILES and DIRECTORY options

Acked-by: Kitware Robot <[email protected]>
Merge-request: !4955
Brad King 5 years ago
parent
commit
9c3e9881ef

+ 16 - 14
Help/command/file.rst

@@ -899,15 +899,15 @@ Archiving
 .. code-block:: cmake
 
   file(ARCHIVE_CREATE OUTPUT <archive>
-    [FILES <files>]
-    [DIRECTORY <dirs>]
+    PATHS <paths>...
     [FORMAT <format>]
     [COMPRESSION <compression>]
     [MTIME <mtime>]
     [VERBOSE])
 
-Creates the specified ``<archive>`` file with the content of ``<files>`` and
-``<dirs>``.
+Creates the specified ``<archive>`` file with the files and directories
+listed in ``<paths>``.  Note that ``<paths>`` must list actual files or
+directories, wildcards are not supported.
 
 Use the ``FORMAT`` option to specify the archive format.  Supported values
 for ``<format>`` are ``7zip``, ``gnutar``, ``pax``, ``paxr``, ``raw`` and
@@ -933,21 +933,23 @@ the ``MTIME`` option.
 .. code-block:: cmake
 
   file(ARCHIVE_EXTRACT INPUT <archive>
-    [FILES <files>]
-    [DIRECTORY <dirs>]
     [DESTINATION <dir>]
+    [PATTERNS <patterns>...]
     [LIST_ONLY]
     [VERBOSE])
 
-Extracts or lists the content of an archive specified by ``INPUT``.
+Extracts or lists the content of the specified ``<archive>``.
 
-The directory where the content of the archive will be extracted can
-be specified via ``DESTINATION``. If the directory does not exit, it
-will be created.
+The directory where the content of the archive will be extracted to can
+be specified using the ``DESTINATION`` option.  If the directory does not
+exist, it will be created.  If ``DESTINATION`` is not given, the current
+binary directory will be used.
 
-To select which files and directories will be extracted or listed
-use  ``FILES`` and ``DIRECTORY`` options.
+If required, you may select which files and directories to list or extract
+from the archive using the specified ``<patterns>``.  Wildcards are supported.
+If the ``PATTERNS`` option is not given, the entire archive will be listed or
+extracted.
 
-``LIST_ONLY`` will only list the files in the archive.
+``LIST_ONLY`` will list the files in the archive rather than extract them.
 
-With ``VERBOSE`` the command will produce verbose output.
+With ``VERBOSE``, the command will produce verbose output.

+ 22 - 35
Source/cmFileCommand.cxx

@@ -8,7 +8,6 @@
 #include <cmath>
 #include <cstdio>
 #include <cstdlib>
-#include <iterator>
 #include <map>
 #include <set>
 #include <sstream>
@@ -2945,8 +2944,7 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
     std::string Compression;
     std::string MTime;
     bool Verbose = false;
-    std::vector<std::string> Files;
-    std::vector<std::string> Directories;
+    std::vector<std::string> Paths;
   };
 
   static auto const parser = cmArgumentParser<Arguments>{}
@@ -2955,8 +2953,7 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
                                .Bind("COMPRESSION"_s, &Arguments::Compression)
                                .Bind("MTIME"_s, &Arguments::MTime)
                                .Bind("VERBOSE"_s, &Arguments::Verbose)
-                               .Bind("FILES"_s, &Arguments::Files)
-                               .Bind("DIRECTORY"_s, &Arguments::Directories);
+                               .Bind("PATHS"_s, &Arguments::Paths);
 
   std::vector<std::string> unrecognizedArguments;
   std::vector<std::string> keywordsMissingValues;
@@ -2970,9 +2967,9 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
     return false;
   }
 
-  const std::vector<std::string> LIST_ARGS = {
-    "OUTPUT", "FORMAT", "COMPRESSION", "MTIME", "FILES", "DIRECTORY",
-  };
+  const std::vector<std::string> LIST_ARGS = { "OUTPUT", "FORMAT",
+                                               "COMPRESSION", "MTIME",
+                                               "PATHS" };
   auto kwbegin = keywordsMissingValues.cbegin();
   auto kwend = cmRemoveMatching(keywordsMissingValues, LIST_ARGS);
   if (kwend != kwbegin) {
@@ -3010,11 +3007,6 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
                            { "XZ", cmSystemTools::TarCompressXZ },
                            { "Zstd", cmSystemTools::TarCompressZstd } };
 
-  std::string const& outFile = parsedArgs.Output;
-  std::vector<std::string> files = parsedArgs.Files;
-  std::copy(parsedArgs.Directories.begin(), parsedArgs.Directories.end(),
-            std::back_inserter(files));
-
   cmSystemTools::cmTarCompression compress = cmSystemTools::TarCompressNone;
   auto typeIt = compressionTypeMap.find(parsedArgs.Compression);
   if (typeIt != compressionTypeMap.end()) {
@@ -3026,14 +3018,16 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
     return false;
   }
 
-  if (files.empty()) {
-    status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING,
-                                      "No files or directories specified");
+  if (parsedArgs.Paths.empty()) {
+    status.SetError("ARCHIVE_CREATE requires a non-empty list of PATHS");
+    cmSystemTools::SetFatalErrorOccured();
+    return false;
   }
 
-  if (!cmSystemTools::CreateTar(outFile, files, compress, parsedArgs.Verbose,
-                                parsedArgs.MTime, parsedArgs.Format)) {
-    status.SetError(cmStrCat("failed to compress: ", outFile));
+  if (!cmSystemTools::CreateTar(parsedArgs.Output, parsedArgs.Paths, compress,
+                                parsedArgs.Verbose, parsedArgs.MTime,
+                                parsedArgs.Format)) {
+    status.SetError(cmStrCat("failed to compress: ", parsedArgs.Output));
     cmSystemTools::SetFatalErrorOccured();
     return false;
   }
@@ -3050,8 +3044,7 @@ bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
     bool Verbose = false;
     bool ListOnly = false;
     std::string Destination;
-    std::vector<std::string> Files;
-    std::vector<std::string> Directories;
+    std::vector<std::string> Patterns;
   };
 
   static auto const parser = cmArgumentParser<Arguments>{}
@@ -3059,8 +3052,7 @@ bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
                                .Bind("VERBOSE"_s, &Arguments::Verbose)
                                .Bind("LIST_ONLY"_s, &Arguments::ListOnly)
                                .Bind("DESTINATION"_s, &Arguments::Destination)
-                               .Bind("FILES"_s, &Arguments::Files)
-                               .Bind("DIRECTORY"_s, &Arguments::Directories);
+                               .Bind("PATTERNS"_s, &Arguments::Patterns);
 
   std::vector<std::string> unrecognizedArguments;
   std::vector<std::string> keywordsMissingValues;
@@ -3074,12 +3066,8 @@ bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
     return false;
   }
 
-  const std::vector<std::string> LIST_ARGS = {
-    "INPUT",
-    "DESTINATION",
-    "FILES",
-    "DIRECTORY",
-  };
+  const std::vector<std::string> LIST_ARGS = { "INPUT", "DESTINATION",
+                                               "PATTERNS" };
   auto kwbegin = keywordsMissingValues.cbegin();
   auto kwend = cmRemoveMatching(keywordsMissingValues, LIST_ARGS);
   if (kwend != kwbegin) {
@@ -3090,18 +3078,16 @@ bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
   }
 
   std::string inFile = parsedArgs.Input;
-  std::vector<std::string> files = parsedArgs.Files;
-  std::copy(parsedArgs.Directories.begin(), parsedArgs.Directories.end(),
-            std::back_inserter(files));
 
   if (parsedArgs.ListOnly) {
-    if (!cmSystemTools::ListTar(inFile, files, parsedArgs.Verbose)) {
+    if (!cmSystemTools::ListTar(inFile, parsedArgs.Patterns,
+                                parsedArgs.Verbose)) {
       status.SetError(cmStrCat("failed to list: ", inFile));
       cmSystemTools::SetFatalErrorOccured();
       return false;
     }
   } else {
-    std::string destDir = cmSystemTools::GetCurrentWorkingDirectory();
+    std::string destDir = status.GetMakefile().GetCurrentBinaryDirectory();
     if (!parsedArgs.Destination.empty()) {
       if (cmSystemTools::FileIsFullPath(parsedArgs.Destination)) {
         destDir = parsedArgs.Destination;
@@ -3129,7 +3115,8 @@ bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
       return false;
     }
 
-    if (!cmSystemTools::ExtractTar(inFile, files, parsedArgs.Verbose)) {
+    if (!cmSystemTools::ExtractTar(inFile, parsedArgs.Patterns,
+                                   parsedArgs.Verbose)) {
       status.SetError(cmStrCat("failed to extract: ", inFile));
       cmSystemTools::SetFatalErrorOccured();
       return false;

+ 12 - 12
Tests/RunCMake/File_Archive/roundtrip.cmake

@@ -36,17 +36,17 @@ file(REMOVE_RECURSE ${FULL_DECOMPRESS_DIR})
 file(MAKE_DIRECTORY ${FULL_DECOMPRESS_DIR})
 
 file(ARCHIVE_CREATE
-    OUTPUT ${FULL_OUTPUT_NAME}
-    FORMAT "${ARCHIVE_FORMAT}"
-    COMPRESSION "${COMPRESSION_TYPE}"
-    VERBOSE
-    DIRECTORY ${COMPRESS_DIR})
+  OUTPUT ${FULL_OUTPUT_NAME}
+  FORMAT "${ARCHIVE_FORMAT}"
+  COMPRESSION "${COMPRESSION_TYPE}"
+  VERBOSE
+  PATHS ${COMPRESS_DIR})
 
 file(ARCHIVE_EXTRACT
-    INPUT ${FULL_OUTPUT_NAME}
-    ${DECOMPRESSION_OPTIONS}
-    DESTINATION ${FULL_DECOMPRESS_DIR}
-    VERBOSE)
+  INPUT ${FULL_OUTPUT_NAME}
+  ${DECOMPRESSION_OPTIONS}
+  DESTINATION ${FULL_DECOMPRESS_DIR}
+  VERBOSE)
 
 if(CUSTOM_CHECK_FILES)
   set(CHECK_FILES ${CUSTOM_CHECK_FILES})
@@ -57,11 +57,11 @@ foreach(file ${CHECK_FILES})
   set(output ${FULL_DECOMPRESS_DIR}/${COMPRESS_DIR}/${file})
 
   if(NOT EXISTS ${input})
-     message(SEND_ERROR "Cannot find input file ${output}")
+    message(SEND_ERROR "Cannot find input file ${output}")
   endif()
 
   if(NOT EXISTS ${output})
-     message(SEND_ERROR "Cannot find output file ${output}")
+    message(SEND_ERROR "Cannot find output file ${output}")
   endif()
 
   file(MD5 ${input} input_md5)
@@ -76,7 +76,7 @@ foreach(file ${NOT_EXISTING_FILES_CHECK})
   set(output ${FULL_DECOMPRESS_DIR}/${COMPRESS_DIR}/${file})
 
   if(EXISTS ${output})
-     message(SEND_ERROR "File ${output} exists but it shouldn't")
+    message(SEND_ERROR "File ${output} exists but it shouldn't")
   endif()
 endforeach()
 

+ 2 - 2
Tests/RunCMake/File_Archive/zip-filtered.cmake

@@ -3,9 +3,9 @@ set(OUTPUT_NAME "test.zip")
 set(ARCHIVE_FORMAT zip)
 
 set(DECOMPRESSION_OPTIONS
-  FILES
+  PATTERNS
     compress_dir/f1.txt # Decompress only file
-    compress_dir/d1     # and whole directory
+    compress_*/d?       # and whole directory (has only one match)
 )
 
 set(CUSTOM_CHECK_FILES