127 lines
4.2 KiB
C#
127 lines
4.2 KiB
C#
using System;
|
|
using System.CommandLine;
|
|
using System.IO;
|
|
|
|
using Microsoft.Extensions.Configuration;
|
|
|
|
namespace MfGames.ToolBuilder
|
|
{
|
|
/// <summary>
|
|
/// A utility class for handling `--config` options.
|
|
/// </summary>
|
|
public class ConfigToolService
|
|
{
|
|
public ConfigToolService()
|
|
{
|
|
this.ConfigOption = new Option<string[]>(
|
|
"--config",
|
|
"Configuration file to use for settings, otherwise a default will be used.",
|
|
ArgumentArity.OneOrMore)
|
|
{
|
|
AllowMultipleArgumentsPerToken = false,
|
|
};
|
|
|
|
this.ConfigOption.AddAlias("-c");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the common option for setting configuration files.
|
|
/// </summary>
|
|
public Option<string[]> ConfigOption { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the default configuration file.
|
|
/// </summary>
|
|
public FileInfo DefaultConfigFile => new(this.DefaultConfigPath);
|
|
|
|
/// <summary>
|
|
/// Gets the default configuration path.
|
|
/// </summary>
|
|
public string DefaultConfigPath
|
|
{
|
|
get
|
|
{
|
|
// If we don't have an internal name, blow up.
|
|
string? internalName = this.InternalName;
|
|
|
|
if (internalName == null)
|
|
{
|
|
throw new ApplicationException(
|
|
"Cannot determine the default configuration path unless internal name has been set.");
|
|
}
|
|
|
|
// Figure out the path to the default configuration. This is
|
|
// something like:
|
|
// $HOME/.config/ApplicationName/Settings.json
|
|
string configDirectory = Environment
|
|
.GetFolderPath(Environment.SpecialFolder.ApplicationData);
|
|
string appDirectory = Path.Combine(
|
|
configDirectory,
|
|
internalName);
|
|
string configPath = Path.Combine(appDirectory, "Settings.json");
|
|
|
|
return configPath;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the name of the application. This is used to figure out
|
|
/// the name of the configuration file and what is shown on the screen.
|
|
/// </summary>
|
|
public string? InternalName { get; set; }
|
|
|
|
/// <summary>
|
|
/// Adds the common options to the command.
|
|
/// </summary>
|
|
/// <param name="root"></param>
|
|
public void AddOptions(RootCommand root)
|
|
{
|
|
root.AddGlobalOption(this.ConfigOption);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets up logging based on the global settings.
|
|
/// </summary>
|
|
/// <param name="builder">The configuration builder to use.</param>
|
|
/// <param name="arguments">The arguments to the command.</param>
|
|
public void Configure(IConfigurationBuilder builder, string[] arguments)
|
|
{
|
|
// In general, we don't use a local AppSettings.json automatically
|
|
// but prefer configuration in the $HOME/.config folder instead.
|
|
// However, if the user gives a configuration setting, we use that
|
|
// no matter where we want to put it.
|
|
string[] configs = GlobalOptionHelper.GetArgumentValue(
|
|
this.ConfigOption,
|
|
arguments,
|
|
Array.Empty<string>());
|
|
|
|
// If we don't have anything, then use the default.
|
|
if (configs.Length == 0)
|
|
{
|
|
builder.AddJsonFile(this.DefaultConfigPath, true, true);
|
|
return;
|
|
}
|
|
|
|
// Otherwise, use the default files.
|
|
foreach (var config in configs)
|
|
{
|
|
builder.AddJsonFile(config, true, true);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the internal name of the application, used for the
|
|
/// configuration path.
|
|
/// </summary>
|
|
/// <param name="internalName">
|
|
/// The internal name of the application.
|
|
/// </param>
|
|
/// <returns>The service for chaining operations.</returns>
|
|
public ConfigToolService WithInternalName(string internalName)
|
|
{
|
|
this.InternalName = internalName;
|
|
return this;
|
|
}
|
|
}
|
|
}
|