From 414e712f515f5b18c8d118921efeb52f52f3d280 Mon Sep 17 00:00:00 2001
From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com>
Date: Fri, 14 Mar 2025 22:02:22 -0500
Subject: [PATCH] feat: add app settings manager to do the reading and writing
---
src/AltGen.API/AltGen.API.csproj | 1 +
.../Unit/AddConfigCommandTests.cs | 91 +++++-----------
.../Unit/AppSettingsManagerTests.cs | 100 ++++++++++++++++++
.../Unit/AppSettingsTests.cs | 10 +-
.../Unit/ListConfigCommandTests.cs | 68 +++---------
.../Unit/RemoveConfigCommandTests.cs | 67 ++++--------
src/AltGen.Console/AltGen.Console.csproj | 1 +
src/AltGen.Console/Config/AddConfigCommand.cs | 25 ++---
.../Config/AppSettingsManager.cs | 30 ++++++
.../Config/IAppSettingsManager.cs | 8 ++
.../Config/ListConfigCommand.cs | 16 ++-
.../Config/RemoveConfigCommand.cs | 23 ++--
src/AltGen.Console/Generate/IAltGenService.cs | 2 +-
src/AltGen.Console/Program.cs | 1 +
14 files changed, 229 insertions(+), 214 deletions(-)
create mode 100644 src/AltGen.Console.Tests/Unit/AppSettingsManagerTests.cs
create mode 100644 src/AltGen.Console/Config/AppSettingsManager.cs
create mode 100644 src/AltGen.Console/Config/IAppSettingsManager.cs
diff --git a/src/AltGen.API/AltGen.API.csproj b/src/AltGen.API/AltGen.API.csproj
index d73d24c..3aabe5f 100644
--- a/src/AltGen.API/AltGen.API.csproj
+++ b/src/AltGen.API/AltGen.API.csproj
@@ -11,6 +11,7 @@
+
diff --git a/src/AltGen.Console.Tests/Unit/AddConfigCommandTests.cs b/src/AltGen.Console.Tests/Unit/AddConfigCommandTests.cs
index 15e3344..a7af256 100644
--- a/src/AltGen.Console.Tests/Unit/AddConfigCommandTests.cs
+++ b/src/AltGen.Console.Tests/Unit/AddConfigCommandTests.cs
@@ -2,35 +2,28 @@ namespace AltGen.Console.Tests.Unit;
public class AddConfigCommandTests : IDisposable
{
- readonly Mock _fileSystem = new();
+ readonly Mock _mockSettingsManager = new();
readonly TestConsole _testConsole = new();
readonly AddConfigCommand _sut;
public AddConfigCommandTests()
{
- _sut = new AddConfigCommand(_testConsole, _fileSystem.Object);
+ _sut = new AddConfigCommand(_testConsole, _mockSettingsManager.Object);
}
[Fact]
public async Task ExecuteAsync_WhenSettingsDoNotExist_ItShouldCreateSettings()
{
- var testSettingsPath = "appsettings.json";
var expectedAppSettings = new AppSettings([
new("provider", "key", false)
]);
- var expectedJson = JsonSerializer.Serialize(expectedAppSettings, JsonOptions.Default);
-
- _fileSystem
- .Setup(static x => x.Path.Combine(It.IsAny(), It.IsAny()))
- .Returns(testSettingsPath);
-
- _fileSystem
- .Setup(static x => x.File.Exists(It.IsAny()))
+ _mockSettingsManager
+ .Setup(static x => x.AppSettingsExist())
.Returns(false);
- var commandSettings = new AddConfigCommand.Settings(_fileSystem.Object)
+ var commandSettings = new AddConfigCommand.Settings()
{
Provider = "provider",
Key = "key",
@@ -40,39 +33,36 @@ public class AddConfigCommandTests : IDisposable
result.Should().Be(0);
- _fileSystem
- .Verify(
- x => x.File.WriteAllTextAsync(testSettingsPath, expectedJson, default),
- Times.Once
- );
+ _mockSettingsManager.Verify(
+ static x => x.SaveAppSettingsAsync(It.Is(
+ static x => x.Providers[0].Provider == "provider" &&
+ x.Providers[0].Key == "key" &&
+ x.Providers[0].Default == false
+ )),
+ Times.Once
+ );
}
[Fact]
public async Task ExecuteAsync_WhenSettingsExist_ItShouldUpdateSettings()
{
- var testSettingsPath = "appsettings.json";
var existingAppSettings = new AppSettings([
new("existing", "existing", false)
]);
- var existingJson = JsonSerializer.Serialize(existingAppSettings, JsonOptions.Default);
+
var expectedAppSettings = new AppSettings([
new("existing", "key", true)
]);
- var expectedJson = JsonSerializer.Serialize(expectedAppSettings, JsonOptions.Default);
- _fileSystem
- .Setup(static x => x.Path.Combine(It.IsAny(), It.IsAny()))
- .Returns(testSettingsPath);
-
- _fileSystem
- .Setup(static x => x.File.Exists(It.IsAny()))
+ _mockSettingsManager
+ .Setup(static x => x.AppSettingsExist())
.Returns(true);
- _fileSystem
- .Setup(static x => x.File.ReadAllTextAsync(It.IsAny(), default))
- .ReturnsAsync(existingJson);
+ _mockSettingsManager
+ .Setup(static x => x.GetAppSettingsAsync())
+ .ReturnsAsync(existingAppSettings);
- var commandSettings = new AddConfigCommand.Settings(_fileSystem.Object)
+ var commandSettings = new AddConfigCommand.Settings()
{
Provider = "existing",
Key = "key",
@@ -83,39 +73,14 @@ public class AddConfigCommandTests : IDisposable
result.Should().Be(0);
- _fileSystem
- .Verify(
- x => x.File.WriteAllTextAsync(testSettingsPath, expectedJson, default),
- Times.Once
- );
- }
-
- [Fact]
- public async Task ExecuteAsync_WhenSettingsExistButCanNotBeDeserialized_ItShouldThrow()
- {
- var testSettingsPath = "appsettings.json";
-
- _fileSystem
- .Setup(static x => x.Path.Combine(It.IsAny(), It.IsAny()))
- .Returns(testSettingsPath);
-
- _fileSystem
- .Setup(static x => x.File.Exists(It.IsAny()))
- .Returns(true);
-
- _fileSystem
- .Setup(static x => x.File.ReadAllTextAsync(It.IsAny(), default))
- .ReturnsAsync("null");
-
- var commandSettings = new AddConfigCommand.Settings(_fileSystem.Object)
- {
- Provider = "provider",
- Key = "key",
- };
-
- var act = async () => await _sut.ExecuteAsync(null!, commandSettings);
-
- await act.Should().ThrowAsync();
+ _mockSettingsManager.Verify(
+ static x => x.SaveAppSettingsAsync(It.Is(
+ static x => x.Providers[0].Provider == "existing" &&
+ x.Providers[0].Key == "key" &&
+ x.Providers[0].Default == true
+ )),
+ Times.Once
+ );
}
public void Dispose()
diff --git a/src/AltGen.Console.Tests/Unit/AppSettingsManagerTests.cs b/src/AltGen.Console.Tests/Unit/AppSettingsManagerTests.cs
new file mode 100644
index 0000000..164d6a9
--- /dev/null
+++ b/src/AltGen.Console.Tests/Unit/AppSettingsManagerTests.cs
@@ -0,0 +1,100 @@
+namespace AltGen.Console.Tests.Unit;
+
+public class AppSettingsManagerTests
+{
+ readonly Mock _mockFileSystem = new();
+ readonly AppSettingsManager _sut;
+
+ public AppSettingsManagerTests()
+ {
+ _mockFileSystem
+ .Setup(static x => x.Path.Combine(It.IsAny(), It.IsAny()))
+ .Returns("path");
+
+ _sut = new AppSettingsManager(_mockFileSystem.Object);
+ }
+
+ [Fact]
+ public void AppSettingsExist_WhenSettingsDoNotExist_ItShouldReturnFalse()
+ {
+ _mockFileSystem
+ .Setup(static x => x.Path.Exists(It.IsAny()))
+ .Returns(false);
+
+ var result = _sut.AppSettingsExist();
+
+ result.Should().BeFalse();
+ }
+
+ [Fact]
+ public void AppSettingsExist_WhenSettingsExist_ItShouldReturnTrue()
+ {
+ _mockFileSystem
+ .Setup(static x => x.Path.Exists(It.IsAny()))
+ .Returns(true);
+
+ var result = _sut.AppSettingsExist();
+
+ result.Should().BeTrue();
+ }
+
+ [Fact]
+ public async Task GetAppSettingsAsync_WhenSettingsExist_ItShouldReturnSettings()
+ {
+ var testSettings = new AppSettings([
+ new("provider", "key", false)
+ ]);
+
+ var json = JsonSerializer.Serialize(testSettings, JsonOptions.Default);
+
+ _mockFileSystem
+ .Setup(static x => x.File.ReadAllTextAsync(It.IsAny(), default))
+ .ReturnsAsync(json);
+
+ var result = await _sut.GetAppSettingsAsync();
+
+ result.Should().BeEquivalentTo(testSettings);
+ }
+
+ [Fact]
+ public async Task GetAppSettingsAsync_WhenDeserializingSettingsIsNull_ItShouldReturnEmptySettings()
+ {
+ _mockFileSystem
+ .Setup(static x => x.File.ReadAllTextAsync(It.IsAny(), default))
+ .ReturnsAsync("null");
+
+ var result = await _sut.GetAppSettingsAsync();
+
+ result.Should().BeEquivalentTo(new AppSettings([]));
+ }
+
+ [Fact]
+ public async Task GetAppSettingsAsync_WhenSettingsDoNotExist_ItShouldThrow()
+ {
+ _mockFileSystem
+ .Setup(static x => x.File.ReadAllTextAsync(It.IsAny(), default))
+ .ThrowsAsync(new FileNotFoundException());
+
+ var action = _sut.GetAppSettingsAsync;
+
+ await action.Should().ThrowAsync();
+ }
+
+ [Fact]
+ public async Task SaveAppSettingsAsync_WhenCalled_ItShouldSaveSettings()
+ {
+ _mockFileSystem
+ .Setup(static x => x.File.WriteAllTextAsync(It.IsAny(), It.IsAny(), default))
+ .Returns(Task.CompletedTask);
+
+ var testSettings = new AppSettings([
+ new("provider", "key", false)
+ ]);
+
+ var json = JsonSerializer.Serialize(testSettings, JsonOptions.Default);
+
+ await _sut.SaveAppSettingsAsync(testSettings);
+
+ _mockFileSystem.Verify(x => x.File.WriteAllTextAsync(It.IsAny(), json, default), Times.Once);
+ }
+}
\ No newline at end of file
diff --git a/src/AltGen.Console.Tests/Unit/AppSettingsTests.cs b/src/AltGen.Console.Tests/Unit/AppSettingsTests.cs
index bb5b868..e50e9ed 100644
--- a/src/AltGen.Console.Tests/Unit/AppSettingsTests.cs
+++ b/src/AltGen.Console.Tests/Unit/AppSettingsTests.cs
@@ -2,14 +2,12 @@ namespace AltGen.Console.Tests.Unit;
public class AppSettingsTests
{
- readonly Mock _fileSystemMock = new();
-
[Fact]
public void AddOrUpdateProvider_WhenProviderDoesNotExist_ItShouldAddProvider()
{
var providerSettings = new ProviderSettings("provider", "key", true);
- var commandSettings = new AddConfigCommand.Settings(_fileSystemMock.Object)
+ var commandSettings = new AddConfigCommand.Settings()
{
Provider = providerSettings.Provider,
Key = providerSettings.Key,
@@ -29,7 +27,7 @@ public class AppSettingsTests
var providerSettings = new ProviderSettings("provider", "key", true);
var existingProviderSettings = new ProviderSettings("provider", "key", false);
- var commandSettings = new AddConfigCommand.Settings(_fileSystemMock.Object)
+ var commandSettings = new AddConfigCommand.Settings()
{
Provider = providerSettings.Provider,
Key = providerSettings.Key,
@@ -48,7 +46,7 @@ public class AppSettingsTests
var providerSettings = new ProviderSettings("claude", "key", true);
var existingProviderSettings = new ProviderSettings("gemini", "key", true);
- var commandSettings = new AddConfigCommand.Settings(_fileSystemMock.Object)
+ var commandSettings = new AddConfigCommand.Settings()
{
Provider = providerSettings.Provider,
Key = providerSettings.Key,
@@ -69,7 +67,7 @@ public class AppSettingsTests
{
var existingProviderSettings = new ProviderSettings("provider", "key", true);
- var commandSettings = new RemoveConfigCommand.Settings(_fileSystemMock.Object)
+ var commandSettings = new RemoveConfigCommand.Settings()
{
Provider = existingProviderSettings.Provider,
};
diff --git a/src/AltGen.Console.Tests/Unit/ListConfigCommandTests.cs b/src/AltGen.Console.Tests/Unit/ListConfigCommandTests.cs
index d17cf11..d3120fd 100644
--- a/src/AltGen.Console.Tests/Unit/ListConfigCommandTests.cs
+++ b/src/AltGen.Console.Tests/Unit/ListConfigCommandTests.cs
@@ -2,26 +2,20 @@ namespace AltGen.Console.Tests.Unit;
public class ListConfigCommandTests : IDisposable
{
- readonly Mock _fileSystem = new();
+ readonly Mock _mockSettingsManager = new();
readonly TestConsole _testConsole = new();
readonly ListConfigCommand _sut;
public ListConfigCommandTests()
{
- _sut = new ListConfigCommand(_testConsole, _fileSystem.Object);
+ _sut = new ListConfigCommand(_testConsole, _mockSettingsManager.Object);
}
[Fact]
public async Task ExecuteAsync_WhenSettingsDoNotExist_ItShouldOutputNoSettings()
{
- var testSettingsPath = "appsettings.json";
-
- _fileSystem
- .Setup(static x => x.Path.Combine(It.IsAny(), It.IsAny()))
- .Returns(testSettingsPath);
-
- _fileSystem
- .Setup(static x => x.File.Exists(It.IsAny()))
+ _mockSettingsManager
+ .Setup(static x => x.AppSettingsExist())
.Returns(false);
var result = await _sut.ExecuteAsync(null!);
@@ -37,23 +31,17 @@ public class ListConfigCommandTests : IDisposable
[Fact]
public async Task ExecuteAsync_WhenSettingsExist_ItShouldOutputSettings()
{
- var testSettingsPath = "appsettings.json";
var testSettings = new AppSettings([
new("provider", "key", false)
]);
- var testSettingsJson = JsonSerializer.Serialize(testSettings, JsonOptions.Default);
- _fileSystem
- .Setup(static x => x.Path.Combine(It.IsAny(), It.IsAny()))
- .Returns(testSettingsPath);
-
- _fileSystem
- .Setup(static x => x.File.Exists(It.IsAny()))
+ _mockSettingsManager
+ .Setup(static x => x.AppSettingsExist())
.Returns(true);
- _fileSystem
- .Setup(static x => x.File.ReadAllTextAsync(It.IsAny(), default))
- .ReturnsAsync(testSettingsJson);
+ _mockSettingsManager
+ .Setup(static x => x.GetAppSettingsAsync())
+ .ReturnsAsync(testSettings);
var result = await _sut.ExecuteAsync(null!);
@@ -68,23 +56,17 @@ public class ListConfigCommandTests : IDisposable
[Fact]
public async Task ExecuteAsync_WhenSettingsExistAndDefault_ItShouldOutputSettings()
{
- var testSettingsPath = "appsettings.json";
var testSettings = new AppSettings([
new("provider", "key", true)
]);
- var testSettingsJson = JsonSerializer.Serialize(testSettings, JsonOptions.Default);
- _fileSystem
- .Setup(static x => x.Path.Combine(It.IsAny(), It.IsAny()))
- .Returns(testSettingsPath);
-
- _fileSystem
- .Setup(static x => x.File.Exists(It.IsAny()))
+ _mockSettingsManager
+ .Setup(static x => x.AppSettingsExist())
.Returns(true);
- _fileSystem
- .Setup(static x => x.File.ReadAllTextAsync(It.IsAny(), default))
- .ReturnsAsync(testSettingsJson);
+ _mockSettingsManager
+ .Setup(static x => x.GetAppSettingsAsync())
+ .ReturnsAsync(testSettings);
var result = await _sut.ExecuteAsync(null!);
@@ -96,28 +78,6 @@ public class ListConfigCommandTests : IDisposable
.Contain("provider key (default)");
}
- [Fact]
- public async Task ExecuteAsync_WhenSettingsCanNotBeDeserialized_ItShouldThrowConfigException()
- {
- var testSettingsPath = "appsettings.json";
-
- _fileSystem
- .Setup(static x => x.Path.Combine(It.IsAny(), It.IsAny()))
- .Returns(testSettingsPath);
-
- _fileSystem
- .Setup(static x => x.File.Exists(It.IsAny()))
- .Returns(true);
-
- _fileSystem
- .Setup(static x => x.File.ReadAllTextAsync(It.IsAny(), default))
- .ReturnsAsync("null");
-
- var action = async () => await _sut.ExecuteAsync(null!);
-
- await action.Should().ThrowAsync();
- }
-
public void Dispose()
{
_testConsole.Dispose();
diff --git a/src/AltGen.Console.Tests/Unit/RemoveConfigCommandTests.cs b/src/AltGen.Console.Tests/Unit/RemoveConfigCommandTests.cs
index 3b8fed3..e49c1ee 100644
--- a/src/AltGen.Console.Tests/Unit/RemoveConfigCommandTests.cs
+++ b/src/AltGen.Console.Tests/Unit/RemoveConfigCommandTests.cs
@@ -2,29 +2,23 @@ namespace AltGen.Console.Tests.Unit;
public class RemoveConfigCommandTests : IDisposable
{
- readonly Mock _fileSystem = new();
+ readonly Mock _mockSettingsManager = new();
readonly TestConsole _testConsole = new();
readonly RemoveConfigCommand _sut;
public RemoveConfigCommandTests()
{
- _sut = new RemoveConfigCommand(_fileSystem.Object, _testConsole);
+ _sut = new RemoveConfigCommand(_testConsole, _mockSettingsManager.Object);
}
[Fact]
public async Task ExecuteAsync_WhenSettingsDoNotExist_ItShouldThrow()
{
- var testSettingsPath = "appsettings.json";
-
- _fileSystem
- .Setup(static x => x.Path.Combine(It.IsAny(), It.IsAny()))
- .Returns(testSettingsPath);
-
- _fileSystem
- .Setup(static x => x.Path.Exists(It.IsAny()))
+ _mockSettingsManager
+ .Setup(static x => x.AppSettingsExist())
.Returns(false);
- var commandSettings = new RemoveConfigCommand.Settings(_fileSystem.Object)
+ var commandSettings = new RemoveConfigCommand.Settings()
{
Provider = "provider",
};
@@ -38,23 +32,17 @@ public class RemoveConfigCommandTests : IDisposable
[Fact]
public async Task ExecuteAsync_WhenProviderDoesNotExist_ItShouldDoNothing()
{
- var testSettingsPath = "appsettings.json";
var testSettings = new AppSettings([]);
- var testSettingsJson = JsonSerializer.Serialize(testSettings, JsonOptions.Default);
- _fileSystem
- .Setup(static x => x.Path.Combine(It.IsAny(), It.IsAny()))
- .Returns(testSettingsPath);
-
- _fileSystem
- .Setup(static x => x.Path.Exists(It.IsAny()))
+ _mockSettingsManager
+ .Setup(static x => x.AppSettingsExist())
.Returns(true);
- _fileSystem
- .Setup(static x => x.File.ReadAllTextAsync(It.IsAny(), default))
- .ReturnsAsync(testSettingsJson);
+ _mockSettingsManager
+ .Setup(static x => x.GetAppSettingsAsync())
+ .ReturnsAsync(testSettings);
- var commandSettings = new RemoveConfigCommand.Settings(_fileSystem.Object)
+ var commandSettings = new RemoveConfigCommand.Settings()
{
Provider = "provider",
};
@@ -63,35 +51,27 @@ public class RemoveConfigCommandTests : IDisposable
result.Should().Be(0);
- _fileSystem
- .Verify(
- x => x.File.WriteAllTextAsync(testSettingsPath, testSettingsJson, default),
- Times.Once
- );
+ _mockSettingsManager.Verify(x => x.SaveAppSettingsAsync(testSettings), Times.Once);
}
[Fact]
public async Task ExecuteAsync_WhenProviderExists_ItShouldRemoveProviderFromSettings()
{
- var testSettingsPath = "appsettings.json";
var testSettings = new AppSettings([
new("provider", "key", false)
]);
- var testSettingsJson = JsonSerializer.Serialize(testSettings, JsonOptions.Default);
- _fileSystem
- .Setup(static x => x.Path.Combine(It.IsAny(), It.IsAny()))
- .Returns(testSettingsPath);
+ var expectedSettings = new AppSettings([]);
- _fileSystem
- .Setup(static x => x.Path.Exists(It.IsAny()))
+ _mockSettingsManager
+ .Setup(static x => x.AppSettingsExist())
.Returns(true);
- _fileSystem
- .Setup(static x => x.File.ReadAllTextAsync(It.IsAny(), default))
- .ReturnsAsync(testSettingsJson);
+ _mockSettingsManager
+ .Setup(static x => x.GetAppSettingsAsync())
+ .ReturnsAsync(testSettings);
- var commandSettings = new RemoveConfigCommand.Settings(_fileSystem.Object)
+ var commandSettings = new RemoveConfigCommand.Settings()
{
Provider = "provider",
};
@@ -100,14 +80,7 @@ public class RemoveConfigCommandTests : IDisposable
result.Should().Be(0);
- var expectedSettings = new AppSettings([]);
- var expectedSettingsJson = JsonSerializer.Serialize(expectedSettings, JsonOptions.Default);
-
- _fileSystem
- .Verify(
- x => x.File.WriteAllTextAsync(testSettingsPath, expectedSettingsJson, default),
- Times.Once
- );
+ _mockSettingsManager.Verify(x => x.SaveAppSettingsAsync(expectedSettings), Times.Once);
}
public void Dispose()
diff --git a/src/AltGen.Console/AltGen.Console.csproj b/src/AltGen.Console/AltGen.Console.csproj
index f192040..089a558 100644
--- a/src/AltGen.Console/AltGen.Console.csproj
+++ b/src/AltGen.Console/AltGen.Console.csproj
@@ -17,6 +17,7 @@
+
diff --git a/src/AltGen.Console/Config/AddConfigCommand.cs b/src/AltGen.Console/Config/AddConfigCommand.cs
index ca51f94..5d69f08 100644
--- a/src/AltGen.Console/Config/AddConfigCommand.cs
+++ b/src/AltGen.Console/Config/AddConfigCommand.cs
@@ -2,16 +2,14 @@ namespace AltGen.Console.Config;
sealed class AddConfigCommand(
IAnsiConsole console,
- IFileSystem fileSystem
+ IAppSettingsManager settingsManager
) : AsyncCommand
{
readonly IAnsiConsole _console = console;
- readonly IFileSystem _fileSystem = fileSystem;
+ readonly IAppSettingsManager _settingsManager = settingsManager;
- public class Settings(IFileSystem filesystem) : CommandSettings
+ public class Settings : CommandSettings
{
- readonly IFileSystem _fileSystem = filesystem;
-
[CommandArgument(1, "")]
[Description("The provider to configure.")]
public string Provider { get; init; } = string.Empty;
@@ -23,32 +21,23 @@ sealed class AddConfigCommand(
[CommandOption("-d|--default")]
[Description("Set the provider as the default.")]
public bool Default { get; init; }
-
- public string SettingsPath => _fileSystem.Path.Combine(AppContext.BaseDirectory, AppSettings.SettingsFileName);
}
public override async Task ExecuteAsync(CommandContext context, Settings settings)
{
- var settingsExist = _fileSystem.File.Exists(settings.SettingsPath);
-
- if (settingsExist is false)
+ if (_settingsManager.AppSettingsExist() is false)
{
var appSettings = new AppSettings([
new(settings.Provider, settings.Key, settings.Default)
]);
-
- var json = JsonSerializer.Serialize(appSettings, JsonOptions.Default);
- await _fileSystem.File.WriteAllTextAsync(settings.SettingsPath, json);
+ await _settingsManager.SaveAppSettingsAsync(appSettings);
_console.MarkupLine($"[bold]{settings.Provider}[/] has been configured.");
return 0;
}
- var existingJson = await _fileSystem.File.ReadAllTextAsync(settings.SettingsPath);
- var existingAppSettings = JsonSerializer.Deserialize(existingJson, JsonOptions.Default)
- ?? throw new ConfigException("Failed to deserialize settings.");
+ var existingAppSettings = await _settingsManager.GetAppSettingsAsync();
var updatedAppSettings = existingAppSettings.AddOrUpdateProvider(settings);
- var udpatedJson = JsonSerializer.Serialize(updatedAppSettings, JsonOptions.Default);
- await _fileSystem.File.WriteAllTextAsync(settings.SettingsPath, udpatedJson);
+ await _settingsManager.SaveAppSettingsAsync(updatedAppSettings);
_console.MarkupLine($"[bold]{settings.Provider}[/] has been configured.");
return 0;
}
diff --git a/src/AltGen.Console/Config/AppSettingsManager.cs b/src/AltGen.Console/Config/AppSettingsManager.cs
new file mode 100644
index 0000000..db8ae4e
--- /dev/null
+++ b/src/AltGen.Console/Config/AppSettingsManager.cs
@@ -0,0 +1,30 @@
+namespace AltGen.Console.Config;
+
+class AppSettingsManager(IFileSystem fileSystem) : IAppSettingsManager
+{
+ const string SettingsFileName = "appsettings.json";
+ readonly IFileSystem _fileSystem = fileSystem;
+
+ public bool AppSettingsExist()
+ {
+ return _fileSystem.Path.Exists(SettingsFileName);
+ }
+
+ public async Task GetAppSettingsAsync()
+ {
+ var existingJson = await _fileSystem.File.ReadAllTextAsync(GetSettingsPath());
+ var existingAppSettings = JsonSerializer.Deserialize(existingJson, JsonOptions.Default) ?? new AppSettings([]);
+ return existingAppSettings;
+ }
+
+ public async Task SaveAppSettingsAsync(AppSettings appSettings)
+ {
+ var json = JsonSerializer.Serialize(appSettings, JsonOptions.Default);
+ await _fileSystem.File.WriteAllTextAsync(GetSettingsPath(), json);
+ }
+
+ string GetSettingsPath()
+ {
+ return _fileSystem.Path.Combine(AppContext.BaseDirectory, SettingsFileName);
+ }
+}
\ No newline at end of file
diff --git a/src/AltGen.Console/Config/IAppSettingsManager.cs b/src/AltGen.Console/Config/IAppSettingsManager.cs
new file mode 100644
index 0000000..67a5886
--- /dev/null
+++ b/src/AltGen.Console/Config/IAppSettingsManager.cs
@@ -0,0 +1,8 @@
+namespace AltGen.Console.Config;
+
+interface IAppSettingsManager
+{
+ bool AppSettingsExist();
+ Task GetAppSettingsAsync();
+ Task SaveAppSettingsAsync(AppSettings appSettings);
+}
\ No newline at end of file
diff --git a/src/AltGen.Console/Config/ListConfigCommand.cs b/src/AltGen.Console/Config/ListConfigCommand.cs
index 31d1918..8f42182 100644
--- a/src/AltGen.Console/Config/ListConfigCommand.cs
+++ b/src/AltGen.Console/Config/ListConfigCommand.cs
@@ -1,25 +1,23 @@
namespace AltGen.Console.Config;
-sealed class ListConfigCommand(IAnsiConsole console, IFileSystem fileSystem) : AsyncCommand
+sealed class ListConfigCommand(
+ IAnsiConsole console,
+ IAppSettingsManager settingsManager
+) : AsyncCommand
{
readonly IAnsiConsole _console = console;
- readonly IFileSystem _fileSystem = fileSystem;
+ readonly IAppSettingsManager _settingsManager = settingsManager;
public override async Task ExecuteAsync(CommandContext context)
{
- var settingsPath = _fileSystem.Path.Combine(AppContext.BaseDirectory, AppSettings.SettingsFileName);
- var settingsExist = _fileSystem.File.Exists(settingsPath);
-
- if (settingsExist is false)
+ if (_settingsManager.AppSettingsExist() is false)
{
_console.MarkupLine("No settings found.");
return 0;
}
- var settingsJson = await _fileSystem.File.ReadAllTextAsync(settingsPath);
- var appSettings = JsonSerializer.Deserialize(settingsJson, JsonOptions.Default)
- ?? throw new ConfigException("Failed to deserialize settings.");
+ var appSettings = await _settingsManager.GetAppSettingsAsync();
foreach (var provider in appSettings.Providers)
{
diff --git a/src/AltGen.Console/Config/RemoveConfigCommand.cs b/src/AltGen.Console/Config/RemoveConfigCommand.cs
index 7bc0540..925f408 100644
--- a/src/AltGen.Console/Config/RemoveConfigCommand.cs
+++ b/src/AltGen.Console/Config/RemoveConfigCommand.cs
@@ -1,39 +1,30 @@
namespace AltGen.Console.Config;
sealed class RemoveConfigCommand(
- IFileSystem fileSystem,
- IAnsiConsole console
+ IAnsiConsole console,
+ IAppSettingsManager settingsManager
) : AsyncCommand
{
- readonly IFileSystem _fileSystem = fileSystem;
readonly IAnsiConsole _console = console;
+ readonly IAppSettingsManager _settingsManager = settingsManager;
- public class Settings(IFileSystem fileSystem) : CommandSettings
+ public class Settings : CommandSettings
{
- readonly IFileSystem _fileSystem = fileSystem;
-
[CommandArgument(1, "")]
[Description("The provider to remove.")]
public string Provider { get; init; } = string.Empty;
-
- public string SettingsPath => _fileSystem.Path.Combine(AppContext.BaseDirectory, AppSettings.SettingsFileName);
}
public override async Task ExecuteAsync(CommandContext context, Settings settings)
{
- var exists = _fileSystem.Path.Exists(settings.SettingsPath);
-
- if (exists is false)
+ if (_settingsManager.AppSettingsExist() is false)
{
throw new ConfigException("No existing settings found.");
}
- var settingsJson = await _fileSystem.File.ReadAllTextAsync(settings.SettingsPath);
- var appSettings = JsonSerializer.Deserialize(settingsJson, JsonOptions.Default)
- ?? throw new ConfigException("Failed to deserialize app settings.");
+ var appSettings = await _settingsManager.GetAppSettingsAsync();
var updatedAppSettings = appSettings.RemoveProvider(settings);
- var updatedJson = JsonSerializer.Serialize(updatedAppSettings, JsonOptions.Default);
- await _fileSystem.File.WriteAllTextAsync(settings.SettingsPath, updatedJson);
+ await _settingsManager.SaveAppSettingsAsync(updatedAppSettings);
_console.MarkupLine($"[bold]{settings.Provider}[/] has been removed.");
return 0;
}
diff --git a/src/AltGen.Console/Generate/IAltGenService.cs b/src/AltGen.Console/Generate/IAltGenService.cs
index 1b2b14b..81101a0 100644
--- a/src/AltGen.Console/Generate/IAltGenService.cs
+++ b/src/AltGen.Console/Generate/IAltGenService.cs
@@ -1,4 +1,4 @@
interface IAltGenService
{
Task GenerateAltTextAsync(GenerateAltTextRequest req);
-}
+}
\ No newline at end of file
diff --git a/src/AltGen.Console/Program.cs b/src/AltGen.Console/Program.cs
index 48aaed7..cc4380e 100644
--- a/src/AltGen.Console/Program.cs
+++ b/src/AltGen.Console/Program.cs
@@ -3,6 +3,7 @@
.ConfigureServices(static (_, services) =>
{
services.AddSingleton();
+ services.AddSingleton();
services.AddSingleton(AnsiConsole.Console);
services.AddHttpClient()
.AddStandardResilienceHandler();