Files
MoShiro/ci/Monitor.Tar/Program.cs
T

39 lines
1.6 KiB
C#

using System.Formats.Tar;
using System.IO.Compression;
if (args.Length < 3)
{
Console.Error.WriteLine("usage: Monitor.Tar <source-directory> <archive-path> <executable-relative-path>...");
return 2;
}
string sourceDirectory = Path.GetFullPath(args[0]);
string archivePath = Path.GetFullPath(args[1]);
HashSet<string> executables = args.Skip(2).Select(path => path.Replace('\\', '/')).ToHashSet(StringComparer.Ordinal);
UnixFileMode executableMode = UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute |
UnixFileMode.GroupRead | UnixFileMode.GroupExecute |
UnixFileMode.OtherRead | UnixFileMode.OtherExecute;
UnixFileMode regularMode = UnixFileMode.UserRead | UnixFileMode.UserWrite |
UnixFileMode.GroupRead | UnixFileMode.OtherRead;
Directory.CreateDirectory(Path.GetDirectoryName(archivePath)!);
using FileStream fileStream = File.Create(archivePath);
using GZipStream gzipStream = new(fileStream, CompressionLevel.Optimal, leaveOpen: true);
using TarWriter writer = new(gzipStream, TarEntryFormat.Pax, leaveOpen: true);
foreach (string filePath in Directory.EnumerateFiles(sourceDirectory, "*", SearchOption.AllDirectories))
{
string relativePath = Path.GetRelativePath(sourceDirectory, filePath).Replace('\\', '/');
PaxTarEntry entry = new(TarEntryType.RegularFile, relativePath)
{
Mode = executables.Contains(relativePath) ? executableMode : regularMode,
DataStream = File.OpenRead(filePath)
};
using (entry.DataStream)
{
writer.WriteEntry(entry);
}
}
return 0;