CSharp · Console
using System;
using System.IO;
using System.Linq;
using NUnit.Framework.Internal;
using ICSharpCode.SharpZipLib.Tar;
TarEntry symlinkEntry = new TarEntry(new TarHeader()
{
Name = "MySymlink",
Mode = Convert.ToInt32("774", 8),
TypeFlag = TarHeader.LF_SYMLINK,
ModTime = DateTime.UtcNow,
Size = 0,
LinkName = "MyFile",
});
Test(SymlinkWithArchiveClass, symlinkEntry);
Test(SymlinkWithStreamClass, symlinkEntry);
// BAD:
// WriteEntry() wants to append file data, which we
// don't have with symlinks. For directories (LF_DIR),
// there is an exemption. I expected one for LF_SYMLINK too.
void SymlinkWithArchiveClass(TarEntry entry) {
using (var ms = new MemoryStream())
{
var ar = TarArchive.CreateOutputTarArchive(ms);
ar.WriteEntry(entry, false);
ar.Close();
}
}
// GOOD:
void SymlinkWithStreamClass(TarEntry entry) {
using var ms = new MemoryStream();
using (var ts = new TarOutputStream(ms, System.Text.Encoding.UTF8))
{
ts.PutNextEntry(entry);
ts.CloseEntry();
ts.Close();
}
}
#region Helpers // These are just a helpers to make the results more legible
void Test<T>(Action<T> a, T input)
{
// Prevent NUnit from grouping exceptions together
using var ctx = new TestExecutionContext.IsolatedContext();
Console.WriteLine($"Testing input \"{input}\"...\n");
try {
a(input);
Console.WriteLine("\n=> OK!");
}
catch (Exception x) {
Console.WriteLine($"\n=> Failed! ({x.GetType().Name})");
Console.WriteLine($"\n{x.Message}");
var trimmedStack = string.Join("\n", x.StackTrace.Split("\n").Where(l => !l.Contains("ReportFailure")));
Console.WriteLine($"{trimmedStack}");
}
Console.WriteLine($"\n{new string('=', 128)}\n");
}
void Log(string message) => Console.WriteLine($" {message}");
#endregion