cli/Program.cs

115 lines
3.5 KiB
C#

namespace Automancer;
using System;
using System.Linq;
using System.Threading.Tasks;
using Automancer.Common;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Spectre.Console.Cli;
using Automancer.Commands;
using System.Reflection;
public abstract class Program
{
public static async Task<int> Main(string[] args)
{
CommandApp? app = null;
var host = Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddConsole();
logging.SetMinimumLevel(LogLevel.Information);
})
.ConfigureAppConfiguration((hostingContext, config) => {
var env = hostingContext.HostingEnvironment;
config.SetBasePath(AppContext.BaseDirectory)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables(prefix: "AUTOMANCER_")
.AddCommandLine(args);
})
.ConfigureServices((context, services) =>
{
var registry = new CommandRegistry();
services.AddSingleton(registry);
LoadPluginAssemblies("plugins");
RegisterCommandModules(services);
var registrar = new TypeRegistrar(services);
app = new CommandApp(registrar);
app.SetDefaultCommand<RootCommand>();
var provider = services.BuildServiceProvider();
app.Configure(config =>
{
config.SetApplicationName("automancer");
var modules = provider.GetServices<ICommandModule>();
var registry = provider.GetRequiredService<CommandRegistry>();
foreach (var module in modules)
{
module.Configure(config, registry);
}
});
})
.Build();
return app != null ? await app.RunAsync(args) : 1;
}
private static void RegisterCommandModules(IServiceCollection services)
{
var moduleType = typeof(ICommandModule);
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
var moduleTypes = assemblies
.SelectMany(a =>
{
try { return a.GetTypes(); }
catch {
return [];
}
})
.Where(t => moduleType.IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract)
.ToList();
foreach (var type in moduleTypes)
{
services.AddSingleton(type);
services.AddSingleton(typeof(ICommandModule), type);
}
}
private static void LoadPluginAssemblies(string pluginDirectory)
{
if (!Directory.Exists(pluginDirectory))
return;
var dlls = Directory.GetFiles(pluginDirectory, "*.dll", SearchOption.AllDirectories);
foreach (var dll in dlls)
{
try
{
var asm = Assembly.LoadFrom(dll);
}
catch (Exception ex)
{
Console.WriteLine($"[WARN] Failed to load plugin '{dll}': {ex.Message}");
}
}
}
}