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(