feat(worktrees): allow CleanupFinishedAsync to filter by list
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -24,16 +24,19 @@ public sealed class WorktreeMaintenanceService
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<CleanupResult> CleanupFinishedAsync(CancellationToken ct = default)
|
public async Task<CleanupResult> CleanupFinishedAsync(string? listId = null, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
using var context = _dbFactory.CreateDbContext();
|
using var context = _dbFactory.CreateDbContext();
|
||||||
var rows = await (from w in context.Worktrees
|
var query = from w in context.Worktrees
|
||||||
join t in context.Tasks on w.TaskId equals t.Id
|
join t in context.Tasks on w.TaskId equals t.Id
|
||||||
join l in context.Lists on t.ListId equals l.Id
|
join l in context.Lists on t.ListId equals l.Id
|
||||||
where w.State == WorktreeState.Merged || w.State == WorktreeState.Discarded
|
where w.State == WorktreeState.Merged || w.State == WorktreeState.Discarded
|
||||||
select new WorktreeRow(w.TaskId, w.Path, w.BranchName, l.WorkingDir))
|
select new { Row = new WorktreeRow(w.TaskId, w.Path, w.BranchName, l.WorkingDir), ListId = t.ListId };
|
||||||
.AsNoTracking()
|
|
||||||
.ToListAsync(ct);
|
if (!string.IsNullOrEmpty(listId))
|
||||||
|
query = query.Where(x => x.ListId == listId);
|
||||||
|
|
||||||
|
var rows = await query.AsNoTracking().Select(x => x.Row).ToListAsync(ct);
|
||||||
|
|
||||||
int removed = 0;
|
int removed = 0;
|
||||||
foreach (var row in rows)
|
foreach (var row in rows)
|
||||||
|
|||||||
@@ -200,4 +200,54 @@ public class WorktreeMaintenanceServiceTests : IDisposable
|
|||||||
var remaining = await new WorktreeRepository(checkCtx).GetAllAsync();
|
var remaining = await new WorktreeRepository(checkCtx).GetAllAsync();
|
||||||
Assert.Empty(remaining);
|
Assert.Empty(remaining);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task CleanupFinished_With_ListId_Only_Removes_That_Lists_Rows()
|
||||||
|
{
|
||||||
|
if (!GitAvailable) { Assert.True(true, "git not available -- skipping"); return; }
|
||||||
|
|
||||||
|
var repo = NewRepo();
|
||||||
|
var git = new GitService();
|
||||||
|
var db = NewDb();
|
||||||
|
|
||||||
|
var (listA, taskA) = MakeEntities(repo.RepoDir);
|
||||||
|
var (listB, taskB) = MakeEntities(repo.RepoDir);
|
||||||
|
|
||||||
|
var wtA = await CreateWorktreeAsync(git, repo.RepoDir, taskA.Id);
|
||||||
|
var wtB = await CreateWorktreeAsync(git, repo.RepoDir, taskB.Id);
|
||||||
|
|
||||||
|
using (var ctx = db.CreateContext())
|
||||||
|
{
|
||||||
|
await new ListRepository(ctx).AddAsync(listA);
|
||||||
|
await new ListRepository(ctx).AddAsync(listB);
|
||||||
|
var taskRepo = new TaskRepository(ctx);
|
||||||
|
await taskRepo.AddAsync(taskA);
|
||||||
|
await taskRepo.AddAsync(taskB);
|
||||||
|
var wtRepo = new WorktreeRepository(ctx);
|
||||||
|
await wtRepo.AddAsync(new WorktreeEntity
|
||||||
|
{
|
||||||
|
TaskId = taskA.Id, Path = wtA, BranchName = $"test/{taskA.Id}",
|
||||||
|
BaseCommit = repo.BaseCommit, State = WorktreeState.Merged, CreatedAt = DateTime.UtcNow,
|
||||||
|
});
|
||||||
|
await wtRepo.AddAsync(new WorktreeEntity
|
||||||
|
{
|
||||||
|
TaskId = taskB.Id, Path = wtB, BranchName = $"test/{taskB.Id}",
|
||||||
|
BaseCommit = repo.BaseCommit, State = WorktreeState.Merged, CreatedAt = DateTime.UtcNow,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var svc = new WorktreeMaintenanceService(
|
||||||
|
db.CreateFactory(), git, NullLogger<WorktreeMaintenanceService>.Instance);
|
||||||
|
|
||||||
|
var result = await svc.CleanupFinishedAsync(listA.Id, CancellationToken.None);
|
||||||
|
|
||||||
|
Assert.Equal(1, result.Removed);
|
||||||
|
Assert.False(Directory.Exists(wtA));
|
||||||
|
Assert.True(Directory.Exists(wtB));
|
||||||
|
|
||||||
|
using var checkCtx = db.CreateContext();
|
||||||
|
var remaining = await new WorktreeRepository(checkCtx).GetAllAsync();
|
||||||
|
Assert.Single(remaining);
|
||||||
|
Assert.Equal(taskB.Id, remaining[0].TaskId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user