From 629fc5b49f50c279b25831b97e88ebfd860c6e4e Mon Sep 17 00:00:00 2001 From: webbrain-one <295484252+webbrain-one@users.noreply.github.com> Date: Tue, 4 Aug 2026 14:09:19 +0300 Subject: [PATCH] Allow compression without TAR archiving Add support for standalone GZIP and Bzip2 compression without creating a TAR archive. This allows direct compression of files, addressing use cases like Docker images which are already archived. Fixes #14 --- src/Cake.Compression/Classes/Bzip2.cs | 4 +- .../Classes/CompressionBase.cs | 4 +- src/Cake.Compression/Classes/GZip.cs | 65 +++++++++++++------ src/Cake.Compression/CompressionAliases.cs | 60 ++++++++++------- 4 files changed, 86 insertions(+), 47 deletions(-) diff --git a/src/Cake.Compression/Classes/Bzip2.cs b/src/Cake.Compression/Classes/Bzip2.cs index 2fb4ffe..616e702 100644 --- a/src/Cake.Compression/Classes/Bzip2.cs +++ b/src/Cake.Compression/Classes/Bzip2.cs @@ -30,11 +30,13 @@ public BZip2( /// The output path. /// The file paths. /// The compression level (1-9). + /// Whether to wrap files in a TAR archive before compressing. public override void Compress( DirectoryPath rootPath, FilePath outputPath, IEnumerable filePaths, - int level) + int level, + bool useTar = true) { ArgumentNullException.ThrowIfNull(rootPath, nameof(rootPath)); ArgumentNullException.ThrowIfNull(outputPath, nameof(outputPath)); diff --git a/src/Cake.Compression/Classes/CompressionBase.cs b/src/Cake.Compression/Classes/CompressionBase.cs index 8545ba7..49d11fb 100644 --- a/src/Cake.Compression/Classes/CompressionBase.cs +++ b/src/Cake.Compression/Classes/CompressionBase.cs @@ -59,11 +59,13 @@ protected CompressionBase( /// The output path. /// The file paths. /// The compression level (1-9). + /// Whether to wrap files in a TAR archive before compressing. public abstract void Compress( DirectoryPath rootPath, FilePath outputPath, IEnumerable filePaths, - int level); + int level, + bool useTar = true); /// /// Decompress the specified archive. diff --git a/src/Cake.Compression/Classes/GZip.cs b/src/Cake.Compression/Classes/GZip.cs index 1167ea6..e08b038 100644 --- a/src/Cake.Compression/Classes/GZip.cs +++ b/src/Cake.Compression/Classes/GZip.cs @@ -1,6 +1,7 @@ using Cake.Core; using Cake.Core.Diagnostics; using Cake.Core.IO; +using System.Linq; using ICSharpCode.SharpZipLib.GZip; using ICSharpCode.SharpZipLib.Tar; using System.Text; @@ -30,11 +31,13 @@ public GZip( /// The output path. /// The file paths. /// The compression level (1-9). + /// Whether to wrap files in a TAR archive before compressing. public override void Compress( DirectoryPath rootPath, FilePath outputPath, IEnumerable filePaths, - int level) + int level, + bool useTar = true) { ArgumentNullException.ThrowIfNull(rootPath, nameof(rootPath)); ArgumentNullException.ThrowIfNull(outputPath, nameof(outputPath)); @@ -50,32 +53,52 @@ public override void Compress( var outputFile = FileSystem.GetFile(outputPath); // Open up a stream to the output file. - Log.Verbose("Creating Zip file: {0}", outputPath.FullPath); + Log.Verbose("Creating GZip file: {0}", outputPath.FullPath); using (var outputStream = outputFile.Open(FileMode.Create, FileAccess.Write, FileShare.None)) - using (var gzipOutputStream = new GZipOutputStream(outputStream)) - using (var tarOutputStream = new TarOutputStream(gzipOutputStream, Encoding.UTF8)) { - gzipOutputStream.SetLevel(level); - - foreach (var inputPath in filePaths) + if (useTar) { - var absoluteInputPath = inputPath.MakeAbsolute(Environment); - var file = FileSystem.GetFile(absoluteInputPath); - - using (var inputStream = file.Open(FileMode.Open, FileAccess.Read, FileShare.Read)) + using (var gzipOutputStream = new GZipOutputStream(outputStream)) + using (var tarOutputStream = new TarOutputStream(gzipOutputStream, Encoding.UTF8)) + { + gzipOutputStream.SetLevel(level); + + foreach (var inputPath in filePaths) + { + var absoluteInputPath = inputPath.MakeAbsolute(Environment); + var file = FileSystem.GetFile(absoluteInputPath); + + using (var inputStream = file.Open(FileMode.Open, FileAccess.Read, FileShare.Read)) + { + // Get the relative filename to the rootPath. + var relativeFilePath = GetRelativeFilePath(rootPath, absoluteInputPath); + Log.Verbose("Compressing file {0}", absoluteInputPath); + + // Create the tar archive entry. + var entry = TarEntry.CreateTarEntry(relativeFilePath.FullPath); + entry.Size = inputStream.Length; + + tarOutputStream.PutNextEntry(entry); + inputStream.CopyTo(tarOutputStream); + tarOutputStream.CloseEntry(); + } + } + } + } + else + { + using (var gzipOutputStream = new GZipOutputStream(outputStream)) { - // Get the relative filename to the rootPath. - var relativeFilePath = GetRelativeFilePath(rootPath, absoluteInputPath); + gzipOutputStream.SetLevel(level); + var inputPath = filePaths.First(); + var absoluteInputPath = inputPath.MakeAbsolute(Environment); + var file = FileSystem.GetFile(absoluteInputPath); Log.Verbose("Compressing file {0}", absoluteInputPath); - - // Create the tar archive entry. - var entry = TarEntry.CreateTarEntry(relativeFilePath.FullPath); - entry.Size = inputStream.Length; - - tarOutputStream.PutNextEntry(entry); - inputStream.CopyTo(tarOutputStream); - tarOutputStream.CloseEntry(); + using (var inputStream = file.Open(FileMode.Open, FileAccess.Read, FileShare.Read)) + { + inputStream.CopyTo(gzipOutputStream); + } } } } diff --git a/src/Cake.Compression/CompressionAliases.cs b/src/Cake.Compression/CompressionAliases.cs index 6683fcf..ed8f4ec 100644 --- a/src/Cake.Compression/CompressionAliases.cs +++ b/src/Cake.Compression/CompressionAliases.cs @@ -245,8 +245,9 @@ public static void BZip2Uncompress( public static void GZipCompress( this ICakeContext context, DirectoryPath rootPath, - FilePath outputPath) => - Compress(context, rootPath, outputPath, Level); + FilePath outputPath, + bool useTar = true) => + Compress(context, rootPath, outputPath, Level, useTar); /// /// Create a GZip Tar archive of the specified directory. @@ -265,8 +266,9 @@ public static void GZipCompress( this ICakeContext context, DirectoryPath rootPath, FilePath outputPath, - int level) => - Compress(context, rootPath, outputPath, level); + int level, + bool useTar = true) => + Compress(context, rootPath, outputPath, level, useTar); /// /// Create a GZip Tar archive of the files matching the specified pattern. @@ -285,8 +287,9 @@ public static void GZipCompress( this ICakeContext context, DirectoryPath rootPath, FilePath outputPath, - string pattern) => - Compress(context, rootPath, outputPath, pattern, Level); + string pattern, + bool useTar = true) => + Compress(context, rootPath, outputPath, pattern, Level, useTar); /// /// Create a GZip Tar archive of the files matching the specified pattern. @@ -307,8 +310,9 @@ public static void GZipCompress( DirectoryPath rootPath, FilePath outputPath, string pattern, - int level) => - Compress(context, rootPath, outputPath, pattern, level); + int level, + bool useTar = true) => + Compress(context, rootPath, outputPath, pattern, level, useTar); /// /// Create a GZip Tar archive of the specified files. @@ -328,8 +332,9 @@ public static void GZipCompress( this ICakeContext context, DirectoryPath rootPath, FilePath outputPath, - IEnumerable filePaths) => - Compress(context, rootPath, outputPath, filePaths, Level); + IEnumerable filePaths, + bool useTar = true) => + Compress(context, rootPath, outputPath, filePaths, Level, useTar); /// /// Create a GZip Tar archive of the specified files. @@ -351,8 +356,9 @@ public static void GZipCompress( DirectoryPath rootPath, FilePath outputPath, IEnumerable filePaths, - int level) => - Compress(context, rootPath, outputPath, filePaths, level); + int level, + bool useTar = true) => + Compress(context, rootPath, outputPath, filePaths, level, useTar); /// /// Create a GZip Tar archive of the specified files. @@ -377,8 +383,9 @@ public static void GZipCompress( this ICakeContext context, DirectoryPath rootPath, FilePath outputPath, - IEnumerable filePaths) => - Compress(context, rootPath, outputPath, filePaths, Level); + IEnumerable filePaths, + bool useTar = true) => + Compress(context, rootPath, outputPath, filePaths, Level, useTar); /// /// Create a GZip Tar archive of the specified files. @@ -405,8 +412,9 @@ public static void GZipCompress( DirectoryPath rootPath, FilePath outputPath, IEnumerable filePaths, - int level) => - Compress(context, rootPath, outputPath, filePaths, level); + int level, + bool useTar = true) => + Compress(context, rootPath, outputPath, filePaths, level, useTar); /// /// Decompress the specified GZip Tar file. @@ -667,7 +675,8 @@ private static void Compress( ICakeContext context, DirectoryPath rootPath, FilePath outputPath, - int level) where T : CompressionBase + int level, + bool useTar = true) where T : CompressionBase { ArgumentNullException.ThrowIfNull(context, nameof(context)); ArgumentNullException.ThrowIfNull(rootPath, nameof(rootPath)); @@ -676,7 +685,7 @@ private static void Compress( ArgumentOutOfRangeException.ThrowIfGreaterThan(level, 9, nameof(level)); var filePaths = context.GetFiles(string.Concat(rootPath, "/**/*")); - Compress(context, rootPath, outputPath, filePaths, level); + Compress(context, rootPath, outputPath, filePaths, level, useTar); } private static void Compress( @@ -684,7 +693,8 @@ private static void Compress( DirectoryPath rootPath, FilePath outputPath, string pattern, - int level) where T : CompressionBase + int level, + bool useTar = true) where T : CompressionBase { ArgumentNullException.ThrowIfNull(context, nameof(context)); ArgumentNullException.ThrowIfNull(rootPath, nameof(rootPath)); @@ -701,7 +711,7 @@ private static void Compress( return; } - Compress(context, rootPath, outputPath, filePaths, level); + Compress(context, rootPath, outputPath, filePaths, level, useTar); } private static void Compress( @@ -709,7 +719,8 @@ private static void Compress( DirectoryPath rootPath, FilePath outputPath, IEnumerable filePaths, - int level) where T : CompressionBase + int level, + bool useTar = true) where T : CompressionBase { ArgumentNullException.ThrowIfNull(context, nameof(context)); ArgumentNullException.ThrowIfNull(rootPath, nameof(rootPath)); @@ -719,7 +730,7 @@ private static void Compress( ArgumentOutOfRangeException.ThrowIfGreaterThan(level, 9, nameof(level)); var zip = CreateInstance(context.FileSystem, context.Environment, context.Log); - zip.Compress(rootPath, outputPath, filePaths, level); + zip.Compress(rootPath, outputPath, filePaths, level, useTar); } private static void Compress( @@ -727,7 +738,8 @@ private static void Compress( DirectoryPath rootPath, FilePath outputPath, IEnumerable filePaths, - int level) where T : CompressionBase + int level, + bool useTar = true) where T : CompressionBase { ArgumentNullException.ThrowIfNull(context, nameof(context)); ArgumentNullException.ThrowIfNull(rootPath, nameof(rootPath)); @@ -737,7 +749,7 @@ private static void Compress( ArgumentOutOfRangeException.ThrowIfGreaterThan(level, 9, nameof(level)); var paths = filePaths.Select(path => new FilePath(path)).ToList(); - Compress(context, rootPath, outputPath, paths, level); + Compress(context, rootPath, outputPath, paths, level, useTar); } private static void Decompress(