You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
93 lines
2.9 KiB
93 lines
2.9 KiB
using Autofac;
|
|
using CliFx;
|
|
using CliFx.Attributes;
|
|
using CliFx.Exceptions;
|
|
using CliFx.Infrastructure;
|
|
using Flurl.Http;
|
|
using JetBrains.Annotations;
|
|
using MoreLinq.Extensions;
|
|
using Recyclarr.Cli.Command.Setup;
|
|
using Recyclarr.Cli.Logging;
|
|
using Recyclarr.TrashLib.Http;
|
|
using Recyclarr.TrashLib.Repo.VersionControl;
|
|
using Recyclarr.TrashLib.Startup;
|
|
using Serilog;
|
|
using Serilog.Events;
|
|
|
|
namespace Recyclarr.Cli.Command;
|
|
|
|
public abstract class BaseCommand : ICommand
|
|
{
|
|
// Not explicitly defined as a Command here because for legacy reasons, different subcommands expose this in
|
|
// different ways to the user.
|
|
public abstract string? AppDataDirectory { get; set; }
|
|
|
|
[CommandOption("debug", 'd', Description =
|
|
"Display additional logs useful for development/debug purposes.")]
|
|
// ReSharper disable once MemberCanBeProtected.Global
|
|
public bool Debug { get; [UsedImplicitly] set; } = false;
|
|
|
|
protected ILogger Logger { get; private set; } = Log.Logger;
|
|
|
|
protected virtual void RegisterServices(ContainerBuilder builder)
|
|
{
|
|
}
|
|
|
|
public virtual async ValueTask ExecuteAsync(IConsole console)
|
|
{
|
|
// Must happen first because everything can use the logger.
|
|
var logLevel = Debug ? LogEventLevel.Debug : LogEventLevel.Information;
|
|
|
|
await using var container = CompositionRoot.Setup(builder =>
|
|
{
|
|
builder.RegisterInstance(console).As<IConsole>().ExternallyOwned();
|
|
|
|
builder.Register(c => c.Resolve<DefaultAppDataSetup>().CreateAppPaths(AppDataDirectory))
|
|
.As<IAppPaths>()
|
|
.SingleInstance();
|
|
|
|
builder.Register(c => c.Resolve<LoggerFactory>().Create(logLevel))
|
|
.As<ILogger>()
|
|
.SingleInstance();
|
|
|
|
RegisterServices(builder);
|
|
});
|
|
|
|
Logger = container.Resolve<ILogger>();
|
|
var tasks = container.Resolve<IOrderedEnumerable<IBaseCommandSetupTask>>().ToArray();
|
|
tasks.ForEach(x => x.OnStart());
|
|
|
|
try
|
|
{
|
|
await Process(container);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
switch (e)
|
|
{
|
|
case GitCmdException e2:
|
|
Logger.Error(e2, "Non-zero exit code {ExitCode} while executing Git command: {Error}",
|
|
e2.ExitCode, e2.Error);
|
|
break;
|
|
|
|
case FlurlHttpException e2:
|
|
Logger.Error("HTTP error: {Message}", e2.SanitizedExceptionMessage());
|
|
break;
|
|
|
|
default:
|
|
Logger.Error("{Message}", e.Message);
|
|
break;
|
|
}
|
|
|
|
Logger.Debug("Exception Stacktrace: {Stacktrace}", e.StackTrace);
|
|
throw new CommandException("Exiting due to exception");
|
|
}
|
|
finally
|
|
{
|
|
tasks.Reverse().ForEach(x => x.OnFinish());
|
|
}
|
|
}
|
|
|
|
public abstract Task Process(ILifetimeScope container);
|
|
}
|