Files
ClaudeDo/tests/ClaudeDo.Worker.Tests/Infrastructure/TaskStateServiceBuilder.cs
T
mika kuns d3155e6868 feat(queue): warn when the base branch has uncommitted changes
Queuing (update_task_status, batch_update_task_status) and run_task_now
now surface a non-blocking baseDirty warning (separate modified/untracked
counts) when the list's working dir has uncommitted changes at enqueue
time, since a new worktree forks from the commit tip and silently misses
them. BaseDirtyChecker caches per working dir for a few seconds so a
batch queue over many tasks in one list only shells out to git once. The
UI surfaces the same warning via the footer error strip on queue actions.
2026-08-10 14:30:33 +02:00

62 lines
2.1 KiB
C#

using ClaudeDo.Data;
using ClaudeDo.Worker.Git;
using ClaudeDo.Worker.Hub;
using ClaudeDo.Worker.Planning;
using ClaudeDo.Worker.Queue;
using ClaudeDo.Worker.State;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging.Abstractions;
namespace ClaudeDo.Worker.Tests.Infrastructure;
/// Test-only helper that wires TaskStateService and PlanningChainCoordinator
/// against a shared DB factory, breaking the Func cycle between them.
public static class TaskStateServiceBuilder
{
public sealed record Built(
TaskStateService State,
PlanningChainCoordinator Chain,
CapturingHubContext Hub,
Func<int> WakeCount,
CountingQueueWaker Waker,
RunCancellationRegistry RunCancels);
public static Built Build(
IDbContextFactory<ClaudeDoDbContext> dbFactory,
Func<IActiveMergeState>? mergeState = null,
IBaseDirtyChecker? baseDirtyChecker = null)
{
var hub = new CapturingHubContext();
var broadcaster = new HubBroadcaster(hub);
var waker = new CountingQueueWaker();
var runCancels = new RunCancellationRegistry(NullLogger<RunCancellationRegistry>.Instance);
TaskStateService? state = null;
var chain = new PlanningChainCoordinator(dbFactory, () => state!);
state = new TaskStateService(
dbFactory,
broadcaster,
waker,
chain,
runCancels,
mergeState ?? (() => NoActiveMergeState.Instance),
baseDirtyChecker ?? new BaseDirtyChecker(new ClaudeDo.Data.Git.GitService(), NullLogger<BaseDirtyChecker>.Instance),
NullLogger<TaskStateService>.Instance);
return new Built(state, chain, hub, () => waker.Count, waker, runCancels);
}
}
file sealed class NoActiveMergeState : IActiveMergeState
{
public static readonly NoActiveMergeState Instance = new();
public bool HasActiveMerge(string taskId) => false;
}
public sealed class CountingQueueWaker : IQueueWaker
{
private int _count;
public int Count => Volatile.Read(ref _count);
public void Wake() => Interlocked.Increment(ref _count);
}