-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add SKonsole configuration command and Spectre.Console package
Summary: This pull request updates the SKonsole project with the addition of a new configuration command and the Spectre.Console package. The new "config" command allows users to manage configuration settings for the application, including getting and setting specific configuration keys. The configuration values are stored in a file named ".skonsole". Additionally, the Spectre.Console package is added as a new package reference to enhance the user interface with interactive prompts and colored output. Changes: - Added a new command, "config", to the SKonsole application. - Implemented subcommands for getting and setting configuration values. - Created a ConfigurationProvider class to handle reading and writing configuration values. - Added a new file, "ConfigCommand.cs", to handle the "config" command logic. - Added a new file, "ConfigurationProvider.cs", to handle reading and writing configuration values. - Modified the "Program.cs" file to include the new "config" command and its subcommands. - Updated the "ConfigCommand.cs" file to handle getting and setting configuration values. - Updated the "Program.cs" file to use the ConfigurationProvider class to get and set configuration values. - Added validation and error handling for empty configuration values. - Updated the "Program.cs" file to use the Spectre.Console library for interactive prompts and colored output. Note: This pull request focuses on adding the new "config" command and its related functionality, as well as integrating the Spectre.Console package for improved user interface. Other changes in the diff are related to existing functionality and are not directly related to the new command. Co-authored-by: xbotter <xbotter@users.noreply.github.com>
- Loading branch information
Showing
4 changed files
with
193 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
using Newtonsoft.Json.Linq; | ||
using Spectre.Console; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.CommandLine; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace SKonsole.Commands | ||
{ | ||
public class ConfigCommand : Command | ||
{ | ||
private readonly ConfigurationProvider _config; | ||
|
||
public ConfigCommand(ConfigurationProvider config) : base("config", "skonsole configuration") | ||
{ | ||
this._config = config; | ||
Add(ConfigGetCommand()); | ||
Add(ConfigSetCommand()); | ||
|
||
this.SetHandler(async context => await RunConfigAsync(context.GetCancellationToken())); | ||
} | ||
|
||
Command ConfigGetCommand() | ||
{ | ||
var keyArgument = new Argument<string>("key", "configuration key"); | ||
|
||
var getCommand = new Command("get", "get configuration value"); | ||
|
||
getCommand.AddArgument(keyArgument); | ||
|
||
getCommand.SetHandler((key) => | ||
{ | ||
var value = _config.Get(key); | ||
if (value == null) | ||
{ | ||
AnsiConsole.MarkupLine($"[red]Configuration key '{key}' not found.[/]"); | ||
} | ||
else | ||
{ | ||
AnsiConsole.MarkupLine($"[green]{key}[/]: {value}"); | ||
} | ||
}, keyArgument); | ||
return getCommand; | ||
} | ||
|
||
|
||
Command ConfigSetCommand() | ||
{ | ||
var keyArgument = new Argument<string>("key", "configuration key"); | ||
var valueArgument = new Argument<string>("value", "configuration value"); | ||
|
||
var setCommand = new Command("set", "set configuration value"); | ||
setCommand.AddArgument(keyArgument); | ||
setCommand.AddArgument(valueArgument); | ||
|
||
setCommand.SetHandler(_config.SaveConfig, keyArgument, valueArgument); | ||
return setCommand; | ||
} | ||
|
||
static async Task RunConfigAsync(CancellationToken token) | ||
{ | ||
while (!token.IsCancellationRequested) | ||
{ | ||
var keys = new[] | ||
{ | ||
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME", | ||
"AZURE_OPENAI_API_ENDPOINT", | ||
"AZURE_OPENAI_API_KEY" | ||
}; | ||
|
||
var config = new ConfigurationProvider(); | ||
var configKey = await new SelectionPrompt<string>() | ||
.Title("Select key to config:") | ||
.AddChoices(keys) | ||
.ShowAsync(AnsiConsole.Console, token); | ||
|
||
var currentValue = config.Get(configKey); | ||
|
||
var value = await new TextPrompt<string>($"Set value for [green]{configKey}[/]") | ||
.DefaultValue(currentValue ?? string.Empty) | ||
.HideDefaultValue() | ||
.Validate((value) => | ||
{ | ||
if (string.IsNullOrWhiteSpace(value)) | ||
{ | ||
return ValidationResult.Error("[red]Value cannot be empty[/]"); | ||
} | ||
return ValidationResult.Success(); | ||
}) | ||
.AllowEmpty() | ||
.ShowAsync(AnsiConsole.Console, token); | ||
if (!string.IsNullOrWhiteSpace(value)) | ||
{ | ||
await config.SaveConfig(configKey, value.Trim()); | ||
} | ||
} | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
using Microsoft.Extensions.Configuration; | ||
using System.Text.Json; | ||
|
||
public class ConfigurationProvider | ||
{ | ||
public static ConfigurationProvider Instance = new(); | ||
|
||
const string _file = ".skonsole"; | ||
|
||
private readonly string _path; | ||
private readonly IConfiguration _configuration; | ||
private readonly Dictionary<string, string?> _config = new(); | ||
|
||
public ConfigurationProvider() | ||
{ | ||
var userProfile = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); | ||
_path = Path.Combine(userProfile, _file); | ||
|
||
if (File.Exists(_path)) | ||
{ | ||
_config = FromJson<Dictionary<string, string?>>(File.ReadAllText(_path)) ?? new(); | ||
} | ||
|
||
_configuration = new ConfigurationBuilder() | ||
.AddEnvironmentVariables() | ||
.AddInMemoryCollection(_config) | ||
.Build(); | ||
} | ||
|
||
public async Task SaveConfig(string key, string value) | ||
{ | ||
_config[key] = value; | ||
|
||
await File.WriteAllTextAsync(_path, ToJson(_config)); | ||
} | ||
|
||
public string? Get(string key) | ||
{ | ||
return _configuration[key]; | ||
} | ||
|
||
private static string ToJson<T>(T obj) | ||
{ | ||
return JsonSerializer.Serialize(obj); | ||
} | ||
|
||
private static T? FromJson<T>(string json) | ||
{ | ||
if (json == null) | ||
return default; | ||
try | ||
{ | ||
return JsonSerializer.Deserialize<T>(json); | ||
} | ||
catch | ||
{ | ||
return default; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters