瀏覽代碼

Merge topic 'improve-tar-command'

8634576dcb cmake: Don't interrupt archive creation if unable to read a file.
c7c6a4a2cc Help: Update 'tar' documentation with supported arguments
7c47fd8cd1 cmake: tar: Display warning when no files provided during archive creation

Acked-by: Kitware Robot <[email protected]>
Merge-request: !3080
Kyle Edwards 6 年之前
父節點
當前提交
f1e53266e9

+ 15 - 0
Help/manual/cmake.1.rst

@@ -483,6 +483,21 @@ Available commands are:
 ``tar [cxt][vf][zjJ] file.tar [<options>] [--] [<file>...]``
   Create or extract a tar or zip archive.  Options are:
 
+  ``c``
+    Create a new archive containing the specified files.
+    If used, the <file> argument is mandatory.
+  ``x``
+    Extract to disk from the archive.
+  ``t``
+    List archive contents to stdout.
+  ``v``
+    Produce verbose output.
+  ``z``
+    Compress the resulting archive with gzip.
+  ``j``
+    Compress the resulting archive with bzip2.
+  ``J``
+    Compress the resulting archive with XZ.
   ``--``
     Stop interpreting options and treat all remaining arguments
     as file names even if they start in ``-``.

+ 6 - 0
Help/release/dev/cmake-e-tar-creating-archive.rst

@@ -0,0 +1,6 @@
+cmake-e-tar-creating-archive
+----------------------------
+
+* The :manual:`cmake(1)` ``-E tar`` tool now continues adding files to an
+  archive, even if some of the files aren't readable. This behavior is more
+  consistent with the classic ``tar`` tool.

+ 5 - 6
Source/cmArchiveWrite.cxx

@@ -179,12 +179,10 @@ cmArchiveWrite::~cmArchiveWrite()
 bool cmArchiveWrite::Add(std::string path, size_t skip, const char* prefix,
                          bool recursive)
 {
-  if (this->Okay()) {
-    if (!path.empty() && path.back() == '/') {
-      path.erase(path.size() - 1);
-    }
-    this->AddPath(path.c_str(), skip, prefix, recursive);
+  if (!path.empty() && path.back() == '/') {
+    path.erase(path.size() - 1);
   }
+  this->AddPath(path.c_str(), skip, prefix, recursive);
   return this->Okay();
 }
 
@@ -220,6 +218,7 @@ bool cmArchiveWrite::AddPath(const char* path, size_t skip, const char* prefix,
 
 bool cmArchiveWrite::AddFile(const char* file, size_t skip, const char* prefix)
 {
+  this->Error = "";
   // Skip the file if we have no name for it.  This may happen on a
   // top-level directory, which does not need to be included anyway.
   if (skip >= strlen(file)) {
@@ -241,7 +240,7 @@ bool cmArchiveWrite::AddFile(const char* file, size_t skip, const char* prefix)
   cm_archive_entry_copy_pathname(e, dest);
   if (archive_read_disk_entry_from_file(this->Disk, e, -1, nullptr) !=
       ARCHIVE_OK) {
-    this->Error = "archive_read_disk_entry_from_file '";
+    this->Error = "Unable to read from file '";
     this->Error += file;
     this->Error += "': ";
     this->Error += cm_archive_error_string(this->Disk);

+ 4 - 6
Source/cmSystemTools.cxx

@@ -1658,20 +1658,18 @@ bool cmSystemTools::CreateTar(const char* outFileName,
 
   a.SetMTime(mtime);
   a.SetVerbose(verbose);
+  bool tarCreatedSuccessfully = true;
   for (auto path : files) {
     if (cmSystemTools::FileIsFullPath(path)) {
       // Get the relative path to the file.
       path = cmSystemTools::RelativePath(cwd, path);
     }
     if (!a.Add(path)) {
-      break;
+      cmSystemTools::Error(a.GetError());
+      tarCreatedSuccessfully = false;
     }
   }
-  if (!a) {
-    cmSystemTools::Error(a.GetError());
-    return false;
-  }
-  return true;
+  return tarCreatedSuccessfully;
 #else
   (void)outFileName;
   (void)files;

+ 4 - 0
Source/cmcmd.cxx

@@ -1114,6 +1114,10 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
           return 1;
         }
       } else if (flags.find_first_of('c') != std::string::npos) {
+        if (files.empty()) {
+          cmSystemTools::Message("tar: No files or directories specified",
+                                 "Warning");
+        }
         if (!cmSystemTools::CreateTar(outFile.c_str(), files, compress,
                                       verbose, mtime, format)) {
           cmSystemTools::Error("Problem creating tar: " + outFile);

+ 6 - 4
Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake

@@ -4,6 +4,7 @@ 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)
@@ -11,12 +12,13 @@ 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")
-external_command_test(bad-format tar cvf bad.tar "--format=bad-format")
-external_command_test(zip-bz2    tar cvjf bad.tar "--format=zip")
-external_command_test(7zip-gz    tar cvzf bad.tar "--format=7zip")
+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-file-result.txt

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

+ 2 - 0
Tests/RunCMake/CommandLineTar/bad-file-stderr.txt

@@ -0,0 +1,2 @@
+^CMake Error: Unable to read from file 'badfile.txt': .*
+CMake Error: Problem creating tar: bad.tar$

+ 1 - 1
Tests/RunCMake/CommandLineTar/bad-from4-stderr.txt

@@ -1,2 +1,2 @@
-^CMake Error: archive_read_disk_entry_from_file 'does-not-exist':.*
+^CMake Error: Unable to read from file 'does-not-exist':.*
 CMake Error: Problem creating tar: bad.tar$

+ 1 - 1
Tests/RunCMake/CommandLineTar/bad-from5-stderr.txt

@@ -1,2 +1,2 @@
-^CMake Error: archive_read_disk_entry_from_file 'does-not-exist':.*
+^CMake Error: Unable to read from file 'does-not-exist':.*
 CMake Error: Problem creating tar: bad.tar$

+ 1 - 1
Tests/RunCMake/CommandLineTar/end-opt1-stderr.txt

@@ -1,2 +1,2 @@
-^CMake Error: archive_read_disk_entry_from_file '--bad':.*
+^CMake Error: Unable to read from file '--bad':.*
 CMake Error: Problem creating tar: bad.tar$

+ 1 - 0
Tests/RunCMake/CommandLineTar/end-opt2-stderr.txt

@@ -0,0 +1 @@
+^tar: No files or directories specified

+ 0 - 0
Tests/RunCMake/CommandLineTar/test-file.txt


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

@@ -0,0 +1 @@
+^tar: No files or directories specified