feat: Add Go module and workspace test fixtures
- Created expected JSON files for Go modules and workspaces. - Added go.mod and go.sum files for example projects. - Implemented private module structure with expected JSON output. - Introduced vendored dependencies with corresponding expected JSON. - Developed PostgresGraphJobStore for managing graph jobs. - Established SQL migration scripts for graph jobs schema. - Implemented GraphJobRepository for CRUD operations on graph jobs. - Created IGraphJobRepository interface for repository abstraction. - Added unit tests for GraphJobRepository to ensure functionality.
This commit is contained in:
123
src/Cli/StellaOps.Cli/Services/MigrationCommandService.cs
Normal file
123
src/Cli/StellaOps.Cli/Services/MigrationCommandService.cs
Normal file
@@ -0,0 +1,123 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StellaOps.Infrastructure.Postgres.Migrations;
|
||||
|
||||
namespace StellaOps.Cli.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Helper for running, verifying, and querying PostgreSQL migrations from the CLI.
|
||||
/// </summary>
|
||||
internal sealed class MigrationCommandService
|
||||
{
|
||||
private readonly IConfiguration _configuration;
|
||||
private readonly ILoggerFactory _loggerFactory;
|
||||
|
||||
public MigrationCommandService(IConfiguration configuration, ILoggerFactory loggerFactory)
|
||||
{
|
||||
_configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
|
||||
_loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
|
||||
}
|
||||
|
||||
public Task<MigrationResult> RunAsync(
|
||||
MigrationModuleInfo module,
|
||||
string? connectionOverride,
|
||||
MigrationCategory? category,
|
||||
bool dryRun,
|
||||
int? timeoutSeconds,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var connectionString = ResolveConnectionString(module, connectionOverride);
|
||||
var runner = CreateRunner(module, connectionString);
|
||||
|
||||
var options = new MigrationRunOptions
|
||||
{
|
||||
CategoryFilter = category,
|
||||
DryRun = dryRun,
|
||||
TimeoutSeconds = timeoutSeconds.GetValueOrDefault(300),
|
||||
ValidateChecksums = true,
|
||||
FailOnChecksumMismatch = true
|
||||
};
|
||||
|
||||
return runner.RunFromAssemblyAsync(module.MigrationsAssembly, module.ResourcePrefix, options, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<MigrationStatus> GetStatusAsync(
|
||||
MigrationModuleInfo module,
|
||||
string? connectionOverride,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var connectionString = ResolveConnectionString(module, connectionOverride);
|
||||
var logger = _loggerFactory.CreateLogger($"migrationstatus.{module.Name}");
|
||||
var statusService = new MigrationStatusService(
|
||||
connectionString,
|
||||
module.SchemaName,
|
||||
module.Name,
|
||||
module.MigrationsAssembly,
|
||||
logger);
|
||||
|
||||
return await statusService.GetStatusAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public Task<IReadOnlyList<string>> VerifyAsync(
|
||||
MigrationModuleInfo module,
|
||||
string? connectionOverride,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var connectionString = ResolveConnectionString(module, connectionOverride);
|
||||
var runner = CreateRunner(module, connectionString);
|
||||
return runner.ValidateChecksumsAsync(module.MigrationsAssembly, module.ResourcePrefix, cancellationToken);
|
||||
}
|
||||
|
||||
private MigrationRunner CreateRunner(MigrationModuleInfo module, string connectionString) =>
|
||||
new(connectionString, module.SchemaName, module.Name, _loggerFactory.CreateLogger($"migration.{module.Name}"));
|
||||
|
||||
private string ResolveConnectionString(MigrationModuleInfo module, string? connectionOverride)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(connectionOverride))
|
||||
{
|
||||
return connectionOverride;
|
||||
}
|
||||
|
||||
var envCandidates = new[]
|
||||
{
|
||||
$"STELLAOPS_POSTGRES_{module.Name.ToUpperInvariant()}_CONNECTION",
|
||||
$"STELLAOPS_POSTGRES_{module.SchemaName.ToUpperInvariant()}_CONNECTION",
|
||||
"STELLAOPS_POSTGRES_CONNECTION",
|
||||
"STELLAOPS_DB_CONNECTION"
|
||||
};
|
||||
|
||||
foreach (var key in envCandidates)
|
||||
{
|
||||
var value = Environment.GetEnvironmentVariable(key);
|
||||
if (!string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
var configCandidates = new[]
|
||||
{
|
||||
$"StellaOps:Database:{module.Name}:ConnectionString",
|
||||
$"Database:{module.Name}:ConnectionString",
|
||||
$"StellaOps:Postgres:ConnectionString",
|
||||
$"Postgres:ConnectionString",
|
||||
"Database:ConnectionString"
|
||||
};
|
||||
|
||||
foreach (var key in configCandidates)
|
||||
{
|
||||
var value = _configuration[key];
|
||||
if (!string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidOperationException(
|
||||
$"No PostgreSQL connection string found for module '{module.Name}'. " +
|
||||
"Provide --connection or set STELLAOPS_POSTGRES_CONNECTION.");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user