This repository has been archived on 2023-02-02. You can view files and clone it, but cannot push or open issues or pull requests.
mfgames-toolbuilder-cil/src/MfGames.ToolBuilder/ConfigToolService.cs
Dylan R. E. Moonfire ad0525be04 feat: initial commit
2021-09-10 12:33:42 -05:00

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;
}
}
}