feat: wip on remove config command

This commit is contained in:
Stevan Freeborn
2025-03-08 19:31:56 -06:00
parent 22eb9a7c87
commit 5647070fd3
9 changed files with 102 additions and 55 deletions
@@ -0,0 +1,6 @@
namespace AltGen.Console.Tests.Unit;
public class AddConfigCommandTests
{
}
@@ -0,0 +1,5 @@
namespace AltGen.Console.Tests.Unit;
public class AppSettingsTests
{
}
@@ -0,0 +1,5 @@
namespace AltGen.Console.Tests.Unit;
public class RemoveConfigCommandTests
{
}
@@ -7,7 +7,16 @@ static class HostBuilderExtensions
var registrar = new TypeRegistrar(builder); var registrar = new TypeRegistrar(builder);
var app = new CommandApp<GenerateCommand>(registrar); var app = new CommandApp<GenerateCommand>(registrar);
app.Configure(static c => c.AddCommand<ConfigCommand>("config")); app.Configure(static c =>
{
c.PropagateExceptions();
c.AddBranch("config", static c =>
{
c.AddCommand<AddConfigCommand>("add");
c.AddCommand<RemoveConfigCommand>("remove");
});
});
return app; return app;
} }
@@ -1,19 +1,9 @@
using Microsoft.Extensions.Configuration;
namespace AltGen.Console.Config; namespace AltGen.Console.Config;
// TODO: We should refactor this so that sealed class AddConfigCommand(
// we have a config add and a config remove command
// the config add will have basically the same code
// as below but the config remove will just
// accept a provider identifier and remove it
sealed class ConfigCommand(
IAnsiConsole console, IAnsiConsole console,
IFileSystem fileSystem, IFileSystem fileSystem
IConfiguration config ) : AsyncCommand<AddConfigCommand.Settings>
) : AsyncCommand<ConfigCommand.Settings>
{ {
static readonly JsonSerializerOptions JsonOptions = new() static readonly JsonSerializerOptions JsonOptions = new()
{ {
@@ -23,7 +13,6 @@ sealed class ConfigCommand(
}; };
readonly IAnsiConsole _console = console; readonly IAnsiConsole _console = console;
readonly IFileSystem _fileSystem = fileSystem; readonly IFileSystem _fileSystem = fileSystem;
readonly IConfiguration _config = config;
public class Settings(IFileSystem filesystem) : CommandSettings public class Settings(IFileSystem filesystem) : CommandSettings
{ {
@@ -63,47 +52,10 @@ sealed class ConfigCommand(
var existingJson = await _fileSystem.File.ReadAllTextAsync(settings.SettingsPath); var existingJson = await _fileSystem.File.ReadAllTextAsync(settings.SettingsPath);
var existingAppSettings = JsonSerializer.Deserialize<AppSettings>(existingJson, JsonOptions) var existingAppSettings = JsonSerializer.Deserialize<AppSettings>(existingJson, JsonOptions)
?? throw new ConfigException("Failed to deserialize settings."); ?? throw new ConfigException("Failed to deserialize settings.");
var updatedAppSettings = existingAppSettings.Update(settings); var updatedAppSettings = existingAppSettings.AddOrUpdateProvider(settings);
var udpatedJson = JsonSerializer.Serialize(updatedAppSettings, JsonOptions); var udpatedJson = JsonSerializer.Serialize(updatedAppSettings, JsonOptions);
await _fileSystem.File.WriteAllTextAsync(settings.SettingsPath, udpatedJson); await _fileSystem.File.WriteAllTextAsync(settings.SettingsPath, udpatedJson);
_console.MarkupLine($"[bold]{settings.Provider}[/] has been configured."); _console.MarkupLine($"[bold]{settings.Provider}[/] has been configured.");
return 0; return 0;
} }
} }
record AppSettings(ProviderSettings[] Providers)
{
public AppSettings Update(ConfigCommand.Settings settings)
{
var updatedProviders = Providers.Select(p =>
{
if (p.Provider == settings.Provider)
{
return p with { Key = settings.Key, Default = settings.Default };
}
if (p.Provider != settings.Provider && settings.Default)
{
return p with { Default = false };
}
return p;
});
var provider = Providers.FirstOrDefault(p => p.Provider == settings.Provider);
if (provider is null)
{
var newProvider = new ProviderSettings(settings.Provider, settings.Key, settings.Default);
return this with { Providers = [.. updatedProviders, newProvider] };
}
return this with { Providers = [.. updatedProviders] };
}
}
record ProviderSettings(string Provider, string Key, bool Default);
class ConfigException(string message) : Exception(message)
{
}
+38
View File
@@ -0,0 +1,38 @@
namespace AltGen.Console.Config;
record AppSettings(ProviderSettings[] Providers)
{
public AppSettings AddOrUpdateProvider(AddConfigCommand.Settings settings)
{
var updatedProviders = Providers.Select(p =>
{
if (p.Provider == settings.Provider)
{
return p with { Key = settings.Key, Default = settings.Default };
}
if (p.Provider != settings.Provider && settings.Default)
{
return p with { Default = false };
}
return p;
});
var provider = Providers.FirstOrDefault(p => p.Provider == settings.Provider);
if (provider is null)
{
var newProvider = new ProviderSettings(settings.Provider, settings.Key, settings.Default);
return this with { Providers = [.. updatedProviders, newProvider] };
}
return this with { Providers = [.. updatedProviders] };
}
public AppSettings RemoveProvider(RemoveConfigCommand.Settings settings)
{
var updatedProviders = Providers.Where(p => p.Provider != settings.Provider);
return this with { Providers = [.. updatedProviders] };
}
}
@@ -0,0 +1,5 @@
namespace AltGen.Console.Config;
class ConfigException(string message) : Exception(message)
{
}
@@ -0,0 +1,3 @@
namespace AltGen.Console.Config;
record ProviderSettings(string Provider, string Key, bool Default);
@@ -1,16 +1,40 @@
namespace AltGen.Console.Config; namespace AltGen.Console.Config;
sealed class RemoveConfigCommand() : AsyncCommand<RemoveConfigCommand.Settings> sealed class RemoveConfigCommand(
IFileSystem fileSystem,
IAnsiConsole console
) : AsyncCommand<RemoveConfigCommand.Settings>
{ {
public class Settings : CommandSettings readonly IFileSystem _fileSystem = fileSystem;
readonly IAnsiConsole _console = console;
public class Settings(IFileSystem fileSystem) : CommandSettings
{ {
readonly IFileSystem _fileSystem = fileSystem;
[CommandArgument(1, "<provider>")] [CommandArgument(1, "<provider>")]
[Description("The provider to remove.")] [Description("The provider to remove.")]
public string Provider { get; init; } = string.Empty; public string Provider { get; init; } = string.Empty;
public string SettingsPath => _fileSystem.Path.Combine(AppContext.BaseDirectory, "appsettings.json");
} }
public override async Task<int> ExecuteAsync(CommandContext context, Settings settings) public override async Task<int> ExecuteAsync(CommandContext context, Settings settings)
{ {
var exists = _fileSystem.Path.Exists(settings.SettingsPath);
if (exists is false)
{
_console.MarkupLine("[bold]No existing settings found.[/]");
return 1;
}
var settingsJson = await _fileSystem.File.ReadAllTextAsync(settings.SettingsPath);
var appSettings = JsonSerializer.Deserialize<AppSettings>(settingsJson) ?? throw new ConfigException("Failed to deserialize app settings.");
var updatedAppSettings = appSettings.RemoveProvider(settings);
var updatedJson = JsonSerializer.Serialize(updatedAppSettings);
await _fileSystem.File.WriteAllTextAsync(settings.SettingsPath, updatedJson);
_console.MarkupLine($"[bold]{settings.Provider}[/] has been removed.");
return 0; return 0;
} }
} }