cli: scaffold migration runner adapter and category parsing

This commit is contained in:
StellaOps Bot
2025-12-06 16:32:07 +00:00
parent 7efee7dd41
commit 0a8f8c14af
2 changed files with 51 additions and 4 deletions

View File

@@ -6,6 +6,23 @@ namespace StellaOps.Cli.Commands;
internal static class SystemCommandBuilder
{
private static MigrationCategory? ParseCategory(string? value)
{
if (string.IsNullOrWhiteSpace(value))
{
return null;
}
return value.ToLowerInvariant() switch
{
"startup" => MigrationCategory.Startup,
"release" => MigrationCategory.Release,
"seed" => MigrationCategory.Seed,
"data" => MigrationCategory.Data,
_ => throw new CommandLineException("Unknown category. Expected: startup|release|seed|data")
};
}
internal static Command BuildSystemCommand()
{
var moduleOption = new Option<string?>("--module", description: "Module name (Authority, Scheduler, Concelier, Policy, Notify, Excititor, all)");
@@ -18,12 +35,17 @@ internal static class SystemCommandBuilder
run.AddOption(dryRunOption);
run.SetAction(async parseResult =>
{
// Placeholder implementation; real execution is handled by migration host/CLI services.
var modules = MigrationModuleRegistry.GetModules(parseResult.GetValue(moduleOption));
var modules = MigrationModuleRegistry.GetModules(parseResult.GetValue(moduleOption)).ToList();
if (!modules.Any())
{
throw new CommandLineException("No modules matched the filter; available: " + string.Join(", ", MigrationModuleRegistry.ModuleNames));
}
var category = ParseCategory(parseResult.GetValue(categoryOption));
if (category == MigrationCategory.Release && parseResult.GetValue(dryRunOption) == false)
{
throw new CommandLineException("Release migrations require explicit approval; use --dry-run to preview or run approved release migrations manually.");
}
// TODO: wire MigrationRunnerAdapter to execute migrations per module/category.
await Task.CompletedTask;
});
@@ -32,11 +54,13 @@ internal static class SystemCommandBuilder
status.AddOption(categoryOption);
status.SetAction(async parseResult =>
{
var modules = MigrationModuleRegistry.GetModules(parseResult.GetValue(moduleOption));
var modules = MigrationModuleRegistry.GetModules(parseResult.GetValue(moduleOption)).ToList();
if (!modules.Any())
{
throw new CommandLineException("No modules matched the filter; available: " + string.Join(", ", MigrationModuleRegistry.ModuleNames));
}
ParseCategory(parseResult.GetValue(categoryOption));
// TODO: wire MigrationRunnerAdapter to fetch status.
await Task.CompletedTask;
});
@@ -45,11 +69,13 @@ internal static class SystemCommandBuilder
verify.AddOption(categoryOption);
verify.SetAction(async parseResult =>
{
var modules = MigrationModuleRegistry.GetModules(parseResult.GetValue(moduleOption));
var modules = MigrationModuleRegistry.GetModules(parseResult.GetValue(moduleOption)).ToList();
if (!modules.Any())
{
throw new CommandLineException("No modules matched the filter; available: " + string.Join(", ", MigrationModuleRegistry.ModuleNames));
}
ParseCategory(parseResult.GetValue(categoryOption));
// TODO: wire MigrationRunnerAdapter to verify checksums.
await Task.CompletedTask;
});

View File

@@ -0,0 +1,21 @@
using System.Threading;
using System.Threading.Tasks;
using StellaOps.Infrastructure.Postgres.Migrations;
namespace StellaOps.Cli.Services;
internal sealed class MigrationRunnerAdapter
{
private readonly IMigrationRunner _runner;
public MigrationRunnerAdapter(IMigrationRunner runner)
{
_runner = runner;
}
public Task<int> RunAsync(string migrationsPath, MigrationCategory? category, CancellationToken cancellationToken) =>
_runner.RunAsync(migrationsPath, category, cancellationToken);
public Task<int> VerifyAsync(string migrationsPath, MigrationCategory? category, CancellationToken cancellationToken) =>
_runner.VerifyAsync(migrationsPath, category, cancellationToken);
}