Skip to content
Prev Previous commit
Next Next commit
Set modified timestamps on files being extracted from tar archives (#…
  • Loading branch information
danmoseley authored and carlossanlop committed Aug 23, 2022
commit 65484f361af3fb8467e8445b1363c7b86a3b168b
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ private void ExtractAsRegularFile(string destinationFileName)
DataStream?.CopyTo(fs);
}

ArchivingUtils.AttemptSetLastWriteTime(destinationFileName, ModificationTime);
AttemptSetLastWriteTime(destinationFileName, ModificationTime);
}

// Asynchronously extracts the current entry as a regular file into the specified destination.
Expand All @@ -551,7 +551,19 @@ private async Task ExtractAsRegularFileAsync(string destinationFileName, Cancell
}
}

ArchivingUtils.AttemptSetLastWriteTime(destinationFileName, ModificationTime);
AttemptSetLastWriteTime(destinationFileName, ModificationTime);
}

private static void AttemptSetLastWriteTime(string destinationFileName, DateTimeOffset lastWriteTime)
{
try
{
File.SetLastWriteTime(destinationFileName, lastWriteTime.LocalDateTime); // SetLastWriteTime expects local time
}
catch
{
// Some OSes like Android might not support setting the last write time, the extraction should not fail because of that
}
}

private FileStreamOptions CreateFileStreamOptions(bool isAsync)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ public void IncludeAllSegmentsOfPath(bool includeBaseDirectory)
Assert.Null(reader.GetNextEntry());
}

[Fact]
[ConditionalFact(typeof(MountHelper), nameof(MountHelper.CanCreateSymbolicLinks))]
public void SkipRecursionIntoDirectorySymlinks()
{
using TempDirectory root = new TempDirectory();
Expand Down Expand Up @@ -225,7 +225,7 @@ public void SkipRecursionIntoDirectorySymlinks()
Assert.Null(reader.GetNextEntry()); // file.txt should not be found
}

[Fact]
[ConditionalFact(typeof(MountHelper), nameof(MountHelper.CanCreateSymbolicLinks))]
public void SkipRecursionIntoBaseDirectorySymlink()
{
using TempDirectory root = new TempDirectory();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ public async Task IncludeAllSegmentsOfPath_Async(bool includeBaseDirectory)
}
}

[Fact]
[ConditionalFact(typeof(MountHelper), nameof(MountHelper.CanCreateSymbolicLinks))]
public async Task SkipRecursionIntoDirectorySymlinksAsync()
{
using TempDirectory root = new TempDirectory();
Expand Down Expand Up @@ -269,7 +269,7 @@ public async Task SkipRecursionIntoDirectorySymlinksAsync()
Assert.Null(await reader.GetNextEntryAsync()); // file.txt should not be found
}

[Fact]
[ConditionalFact(typeof(MountHelper), nameof(MountHelper.CanCreateSymbolicLinks))]
public async Task SkipRecursionIntoBaseDirectorySymlinkAsync()
{
using TempDirectory root = new TempDirectory();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,33 @@ public void NonExistentDirectory_Throws()
Assert.Throws<DirectoryNotFoundException>(() => TarFile.ExtractToDirectory(sourceFileName: filePath, destinationDirectoryName: dirPath, overwriteFiles: false));
}

[Fact]
public void SetsLastModifiedTimeOnExtractedFiles()
{
using TempDirectory root = new TempDirectory();

string inDir = Path.Join(root.Path, "indir");
string inFile = Path.Join(inDir, "file");

string tarFile = Path.Join(root.Path, "file.tar");

string outDir = Path.Join(root.Path, "outdir");
string outFile = Path.Join(outDir, "file");

Directory.CreateDirectory(inDir);
File.Create(inFile).Dispose();
var dt = new DateTime(2001, 1, 2, 3, 4, 5, DateTimeKind.Local);
File.SetLastWriteTime(inFile, dt);

TarFile.CreateFromDirectory(sourceDirectoryName: inDir, destinationFileName: tarFile, includeBaseDirectory: false);

Directory.CreateDirectory(outDir);
TarFile.ExtractToDirectory(sourceFileName: tarFile, destinationDirectoryName: outDir, overwriteFiles: false);

Assert.True(File.Exists(outFile));
Assert.InRange(File.GetLastWriteTime(outFile).Ticks, dt.AddSeconds(-3).Ticks, dt.AddSeconds(3).Ticks); // include some slop for filesystem granularity
}

[Theory]
[InlineData(TestTarFormat.v7)]
[InlineData(TestTarFormat.ustar)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,33 @@ public async Task NonExistentDirectory_Throws_Async()
}
}

[Fact]
public async Task SetsLastModifiedTimeOnExtractedFiles()
{
using TempDirectory root = new TempDirectory();

string inDir = Path.Join(root.Path, "indir");
string inFile = Path.Join(inDir, "file");

string tarFile = Path.Join(root.Path, "file.tar");

string outDir = Path.Join(root.Path, "outdir");
string outFile = Path.Join(outDir, "file");

Directory.CreateDirectory(inDir);
File.Create(inFile).Dispose();
var dt = new DateTime(2001, 1, 2, 3, 4, 5, DateTimeKind.Local);
File.SetLastWriteTime(inFile, dt);

await TarFile.CreateFromDirectoryAsync(sourceDirectoryName: inDir, destinationFileName: tarFile, includeBaseDirectory: false);

Directory.CreateDirectory(outDir);
await TarFile.ExtractToDirectoryAsync(sourceFileName: tarFile, destinationDirectoryName: outDir, overwriteFiles: false);

Assert.True(File.Exists(outFile));
Assert.InRange(File.GetLastWriteTime(outFile).Ticks, dt.AddSeconds(-3).Ticks, dt.AddSeconds(3).Ticks); // include some slop for filesystem granularity
}

[Theory]
[InlineData(TestTarFormat.v7)]
[InlineData(TestTarFormat.ustar)]
Expand Down