Skip to content

Commit e31f9be

Browse files
committed
Add ability to remove entry from the bundle
1 parent a404de7 commit e31f9be

File tree

2 files changed

+71
-11
lines changed

2 files changed

+71
-11
lines changed

src/EasySign/Bundle.cs

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@ public class Bundle
2727
private readonly string _bundleName;
2828
private byte[] _rawZipContents = [];
2929

30-
private readonly Dictionary<string, X509Certificate2> _certCache = new();
31-
private readonly ConcurrentDictionary<string, byte[]> _newEmbeddedFiles = new();
30+
private readonly ConcurrentDictionary<string, X509Certificate2> _certCache = new();
3231
private readonly ConcurrentDictionary<string, byte[]> _fileCache = new();
3332

33+
private readonly ConcurrentDictionary<string, byte[]> _pendingForAdd = new();
34+
private readonly List<string> _pendingForRemove = new();
35+
3436
/// <summary>
3537
/// Gets the JSON serializer options.
3638
/// </summary>
@@ -281,8 +283,35 @@ public void AddEntry(string path, string destinationPath = "./", string? rootPat
281283

282284
if (Manifest.StoreOriginalFiles)
283285
{
284-
Logger.LogDebug("Embedding file: {name} in the bundle", name);
285-
_newEmbeddedFiles[name] = File.ReadAllBytes(path);
286+
Logger.LogDebug("Pending file: {name} for embedding in the bundle", name);
287+
_pendingForAdd[name] = File.ReadAllBytes(path);
288+
}
289+
}
290+
291+
/// <summary>
292+
/// Deletes an entry from the bundle.
293+
/// </summary>
294+
/// <param name="entryName">The name of the entry to delete.</param>
295+
public void DeleteEntry(string entryName)
296+
{
297+
EnsureWritable();
298+
299+
Ensure.String.IsNotNullOrEmpty(entryName.Trim(), nameof(entryName));
300+
301+
Logger.LogInformation("Deleting entry: {name}", entryName);
302+
303+
Manifest.DeleteEntry(entryName);
304+
305+
if (Manifest.StoreOriginalFiles)
306+
{
307+
Logger.LogDebug("Pending entry: {name} for deletion from the bundle", entryName);
308+
_pendingForRemove.Add(entryName);
309+
310+
if (_pendingForAdd.ContainsKey(entryName))
311+
{
312+
Logger.LogDebug("Removing pending entry: {name} from the bundle", entryName);
313+
_pendingForAdd.Remove(entryName, out _);
314+
}
286315
}
287316
}
288317

@@ -314,8 +343,8 @@ public void Sign(X509Certificate2 certificate, RSA privateKey)
314343
var manifestData = Export(Manifest, SourceGenerationManifestContext.Default);
315344
var signature = privateKey.SignData(manifestData, HashAlgorithmName.SHA512, RSASignaturePadding.Pkcs1);
316345

317-
Logger.LogDebug("Embedding file: {name} in the bundle", name);
318-
_newEmbeddedFiles[name] = Encoding.UTF8.GetBytes(pemContents);
346+
Logger.LogDebug("Pending file: {name} for embedding in the bundle", name);
347+
_pendingForAdd[name] = Encoding.UTF8.GetBytes(pemContents);
319348

320349
Logger.LogDebug("Adding signature for certificate: {name} to signatures", name);
321350
Signatures.Entries[name] = signature;
@@ -590,6 +619,22 @@ public void Update()
590619

591620
using (ZipArchive zip = OpenZipArchive(ZipArchiveMode.Update))
592621
{
622+
Logger.LogDebug("Deleting pending files from the bundle");
623+
624+
ZipArchiveEntry? tempEntry;
625+
foreach (var entryName in _pendingForRemove)
626+
{
627+
if ((tempEntry = zip.GetEntry(entryName)) != null)
628+
{
629+
Logger.LogDebug("Deleting entry: {name}", entryName);
630+
tempEntry.Delete();
631+
}
632+
else
633+
{
634+
Logger.LogWarning("Entry {name} not found in the bundle", entryName);
635+
}
636+
}
637+
593638
Logger.LogDebug("Raising OnUpdating event");
594639
OnUpdating?.Invoke(zip);
595640

@@ -601,8 +646,8 @@ public void Update()
601646
var signatureData = Export(Signatures, SourceGenerationSignaturesContext.Default);
602647
WriteEntry(zip, ".signatures.ec", signatureData);
603648

604-
Logger.LogDebug("Writing new files to the bundle");
605-
foreach (var newFile in _newEmbeddedFiles)
649+
Logger.LogDebug("Writing pending files to the bundle");
650+
foreach (var newFile in _pendingForAdd)
606651
{
607652
WriteEntry(zip, newFile.Key, newFile.Value);
608653
}

src/EasySign/Manifest.cs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Concurrent;
33
using System.Collections.Generic;
4+
using System.Data;
45
using System.Linq;
56
using System.Text;
67
using System.Text.Json.Serialization;
@@ -47,20 +48,34 @@ public SortedDictionary<string, byte[]> Entries
4748

4849
/// <summary>
4950
/// Adds an entry to the manifest.
50-
/// if it already exists, an exception will be thrown.
51+
/// An exception will be thrown if the entry already exists.
5152
/// </summary>
5253
/// <param name="entryName">
5354
/// The name of the entry to add.
5455
/// </param>
5556
/// <param name="hash">
5657
/// The hash of the entry to add.
5758
/// </param>
58-
/// <exception cref="InvalidOperationException"></exception>
59+
/// <exception cref="DuplicateNameException"></exception>
5960
public void AddEntry(string entryName, byte[] hash)
6061
{
6162
if (!entries.TryAdd(entryName, hash))
6263
{
63-
throw new InvalidOperationException($"The entry '{entryName}' is already in the manifest.");
64+
throw new DuplicateNameException($"The entry '{entryName}' is already in the manifest.");
65+
}
66+
}
67+
68+
/// <summary>
69+
/// Deletes an entry from the manifest.
70+
/// An exception will be thrown if the entry does not exist.
71+
/// </summary>
72+
/// <param name="entryName">The name of the entry to delete. </param>
73+
/// <exception cref="KeyNotFoundException"></exception>
74+
public void DeleteEntry(string entryName)
75+
{
76+
if (!entries.Remove(entryName, out _))
77+
{
78+
throw new KeyNotFoundException(entryName);
6479
}
6580
}
6681

0 commit comments

Comments
 (0)