2023-06-26 11:58:41 +00:00
|
|
|
|
using System.Reflection;
|
|
|
|
|
|
|
|
|
|
namespace ArgsUniform
|
|
|
|
|
{
|
|
|
|
|
public class ArgsUniform<T>
|
|
|
|
|
{
|
2024-05-16 10:14:03 +00:00
|
|
|
|
private readonly Assigner<T> assigner;
|
2023-06-30 07:09:59 +00:00
|
|
|
|
private readonly Action printAppInfo;
|
2023-06-26 11:58:41 +00:00
|
|
|
|
private readonly string[] args;
|
|
|
|
|
private const int cliStart = 8;
|
|
|
|
|
private const int shortStart = 38;
|
|
|
|
|
private const int envStart = 48;
|
|
|
|
|
private const int descStart = 80;
|
|
|
|
|
|
2023-06-30 07:09:59 +00:00
|
|
|
|
public ArgsUniform(Action printAppInfo, params string[] args)
|
|
|
|
|
: this(printAppInfo, new IEnv.Env(), args)
|
2023-06-26 11:58:41 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-30 07:09:59 +00:00
|
|
|
|
public ArgsUniform(Action printAppInfo, object defaultsProvider, params string[] args)
|
|
|
|
|
: this(printAppInfo, defaultsProvider, new IEnv.Env(), args)
|
2023-06-26 11:58:41 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-30 07:09:59 +00:00
|
|
|
|
public ArgsUniform(Action printAppInfo, IEnv.IEnv env, params string[] args)
|
|
|
|
|
: this(printAppInfo, null!, env, args)
|
2023-06-26 11:58:41 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-30 07:09:59 +00:00
|
|
|
|
public ArgsUniform(Action printAppInfo, object defaultsProvider, IEnv.IEnv env, params string[] args)
|
2023-06-26 11:58:41 +00:00
|
|
|
|
{
|
2023-06-30 07:09:59 +00:00
|
|
|
|
this.printAppInfo = printAppInfo;
|
2023-06-26 11:58:41 +00:00
|
|
|
|
this.args = args;
|
2024-05-16 10:14:03 +00:00
|
|
|
|
|
|
|
|
|
assigner = new Assigner<T>(env, args, defaultsProvider);
|
2023-06-26 11:58:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public T Parse(bool printResult = false)
|
|
|
|
|
{
|
2023-06-30 07:09:59 +00:00
|
|
|
|
if (args.Any(a => a == "-h" || a == "--help" || a == "-?"))
|
|
|
|
|
{
|
|
|
|
|
printAppInfo();
|
|
|
|
|
PrintHelp();
|
2024-05-16 09:54:31 +00:00
|
|
|
|
Environment.Exit(0);
|
2023-06-30 07:09:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-06-26 11:58:41 +00:00
|
|
|
|
var result = Activator.CreateInstance<T>();
|
|
|
|
|
var uniformProperties = typeof(T).GetProperties().Where(m => m.GetCustomAttributes(typeof(UniformAttribute), false).Length == 1).ToArray();
|
|
|
|
|
var missingRequired = new List<PropertyInfo>();
|
|
|
|
|
foreach (var uniformProperty in uniformProperties)
|
|
|
|
|
{
|
|
|
|
|
var attr = uniformProperty.GetCustomAttribute<UniformAttribute>();
|
|
|
|
|
if (attr != null)
|
|
|
|
|
{
|
2024-05-16 10:14:03 +00:00
|
|
|
|
if (!assigner.UniformAssign(result, attr, uniformProperty) && attr.Required)
|
2023-06-26 11:58:41 +00:00
|
|
|
|
{
|
2024-05-16 09:54:31 +00:00
|
|
|
|
missingRequired.Add(uniformProperty);
|
2023-06-26 11:58:41 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (missingRequired.Any())
|
|
|
|
|
{
|
2024-05-16 12:05:58 +00:00
|
|
|
|
PrintResults(printResult,result, uniformProperties);
|
2023-06-26 11:58:41 +00:00
|
|
|
|
Print("");
|
|
|
|
|
foreach (var missing in missingRequired)
|
|
|
|
|
{
|
|
|
|
|
var attr = missing.GetCustomAttribute<UniformAttribute>()!;
|
|
|
|
|
var exampleArg = $"--{attr.Arg}=...";
|
|
|
|
|
var exampleEnvVar = $"{attr.EnvVar}=...";
|
|
|
|
|
Print($" ! Missing required input. Use argument: '{exampleArg}' or environment variable: '{exampleEnvVar}'.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PrintHelp();
|
2024-05-16 09:54:31 +00:00
|
|
|
|
Environment.Exit(1);
|
2023-06-26 11:58:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-05-16 12:05:58 +00:00
|
|
|
|
PrintResults(printResult, result, uniformProperties);
|
2023-06-26 11:58:41 +00:00
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-16 12:05:58 +00:00
|
|
|
|
public void PrintHelp()
|
2023-06-26 12:44:21 +00:00
|
|
|
|
{
|
|
|
|
|
Print("");
|
2024-05-16 12:05:58 +00:00
|
|
|
|
PrintAligned("CLI option:", "(short)", "Environment variable:", "Description", "(default)");
|
|
|
|
|
var props = typeof(T).GetProperties().Where(m => m.GetCustomAttributes(typeof(UniformAttribute), false).Length == 1).ToArray();
|
|
|
|
|
foreach (var prop in props)
|
2023-06-26 12:44:21 +00:00
|
|
|
|
{
|
2024-05-16 12:05:58 +00:00
|
|
|
|
var a = prop.GetCustomAttribute<UniformAttribute>();
|
|
|
|
|
if (a != null)
|
|
|
|
|
{
|
|
|
|
|
var optional = !a.Required ? " (optional)" : "";
|
|
|
|
|
var def = assigner.DescribeDefaultFor(prop);
|
|
|
|
|
PrintAligned($"--{a.Arg}=...", $"({a.ArgShort})", a.EnvVar, a.Description + optional, $"({def})");
|
|
|
|
|
}
|
2023-06-26 12:44:21 +00:00
|
|
|
|
}
|
|
|
|
|
Print("");
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-16 12:05:58 +00:00
|
|
|
|
private void PrintResults(bool printResult, T result, PropertyInfo[] uniformProperties)
|
2023-06-26 11:58:41 +00:00
|
|
|
|
{
|
2024-05-16 12:05:58 +00:00
|
|
|
|
if (!printResult) return;
|
2023-06-26 11:58:41 +00:00
|
|
|
|
Print("");
|
2024-05-16 12:05:58 +00:00
|
|
|
|
foreach (var p in uniformProperties)
|
2023-06-26 11:58:41 +00:00
|
|
|
|
{
|
2024-05-16 12:05:58 +00:00
|
|
|
|
Print($"\t{p.Name} = {p.GetValue(result)}");
|
2023-06-26 11:58:41 +00:00
|
|
|
|
}
|
|
|
|
|
Print("");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Print(string msg)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine(msg);
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-16 12:05:58 +00:00
|
|
|
|
private void PrintAligned(string cli, string s, string env, string desc, string def)
|
2023-06-26 11:58:41 +00:00
|
|
|
|
{
|
|
|
|
|
Console.CursorLeft = cliStart;
|
|
|
|
|
Console.Write(cli);
|
|
|
|
|
Console.CursorLeft = shortStart;
|
|
|
|
|
Console.Write(s);
|
|
|
|
|
Console.CursorLeft = envStart;
|
|
|
|
|
Console.Write(env);
|
|
|
|
|
Console.CursorLeft = descStart;
|
2024-05-16 12:05:58 +00:00
|
|
|
|
Console.Write(desc + " ");
|
|
|
|
|
Console.Write(def + Environment.NewLine);
|
2023-06-26 11:58:41 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|