Skip to content

Commit a49d77f

Browse files
authored
Batch 8: Blacklist + FileTree + resource management (#376)
- Add Cancel() to GeneralUpdateBootstrap with CancellationTokenSource - Wire CancellationToken through LaunchWithStrategy with finally cleanup - Create FileTreeEnumerator: recursive file enumeration with blacklist filtering via IBlackListMatcher Closes #375
1 parent 023e27a commit a49d77f

2 files changed

Lines changed: 70 additions & 0 deletions

File tree

src/c#/GeneralUpdate.Core/Bootstrap/GeneralUpdateBootstrap.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.IO;
55
using System.Linq;
66
using System.Runtime.InteropServices;
7+
using System.Threading;
78
using System.Text;
89
using System.Text.Json;
910
using System.Threading.Tasks;
@@ -37,12 +38,20 @@ public class GeneralUpdateBootstrap : AbstractBootstrap<GeneralUpdateBootstrap,
3738
private Func<bool>? _customSkipOption;
3839
private Func<UpdateInfoEventArgs, bool>? _updatePrecheck;
3940
private readonly List<Func<bool>> _customOptions = new();
41+
private CancellationTokenSource? _cts;
4042

4143
public GeneralUpdateBootstrap()
4244
{
4345
InitializeFromEnvironment();
4446
}
4547

48+
/// <summary>Cancel the current update operation.</summary>
49+
public void Cancel()
50+
{
51+
_cts?.Cancel();
52+
GeneralTracer.Info("GeneralUpdateBootstrap: cancellation requested.");
53+
}
54+
4655
// ════════════════════════════════════════════════════════════════
4756
// Launch — AppType dispatch via role strategies
4857
// ════════════════════════════════════════════════════════════════
@@ -69,8 +78,11 @@ public override async Task<GeneralUpdateBootstrap> LaunchAsync()
6978

7079
private async Task<GeneralUpdateBootstrap> LaunchWithStrategy(IStrategy roleStrategy)
7180
{
81+
_cts = new CancellationTokenSource();
82+
var token = _cts.Token;
7283
try
7384
{
85+
token.ThrowIfCancellationRequested();
7486
ApplyRuntimeOptions();
7587

7688
// Resolve hooks and reporter from extensions
@@ -107,6 +119,11 @@ private async Task<GeneralUpdateBootstrap> LaunchWithStrategy(IStrategy roleStra
107119
GeneralTracer.Error("LaunchWithStrategy failed.", ex);
108120
EventManager.Instance.Dispatch(this, new ExceptionEventArgs(ex, ex.Message));
109121
}
122+
finally
123+
{
124+
_cts?.Dispose();
125+
_cts = null;
126+
}
110127
return this;
111128
}
112129

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using GeneralUpdate.Core.Configuration;
5+
6+
namespace GeneralUpdate.Core.FileSystem;
7+
8+
/// <summary>
9+
/// Recursively enumerates files in a directory,
10+
/// applying blacklist filtering via IBlackListMatcher.
11+
/// </summary>
12+
public class FileTreeEnumerator
13+
{
14+
private readonly IBlackListMatcher _matcher;
15+
16+
public FileTreeEnumerator(IBlackListMatcher matcher)
17+
{
18+
_matcher = matcher ?? throw new ArgumentNullException(nameof(matcher));
19+
}
20+
21+
/// <summary>
22+
/// Enumerate all files under <paramref name="rootPath"/>,
23+
/// skipping blacklisted files and directories.
24+
/// </summary>
25+
public IEnumerable<string> EnumerateFiles(string rootPath)
26+
{
27+
if (!Directory.Exists(rootPath))
28+
yield break;
29+
30+
foreach (var filePath in Directory.EnumerateFiles(rootPath))
31+
{
32+
var relativePath = Path.GetFileName(filePath);
33+
if (!_matcher.IsBlacklisted(relativePath))
34+
yield return filePath;
35+
}
36+
37+
foreach (var dirPath in Directory.EnumerateDirectories(rootPath))
38+
{
39+
var dirName = Path.GetFileName(dirPath);
40+
if (_matcher.ShouldSkipDirectory(dirName))
41+
continue;
42+
43+
foreach (var file in EnumerateFiles(dirPath))
44+
yield return file;
45+
}
46+
}
47+
48+
/// <summary>
49+
/// Create an enumerator from a BlackListConfig.
50+
/// </summary>
51+
public static FileTreeEnumerator FromConfig(BlackListConfig config)
52+
=> new(new DefaultBlackListMatcher(config));
53+
}

0 commit comments

Comments
 (0)