feat: initial cli implementation
This commit is contained in:
+51
@@ -0,0 +1,51 @@
|
||||
using System.CommandLine;
|
||||
|
||||
using StevanFreeborn.Extensions.Configuration.Secure.Configuration;
|
||||
|
||||
namespace StevanFreeborn.Extensions.Configuration.Secure.Cli.Commands;
|
||||
|
||||
internal sealed class DeleteCommandFactory(
|
||||
ISecureConfig secureConfig,
|
||||
ITerminal terminal
|
||||
) : ICommandFactory
|
||||
{
|
||||
private const string CommandName = "delete";
|
||||
private const string CommandDescription = "Delete the value for the given key";
|
||||
|
||||
private readonly Argument<string> _keyArg = new("key")
|
||||
{
|
||||
Description = "The key whose value you want to remove."
|
||||
};
|
||||
|
||||
private readonly ISecureConfig _secureConfig = secureConfig;
|
||||
private readonly ITerminal _terminal = terminal;
|
||||
|
||||
public Command Create()
|
||||
{
|
||||
var command = new Command(CommandName, CommandDescription)
|
||||
{
|
||||
_keyArg,
|
||||
};
|
||||
|
||||
command.SetAction(HandleAsync);
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
private async Task<int> HandleAsync(ParseResult result, CancellationToken ct)
|
||||
{
|
||||
var key = result.GetRequiredValue(_keyArg);
|
||||
var isDeleted = await _secureConfig.DeleteAsync(key, ct);
|
||||
|
||||
if (isDeleted)
|
||||
{
|
||||
_terminal.WriteLine($"Successfully removed value for {key}");
|
||||
return ExitCodes.Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
_terminal.WriteLine($"Unable to remove value for {key}");
|
||||
return ExitCodes.KeyNotRemoved;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace StevanFreeborn.Extensions.Configuration.Secure.Cli.Commands;
|
||||
|
||||
internal static class ExitCodes
|
||||
{
|
||||
public const int Success = 0;
|
||||
public const int KeyNotFound = 1;
|
||||
public const int KeyNotRemoved = 2;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using System.CommandLine;
|
||||
using System.Text.Json;
|
||||
|
||||
using StevanFreeborn.Extensions.Configuration.Secure.Cli.Json;
|
||||
using StevanFreeborn.Extensions.Configuration.Secure.Configuration;
|
||||
|
||||
namespace StevanFreeborn.Extensions.Configuration.Secure.Cli.Commands;
|
||||
|
||||
internal sealed class GetCommandFactory(
|
||||
ISecureConfig secureConfig,
|
||||
ITerminal terminal
|
||||
) : ICommandFactory
|
||||
{
|
||||
private const string CommandName = "get";
|
||||
private const string CommandDescription = "Retrieves the value for the given key";
|
||||
|
||||
private readonly Argument<string> _keyArg = new("key")
|
||||
{
|
||||
Description = "The key whose value you want to retrieve."
|
||||
};
|
||||
|
||||
private readonly Option<bool> _prettyOption = new("--pretty", "-p")
|
||||
{
|
||||
Description = "Indicates whether the value - if JSON - should be pretty printed or not"
|
||||
};
|
||||
|
||||
private readonly ISecureConfig _secureConfig = secureConfig;
|
||||
private readonly ITerminal _terminal = terminal;
|
||||
|
||||
public Command Create()
|
||||
{
|
||||
var command = new Command(CommandName, CommandDescription)
|
||||
{
|
||||
_keyArg,
|
||||
_prettyOption
|
||||
};
|
||||
|
||||
command.SetAction(HandleAsync);
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
private async Task<int> HandleAsync(ParseResult result, CancellationToken ct)
|
||||
{
|
||||
var key = result.GetRequiredValue(_keyArg);
|
||||
var shouldPrintPretty = result.GetValue(_prettyOption);
|
||||
var value = await _secureConfig.GetAsync<string>(key, ct);
|
||||
|
||||
if (value is null)
|
||||
{
|
||||
_terminal.WriteLine($"Unable to retrieve value for {key}");
|
||||
return ExitCodes.KeyNotFound;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using var json = JsonDocument.Parse(value);
|
||||
|
||||
if (shouldPrintPretty)
|
||||
{
|
||||
var options = new JsonSerializerOptions()
|
||||
{
|
||||
WriteIndented = true,
|
||||
};
|
||||
var context = new CliJsonContext(options);
|
||||
value = JsonSerializer.Serialize(json.RootElement, context.JsonElement);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = JsonSerializer.Serialize(json.RootElement, CliJsonContext.Default.JsonElement);
|
||||
}
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
}
|
||||
|
||||
_terminal.WriteLine(value);
|
||||
return ExitCodes.Success;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using System.CommandLine;
|
||||
|
||||
namespace StevanFreeborn.Extensions.Configuration.Secure.Cli.Commands;
|
||||
|
||||
internal interface ICommandFactory
|
||||
{
|
||||
Command Create();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace StevanFreeborn.Extensions.Configuration.Secure.Cli.Commands;
|
||||
|
||||
internal interface ITerminal
|
||||
{
|
||||
public void WriteLine(string value);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
|
||||
using System.CommandLine;
|
||||
using System.Text.Json;
|
||||
|
||||
using StevanFreeborn.Extensions.Configuration.Secure.Cli.Json;
|
||||
using StevanFreeborn.Extensions.Configuration.Secure.Configuration;
|
||||
|
||||
namespace StevanFreeborn.Extensions.Configuration.Secure.Cli.Commands;
|
||||
|
||||
internal sealed class SetCommandFactory(
|
||||
ISecureConfig secureConfig,
|
||||
ITerminal terminal
|
||||
) : ICommandFactory
|
||||
{
|
||||
private const string CommandName = "set";
|
||||
private const string CommandDescription = "Sets the value for the given key";
|
||||
|
||||
private readonly Argument<string> _keyArg = new("key")
|
||||
{
|
||||
Description = "The key whose value you want to set."
|
||||
};
|
||||
|
||||
private readonly Argument<string> _valueArg = new("value")
|
||||
{
|
||||
Description = "The value that you want to set for the key."
|
||||
};
|
||||
|
||||
private readonly ISecureConfig _secureConfig = secureConfig;
|
||||
private readonly ITerminal _terminal = terminal;
|
||||
|
||||
public Command Create()
|
||||
{
|
||||
var command = new Command(CommandName, CommandDescription)
|
||||
{
|
||||
_keyArg,
|
||||
_valueArg,
|
||||
};
|
||||
|
||||
command.SetAction(HandleAsync);
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
private async Task<int> HandleAsync(ParseResult result, CancellationToken ct)
|
||||
{
|
||||
var key = result.GetRequiredValue(_keyArg);
|
||||
var value = result.GetRequiredValue(_valueArg);
|
||||
|
||||
try
|
||||
{
|
||||
using var json = JsonDocument.Parse(value);
|
||||
value = JsonSerializer.Serialize(json.RootElement, CliJsonContext.Default.JsonElement);
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
}
|
||||
|
||||
await _secureConfig.SetAsync(key, value, ct);
|
||||
|
||||
_terminal.WriteLine($"Successfully set value of {key}");
|
||||
return ExitCodes.Success;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace StevanFreeborn.Extensions.Configuration.Secure.Cli.Commands;
|
||||
|
||||
internal sealed class Terminal : ITerminal
|
||||
{
|
||||
public void WriteLine(string value)
|
||||
{
|
||||
Console.WriteLine(value);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user