Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/c#/GeneralUpdate.Core/Bootstrap/GeneralUpdateBootstrap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
Expand Down Expand Up @@ -37,12 +38,20 @@ public class GeneralUpdateBootstrap : AbstractBootstrap<GeneralUpdateBootstrap,
private Func<bool>? _customSkipOption;
private Func<UpdateInfoEventArgs, bool>? _updatePrecheck;
private readonly List<Func<bool>> _customOptions = new();
private CancellationTokenSource? _cts;

public GeneralUpdateBootstrap()
{
InitializeFromEnvironment();
}

/// <summary>Cancel the current update operation.</summary>
public void Cancel()
{
_cts?.Cancel();
GeneralTracer.Info("GeneralUpdateBootstrap: cancellation requested.");
}

// ════════════════════════════════════════════════════════════════
// Launch — AppType dispatch via role strategies
// ════════════════════════════════════════════════════════════════
Expand All @@ -69,8 +78,11 @@ public override async Task<GeneralUpdateBootstrap> LaunchAsync()

private async Task<GeneralUpdateBootstrap> LaunchWithStrategy(IStrategy roleStrategy)
{
_cts = new CancellationTokenSource();
var token = _cts.Token;
try
{
token.ThrowIfCancellationRequested();
ApplyRuntimeOptions();

// Resolve hooks and reporter from extensions
Expand Down Expand Up @@ -107,6 +119,11 @@ private async Task<GeneralUpdateBootstrap> LaunchWithStrategy(IStrategy roleStra
GeneralTracer.Error("LaunchWithStrategy failed.", ex);
EventManager.Instance.Dispatch(this, new ExceptionEventArgs(ex, ex.Message));
}
finally
{
_cts?.Dispose();
_cts = null;
}
return this;
}

Expand Down
53 changes: 53 additions & 0 deletions src/c#/GeneralUpdate.Core/FileSystem/FileTreeEnumerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.IO;
using GeneralUpdate.Core.Configuration;

namespace GeneralUpdate.Core.FileSystem;

/// <summary>
/// Recursively enumerates files in a directory,
/// applying blacklist filtering via IBlackListMatcher.
/// </summary>
public class FileTreeEnumerator
{
private readonly IBlackListMatcher _matcher;

public FileTreeEnumerator(IBlackListMatcher matcher)
{
_matcher = matcher ?? throw new ArgumentNullException(nameof(matcher));
}

/// <summary>
/// Enumerate all files under <paramref name="rootPath"/>,
/// skipping blacklisted files and directories.
/// </summary>
public IEnumerable<string> EnumerateFiles(string rootPath)
{
if (!Directory.Exists(rootPath))
yield break;

foreach (var filePath in Directory.EnumerateFiles(rootPath))
{
var relativePath = Path.GetFileName(filePath);
if (!_matcher.IsBlacklisted(relativePath))
yield return filePath;
}

foreach (var dirPath in Directory.EnumerateDirectories(rootPath))
{
var dirName = Path.GetFileName(dirPath);
if (_matcher.ShouldSkipDirectory(dirName))
continue;

foreach (var file in EnumerateFiles(dirPath))
yield return file;
}
}

/// <summary>
/// Create an enumerator from a BlackListConfig.
/// </summary>
public static FileTreeEnumerator FromConfig(BlackListConfig config)
=> new(new DefaultBlackListMatcher(config));
}
Loading