feat(installer): add WriteInstallManifestStep

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Mika Kuns
2026-04-15 09:48:29 +02:00
parent ea32a74baa
commit 548251841f
2 changed files with 76 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
using System.IO;
using ClaudeDo.Installer.Core;
namespace ClaudeDo.Installer.Steps;
public sealed class WriteInstallManifestStep : IInstallStep
{
public string Name => "Write Install Manifest";
public Task<StepResult> ExecuteAsync(InstallContext ctx, IProgress<string> progress, CancellationToken ct)
{
if (string.IsNullOrWhiteSpace(ctx.InstalledVersion))
return Task.FromResult(StepResult.Fail("Installed version is not set — DownloadAndExtractStep must run first."));
var manifest = new InstallManifest(
Version: ctx.InstalledVersion!,
InstallDir: ctx.InstallDirectory,
WorkerDir: Path.Combine(ctx.InstallDirectory, "worker"),
InstalledAt: DateTimeOffset.UtcNow);
InstallManifestStore.Write(ctx.InstallDirectory, manifest);
progress.Report($"Wrote {InstallManifestStore.ManifestPath(ctx.InstallDirectory)}");
return Task.FromResult(StepResult.Ok());
}
}

View File

@@ -0,0 +1,51 @@
using ClaudeDo.Installer.Core;
using ClaudeDo.Installer.Steps;
namespace ClaudeDo.Installer.Tests;
public sealed class WriteInstallManifestStepTests : IDisposable
{
private readonly string _installDir;
public WriteInstallManifestStepTests()
{
_installDir = Path.Combine(Path.GetTempPath(), "ClaudeDoWriteManifest-" + Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(_installDir);
}
public void Dispose()
{
try { Directory.Delete(_installDir, recursive: true); } catch { }
}
[Fact]
public async Task Writes_Manifest_WithAllFields()
{
var ctx = new InstallContext
{
InstallDirectory = _installDir,
InstalledVersion = "0.2.0",
};
var step = new WriteInstallManifestStep();
var result = await step.ExecuteAsync(ctx, new Progress<string>(_ => { }), CancellationToken.None);
Assert.True(result.Success);
var manifest = InstallManifestStore.TryRead(_installDir);
Assert.NotNull(manifest);
Assert.Equal("0.2.0", manifest!.Version);
Assert.Equal(_installDir, manifest.InstallDir);
Assert.Equal(Path.Combine(_installDir, "worker"), manifest.WorkerDir);
}
[Fact]
public async Task Fails_When_InstalledVersion_Missing()
{
var ctx = new InstallContext { InstallDirectory = _installDir }; // no version set
var step = new WriteInstallManifestStep();
var result = await step.ExecuteAsync(ctx, new Progress<string>(_ => { }), CancellationToken.None);
Assert.False(result.Success);
}
}