2021-09-10 17:33:42 +00:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.CommandLine;
|
|
|
|
using System.CommandLine.Builder;
|
|
|
|
using System.CommandLine.Invocation;
|
|
|
|
using System.CommandLine.Parsing;
|
|
|
|
using System.Threading;
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
2021-09-11 05:42:04 +00:00
|
|
|
using MfGames.ToolBuilder.Globals;
|
|
|
|
|
2021-09-10 17:33:42 +00:00
|
|
|
using Microsoft.Extensions.Hosting;
|
|
|
|
|
|
|
|
using Serilog;
|
|
|
|
|
|
|
|
#pragma warning disable Serilog004
|
|
|
|
|
|
|
|
// ReSharper disable TemplateIsNotCompileTimeConstantProblem
|
|
|
|
// ReSharper disable SuspiciousTypeConversion.Global
|
|
|
|
|
|
|
|
namespace MfGames.ToolBuilder
|
|
|
|
{
|
|
|
|
/// <summary>
|
|
|
|
/// Implements the command-line shell for generating the static site.
|
|
|
|
/// </summary>
|
|
|
|
public class ToolService : IHostedService
|
|
|
|
{
|
|
|
|
private readonly IList<ITopCommand> commands;
|
|
|
|
|
2021-09-11 05:42:04 +00:00
|
|
|
private readonly ConfigToolGlobalService configService;
|
2021-09-10 17:33:42 +00:00
|
|
|
|
|
|
|
private readonly IHostApplicationLifetime lifetime;
|
|
|
|
|
|
|
|
private readonly ILogger logger;
|
|
|
|
|
2021-09-11 05:42:04 +00:00
|
|
|
private readonly LoggingToolGlobalService loggingService;
|
2021-09-10 17:33:42 +00:00
|
|
|
|
|
|
|
public ToolService(
|
|
|
|
ILogger logger,
|
|
|
|
IHostApplicationLifetime lifetime,
|
|
|
|
IList<ITopCommand> commands,
|
2021-09-11 05:42:04 +00:00
|
|
|
ConfigToolGlobalService configService,
|
|
|
|
LoggingToolGlobalService loggingService)
|
2021-09-10 17:33:42 +00:00
|
|
|
{
|
|
|
|
this.lifetime = lifetime;
|
|
|
|
this.commands = commands;
|
|
|
|
this.configService = configService;
|
|
|
|
this.loggingService = loggingService;
|
|
|
|
this.logger = logger.ForContext<ToolService>();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
public Task StartAsync(CancellationToken cancellationToken)
|
|
|
|
{
|
|
|
|
this.lifetime.ApplicationStarted
|
|
|
|
.Register(
|
|
|
|
() =>
|
|
|
|
{
|
|
|
|
Task.Run(
|
|
|
|
async () =>
|
|
|
|
await this.RunAsync().ConfigureAwait(false),
|
|
|
|
cancellationToken);
|
|
|
|
});
|
|
|
|
|
|
|
|
return Task.CompletedTask;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
public Task StopAsync(CancellationToken cancellationToken)
|
|
|
|
{
|
|
|
|
return Task.CompletedTask;
|
|
|
|
}
|
|
|
|
|
|
|
|
private RootCommand CreateRootCommand()
|
|
|
|
{
|
|
|
|
// Create the root command and add in the top-level commands
|
|
|
|
// underneath it.
|
|
|
|
var root = new RootCommand();
|
|
|
|
|
|
|
|
foreach (var command in this.commands)
|
|
|
|
{
|
|
|
|
root.AddCommand((Command)command);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add the universal options.
|
|
|
|
this.loggingService.AddOptions(root);
|
|
|
|
this.configService.AddOptions(root);
|
|
|
|
|
|
|
|
// Return the resulting container.
|
|
|
|
return root;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void OnException(Exception exception, InvocationContext context)
|
|
|
|
{
|
|
|
|
if (exception is ToolException toolException)
|
|
|
|
{
|
|
|
|
this.logger.Fatal(toolException.Message);
|
|
|
|
|
|
|
|
foreach (var message in toolException.Messages)
|
|
|
|
{
|
|
|
|
this.logger.Fatal(message);
|
|
|
|
}
|
|
|
|
|
|
|
|
Environment.ExitCode = toolException.ExitCode;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.logger.Fatal(
|
|
|
|
exception,
|
|
|
|
"Unhandled exception!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private async Task RunAsync()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
// Build the command tree.
|
|
|
|
RootCommand root = this.CreateRootCommand();
|
|
|
|
string[] args = Environment.GetCommandLineArgs();
|
|
|
|
|
|
|
|
// Execute the command.
|
|
|
|
this.logger.Verbose(
|
|
|
|
"Running the command-line arguments: {Arguments}",
|
|
|
|
args);
|
|
|
|
|
|
|
|
Environment.ExitCode = await new CommandLineBuilder(root)
|
|
|
|
.UseDefaults()
|
|
|
|
.UseExceptionHandler(this.OnException)
|
|
|
|
.Build()
|
|
|
|
.InvokeAsync(args)
|
|
|
|
.ConfigureAwait(false);
|
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
// Stop the application once the work is done.
|
|
|
|
this.lifetime.StopApplication();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|