summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKasper Laudrup <you@example.com>2022-03-15 18:27:54 (GMT)
committerKasper Laudrup <you@example.com>2022-03-23 13:41:34 (GMT)
commit0b7fd783f82639ba129e62edeac0de6594542708 (patch)
tree6958f1bb75909c6fa703927b16d184d15a5de9b5
parentf692cba34b758f5c308c3fd659c438ce022a0a80 (diff)
downloadCMake-0b7fd783f82639ba129e62edeac0de6594542708.zip
CMake-0b7fd783f82639ba129e62edeac0de6594542708.tar.gz
CMake-0b7fd783f82639ba129e62edeac0de6594542708.tar.bz2
cmake -E tar: Add --touch option
Similar to GNU tar add a --touch option to the tar extract command to skip extracting the timestamps from the files in the archive effectively touching them as if they were just created. Issue: #22746
-rw-r--r--Help/command/file.rst7
-rw-r--r--Help/manual/cmake.1.rst6
-rw-r--r--Help/release/dev/cmake-E-tar-touch.rst6
-rw-r--r--Source/cmFileCommand.cxx11
-rw-r--r--Source/cmSystemTools.cxx18
-rw-r--r--Source/cmSystemTools.h10
-rw-r--r--Source/cmcmd.cxx7
-rw-r--r--Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/CommandLineTar/touch-mtime.cmake13
9 files changed, 69 insertions, 12 deletions
diff --git a/Help/command/file.rst b/Help/command/file.rst
index 2769577..3374d2d 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -1227,7 +1227,8 @@ the ``MTIME`` option.
[DESTINATION <dir>]
[PATTERNS <patterns>...]
[LIST_ONLY]
- [VERBOSE])
+ [VERBOSE]
+ [TOUCH])
.. versionadded:: 3.18
@@ -1245,4 +1246,8 @@ extracted.
``LIST_ONLY`` will list the files in the archive rather than extract them.
+.. versionadded:: 3.24
+ The ``TOUCH`` option gives extracted files a current local
+ timestamp instead of extracting file timestamps from the archive.
+
With ``VERBOSE``, the command will produce verbose output.
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index e93cbe5..3febc9e 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -948,6 +948,12 @@ Available commands are:
Specify modification time recorded in tarball entries.
+ ``--touch``
+ .. versionadded:: 3.24
+
+ Use current local timestamp instead of extracting file timestamps
+ from the archive.
+
``--``
.. versionadded:: 3.1
diff --git a/Help/release/dev/cmake-E-tar-touch.rst b/Help/release/dev/cmake-E-tar-touch.rst
new file mode 100644
index 0000000..6d1338d
--- /dev/null
+++ b/Help/release/dev/cmake-E-tar-touch.rst
@@ -0,0 +1,6 @@
+cmake-E-tar-touch
+-----------------
+
+* The :manual:`cmake(1)` ``-E tar`` command gained the ``--touch`` option
+ to keep the current local timestamp instead of extracting file timestamps
+ from the archive.
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 09e5015..e4728ac 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -3507,6 +3507,7 @@ bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
bool ListOnly = false;
std::string Destination;
std::vector<std::string> Patterns;
+ bool Touch = false;
};
static auto const parser = cmArgumentParser<Arguments>{}
@@ -3514,7 +3515,8 @@ 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("PATTERNS"_s, &Arguments::Patterns);
+ .Bind("PATTERNS"_s, &Arguments::Patterns)
+ .Bind("TOUCH"_s, &Arguments::Touch);
std::vector<std::string> unrecognizedArguments;
std::vector<std::string> keywordsMissingValues;
@@ -3577,8 +3579,11 @@ bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
return false;
}
- if (!cmSystemTools::ExtractTar(inFile, parsedArgs.Patterns,
- parsedArgs.Verbose)) {
+ if (!cmSystemTools::ExtractTar(
+ inFile, parsedArgs.Patterns,
+ parsedArgs.Touch ? cmSystemTools::cmTarExtractTimestamps::No
+ : cmSystemTools::cmTarExtractTimestamps::Yes,
+ parsedArgs.Verbose)) {
status.SetError(cmStrCat("failed to extract: ", inFile));
cmSystemTools::SetFatalErrorOccured();
return false;
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index a5dfa4c..cb32172 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -1821,6 +1821,7 @@ bool copy_data(struct archive* ar, struct archive* aw)
bool extract_tar(const std::string& outFileName,
const std::vector<std::string>& files, bool verbose,
+ cmSystemTools::cmTarExtractTimestamps extractTimestamps,
bool extract)
{
cmLocaleRAII localeRAII;
@@ -1879,10 +1880,12 @@ bool extract_tar(const std::string& outFileName,
cmSystemTools::Stdout("\n");
}
if (extract) {
- r = archive_write_disk_set_options(ext, ARCHIVE_EXTRACT_TIME);
- if (r != ARCHIVE_OK) {
- ArchiveError("Problem with archive_write_disk_set_options(): ", ext);
- break;
+ if (extractTimestamps == cmSystemTools::cmTarExtractTimestamps::Yes) {
+ r = archive_write_disk_set_options(ext, ARCHIVE_EXTRACT_TIME);
+ if (r != ARCHIVE_OK) {
+ ArchiveError("Problem with archive_write_disk_set_options(): ", ext);
+ break;
+ }
}
r = archive_write_header(ext, entry);
@@ -1942,13 +1945,15 @@ bool extract_tar(const std::string& outFileName,
bool cmSystemTools::ExtractTar(const std::string& outFileName,
const std::vector<std::string>& files,
+ cmTarExtractTimestamps extractTimestamps,
bool verbose)
{
#if !defined(CMAKE_BOOTSTRAP)
- return extract_tar(outFileName, files, verbose, true);
+ return extract_tar(outFileName, files, verbose, extractTimestamps, true);
#else
(void)outFileName;
(void)files;
+ (void)extractTimestamps;
(void)verbose;
return false;
#endif
@@ -1959,7 +1964,8 @@ bool cmSystemTools::ListTar(const std::string& outFileName,
bool verbose)
{
#if !defined(CMAKE_BOOTSTRAP)
- return extract_tar(outFileName, files, verbose, false);
+ return extract_tar(outFileName, files, verbose, cmTarExtractTimestamps::Yes,
+ false);
#else
(void)outFileName;
(void)files;
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 19dabe8..c17ecbd 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -417,6 +417,12 @@ public:
TarCompressNone
};
+ enum class cmTarExtractTimestamps
+ {
+ Yes,
+ No
+ };
+
static bool ListTar(const std::string& outFileName,
const std::vector<std::string>& files, bool verbose);
static bool CreateTar(const std::string& outFileName,
@@ -426,7 +432,9 @@ public:
std::string const& format = std::string(),
int compressionLevel = 0);
static bool ExtractTar(const std::string& inFileName,
- const std::vector<std::string>& files, bool verbose);
+ const std::vector<std::string>& files,
+ cmTarExtractTimestamps extractTimestamps,
+ bool verbose);
// This should be called first thing in main
// it will keep child processes from inheriting the
// stdin and stdout of this process. This is important
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index f1c1bdc..df740c9 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -1368,6 +1368,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
std::vector<std::string> files;
std::string mtime;
std::string format;
+ cmSystemTools::cmTarExtractTimestamps extractTimestamps =
+ cmSystemTools::cmTarExtractTimestamps::Yes;
cmSystemTools::cmTarCompression compress =
cmSystemTools::TarCompressNone;
int nCompress = 0;
@@ -1393,6 +1395,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
format);
return 1;
}
+ } else if (arg == "--touch") {
+ extractTimestamps = cmSystemTools::cmTarExtractTimestamps::No;
} else {
cmSystemTools::Error("Unknown option to -E tar: " + arg);
return 1;
@@ -1464,7 +1468,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
return 1;
}
} else if (action == cmSystemTools::TarActionExtract) {
- if (!cmSystemTools::ExtractTar(outFile, files, verbose)) {
+ if (!cmSystemTools::ExtractTar(outFile, files, extractTimestamps,
+ verbose)) {
cmSystemTools::Error("Problem extracting tar: " + outFile);
return 1;
}
diff --git a/Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake b/Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake
index 079a535..a487f37 100644
--- a/Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake
@@ -37,3 +37,6 @@ run_cmake(zip-filtered)
# Use the --mtime option to set the mtime when creating archive
run_cmake(set-mtime)
+
+# Use the --touch option to avoid extracting the mtime
+run_cmake(touch-mtime)
diff --git a/Tests/RunCMake/CommandLineTar/touch-mtime.cmake b/Tests/RunCMake/CommandLineTar/touch-mtime.cmake
new file mode 100644
index 0000000..c9e3524
--- /dev/null
+++ b/Tests/RunCMake/CommandLineTar/touch-mtime.cmake
@@ -0,0 +1,13 @@
+include(${CMAKE_CURRENT_LIST_DIR}/mtime-tests.cmake)
+
+set(DECOMPRESSION_OPTIONS --touch)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+foreach(file ${CHECK_FILES})
+ file(TIMESTAMP ${FULL_DECOMPRESS_DIR}/${COMPRESS_DIR}/${file} MTIME UTC)
+ if(MTIME STREQUAL ARCHIVE_MTIME_RFC3339)
+ message(FATAL_ERROR
+ "File has unexpected timestamp ${MTIME}")
+ endif()
+endforeach()