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
This commit is contained in:
parent
f692cba34b
commit
0b7fd783f8
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
6
Help/release/dev/cmake-E-tar-touch.rst
Normal file
6
Help/release/dev/cmake-E-tar-touch.rst
Normal file
@ -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.
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
13
Tests/RunCMake/CommandLineTar/touch-mtime.cmake
Normal file
13
Tests/RunCMake/CommandLineTar/touch-mtime.cmake
Normal file
@ -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()
|
Loading…
Reference in New Issue
Block a user