Files
Libation/Source/LibationCli/Options/GetSettingOptions.cs
MBucari ce2b81036f Add license and settings overrides to LibationCli
- Add `LIBATION_FILES_DIR` environment variable to specify LibationFiles directory instead of appsettings.json
- OptionsBase supports overriding setting
  - Added `EphemeralSettings` which are loaded from Settings.json once and can be modified with the `--override` command parameter
- Added `get-setting` command
  - Prints (editable) settings and their values. Prints specified settings, or all settings if none specified
  - `--listEnumValues` option will list all names for a speficied enum-type settings. If no setting names are specified, prints all enum values for all enum settings.
  - Prints in a text-based table or bare with `-b` switch
- Added `get-license` command which requests a content license and prints it as a json to stdout
- Improved `liberate` command
  - Added `-force` option to force liberation without validation.
  - Added support to download with a license file supplied to stdin
  - Improve startup performance when downloading explicit ASIN(s)
  - Fix long-standing bug where cover art was not being downloading
2025-11-19 23:47:41 -07:00

141 lines
3.9 KiB
C#

using CommandLine;
using Dinah.Core;
using FileManager;
using LibationFileManager;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
#nullable enable
namespace LibationCli.Options;
[Verb("get-setting", HelpText = "List current settings files and their locations.")]
internal class GetSettingOptions : OptionsBase
{
[Option('l', "listEnumValues", HelpText = "List all value possibilities of enum types")]
public bool ListEnumValues { get; set; }
[Option('b', "bare", HelpText = "Print bare list without table decoration")]
public bool Bare { get; set; }
[Value(0, MetaName = "[setting names]", HelpText = "Optional names of settings to get.")]
public IEnumerable<string>? SettingNames { get; set; }
protected override Task ProcessAsync()
{
var configs = GetConfigOptions();
if (SettingNames?.Any() is true)
{
//Operate over listed settings
foreach (var item in SettingNames.ExceptBy(configs.Select(c => c.Name), c => c, StringComparer.OrdinalIgnoreCase))
{
Console.Error.WriteLine($"Unknown Setting Name: {item}");
}
var validSettings = configs.IntersectBy(SettingNames, a => a.Name, StringComparer.OrdinalIgnoreCase);
if (ListEnumValues)
{
foreach (var item in validSettings.Where(s => !s.SettingType.IsEnum))
{
Console.Error.WriteLine($"Setting '{item.Name}' is not an enum type");
}
PrintEnumValues(validSettings.Where(s => s.SettingType.IsEnum));
}
else
{
PrintConfigOption(validSettings);
}
}
else
{
//Operate over all settings
if (ListEnumValues)
{
PrintEnumValues(configs);
}
else
{
PrintConfigOption(configs);
}
}
return Task.CompletedTask;
}
private void PrintConfigOption(IEnumerable<ConfigOption> options)
{
if (Bare)
{
foreach (var option in options)
{
Console.WriteLine($"{option.Name}={option.Value}");
}
}
else
{
Console.Out.DrawTable(options, new(), o => o.Name, o => o.Value, o => o.Type);
}
}
private void PrintEnumValues(IEnumerable<ConfigOption> options)
{
foreach (var item in options.Where(s => s.SettingType.IsEnum))
{
var enumValues = Enum.GetNames(item.SettingType);
if (Bare)
{
Console.WriteLine(string.Join(Environment.NewLine, enumValues.Select(e => $"{item.Name}.{e}")));
}
else
{
Console.Out.DrawTable(enumValues, new TextTableOptions(), new ColumnDef<string>(item.Name, t => t));
}
}
}
private ConfigOption[] GetConfigOptions()
{
var configs = GetConfigurationProperties().Where(o=> o.PropertyType != typeof(ReplacementCharacters)).Select(p => new ConfigOption(p));
var replacements = GetConfigurationProperties().SingleOrDefault(o => o.PropertyType == typeof(ReplacementCharacters))?.GetValue(Configuration.Instance) as ReplacementCharacters;
if (replacements is not null)
{
//Don't reorder after concat to keep replacements grouped together at the bottom
configs = configs.Concat(replacements.Replacements.Select(r => new ConfigOption(r)));
}
return configs.ToArray();
}
private record EnumOption(string EnumOptionValue);
private record ConfigOption
{
public string Name { get; }
public string Type { get; }
public Type SettingType { get; }
public string Value { get; }
public ConfigOption(PropertyInfo propertyInfo)
{
Name = propertyInfo.Name;
SettingType = propertyInfo.PropertyType;
Type = GetTypeString(SettingType);
Value = propertyInfo.GetValue(Configuration.Instance)?.ToString() is not string value ? "[null]"
: SettingType == typeof(string) || SettingType == typeof(LongPath) ? value.SurroundWithQuotes()
: value;
}
public ConfigOption(Replacement replacement)
{
Name = GetReplacementName(replacement);
SettingType = typeof(string);
Type = GetTypeString(SettingType);
Value = replacement.ReplacementString.SurroundWithQuotes();
}
private static string GetTypeString(Type type)
=> type.IsEnum ? $"{type.Name} (enum)": type.Name;
}
}