From 2aa86333b5e4af3272f1a8ffdf2210420cf1e861 Mon Sep 17 00:00:00 2001 From: Scott Holodak Date: Mon, 30 Oct 2023 16:00:32 -0400 Subject: [PATCH] WiP --- .../AppBuilder/BaseCommandLineAppBuilder.cs | 300 +++++++++--------- Source/Sholo.CommandLine/Command/ICommand.cs | 17 - Source/Sholo.CommandLine/CommandLineApp.cs | 135 ++++---- .../CommandLineAppBuilder.cs | 9 +- .../CommandLineAppBuilderExtensions.cs | 13 + .../CommandPlugin/BaseCommandPlugin.cs | 41 --- .../CommandPlugin/BaseLambdaCommandPlugin.cs | 46 --- .../CommandPlugin/CommandPlugin.cs | 221 ------------- .../CommandPlugin/ICommandPlugin.cs | 28 -- .../CommandPlugin/ICommonCommandPlugin.cs | 16 - .../CommandPlugin/LambdaCommandPlugin.cs | 107 ------- .../BaseCommandPluginBuilder.cs | 54 ---- .../BaseCommonCommandPluginBuilder.cs | 61 ---- .../CommandPluginBuilder.cs | 45 --- .../ICommandPluginBuilder.cs | 30 -- .../ICommonCommandPluginBuilder.cs | 25 -- .../BaseCommandPluginBuilder.cs | 53 ++++ .../BaseCommonCommandPluginBuilder.cs | 60 ++++ .../CommandPluginBuilder.cs | 44 +++ .../ICommandPluginBuilder.cs | 29 ++ .../ICommonCommandPluginBuilder.cs | 24 ++ .../CommandPlugins/BaseCommandPlugin.cs | 40 +++ .../CommandPlugins/BaseLambdaCommandPlugin.cs | 45 +++ .../CommandPlugins/CommandPlugin.cs | 214 +++++++++++++ .../CommandPlugins/ICommandPlugin.cs | 27 ++ .../CommandPlugins/ICommonCommandPlugin.cs | 15 + .../CommandPlugins/LambdaCommandPlugin.cs | 106 +++++++ Source/Sholo.CommandLine/Commands/ICommand.cs | 16 + .../Context/BasePluginConfigurationContext.cs | 37 ++- .../Context/CommandConfigurationContext.cs | 25 +- .../Context/CommandContext.cs | 83 +++-- .../Context/CommandParameterizationContext.cs | 39 ++- .../Context/CommandServicesContext.cs | 77 +++-- .../Sholo.CommandLine/Context/HostContext.cs | 9 +- .../Context/HostLoggingContext.cs | 16 + .../Context/HostServicesContext.cs | 17 +- .../Context/ICommandConfigurationContext.cs | 13 +- .../Context/ICommandContext.cs | 27 +- .../ICommandParameterizationContext.cs | 17 +- .../Context/ICommandServicesContext.cs | 28 +- .../Sholo.CommandLine/Context/IHostContext.cs | 7 +- .../Context/IHostLoggingContext.cs | 10 + .../Context/IHostServicesContext.cs | 9 +- .../Context/IPluginConfigurationContext.cs | 38 +-- .../Context/PluginConfigurationContext.cs | 72 ++--- Source/Sholo.CommandLine/GlobalUsings.cs | 3 + Source/Sholo.CommandLine/ICommandLineApp.cs | 9 +- .../ICommandLineAppBuilder.cs | 31 +- .../Sholo.CommandLine.csproj | 20 +- 49 files changed, 1219 insertions(+), 1189 deletions(-) delete mode 100644 Source/Sholo.CommandLine/Command/ICommand.cs create mode 100644 Source/Sholo.CommandLine/CommandLineAppBuilderExtensions.cs delete mode 100644 Source/Sholo.CommandLine/CommandPlugin/BaseCommandPlugin.cs delete mode 100644 Source/Sholo.CommandLine/CommandPlugin/BaseLambdaCommandPlugin.cs delete mode 100644 Source/Sholo.CommandLine/CommandPlugin/CommandPlugin.cs delete mode 100644 Source/Sholo.CommandLine/CommandPlugin/ICommandPlugin.cs delete mode 100644 Source/Sholo.CommandLine/CommandPlugin/ICommonCommandPlugin.cs delete mode 100644 Source/Sholo.CommandLine/CommandPlugin/LambdaCommandPlugin.cs delete mode 100644 Source/Sholo.CommandLine/CommandPluginBuilder/BaseCommandPluginBuilder.cs delete mode 100644 Source/Sholo.CommandLine/CommandPluginBuilder/BaseCommonCommandPluginBuilder.cs delete mode 100644 Source/Sholo.CommandLine/CommandPluginBuilder/CommandPluginBuilder.cs delete mode 100644 Source/Sholo.CommandLine/CommandPluginBuilder/ICommandPluginBuilder.cs delete mode 100644 Source/Sholo.CommandLine/CommandPluginBuilder/ICommonCommandPluginBuilder.cs create mode 100644 Source/Sholo.CommandLine/CommandPluginBuilders/BaseCommandPluginBuilder.cs create mode 100644 Source/Sholo.CommandLine/CommandPluginBuilders/BaseCommonCommandPluginBuilder.cs create mode 100644 Source/Sholo.CommandLine/CommandPluginBuilders/CommandPluginBuilder.cs create mode 100644 Source/Sholo.CommandLine/CommandPluginBuilders/ICommandPluginBuilder.cs create mode 100644 Source/Sholo.CommandLine/CommandPluginBuilders/ICommonCommandPluginBuilder.cs create mode 100644 Source/Sholo.CommandLine/CommandPlugins/BaseCommandPlugin.cs create mode 100644 Source/Sholo.CommandLine/CommandPlugins/BaseLambdaCommandPlugin.cs create mode 100644 Source/Sholo.CommandLine/CommandPlugins/CommandPlugin.cs create mode 100644 Source/Sholo.CommandLine/CommandPlugins/ICommandPlugin.cs create mode 100644 Source/Sholo.CommandLine/CommandPlugins/ICommonCommandPlugin.cs create mode 100644 Source/Sholo.CommandLine/CommandPlugins/LambdaCommandPlugin.cs create mode 100644 Source/Sholo.CommandLine/Commands/ICommand.cs create mode 100644 Source/Sholo.CommandLine/Context/HostLoggingContext.cs create mode 100644 Source/Sholo.CommandLine/Context/IHostLoggingContext.cs create mode 100644 Source/Sholo.CommandLine/GlobalUsings.cs diff --git a/Source/Sholo.CommandLine/AppBuilder/BaseCommandLineAppBuilder.cs b/Source/Sholo.CommandLine/AppBuilder/BaseCommandLineAppBuilder.cs index 7d29bf0..c7335fd 100644 --- a/Source/Sholo.CommandLine/AppBuilder/BaseCommandLineAppBuilder.cs +++ b/Source/Sholo.CommandLine/AppBuilder/BaseCommandLineAppBuilder.cs @@ -1,203 +1,209 @@ using System; using System.Collections.Generic; +using System.Reflection; using McMaster.Extensions.CommandLineUtils; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Logging; -using Sholo.CommandLine.CommandPlugin; +using Sholo.CommandLine.CommandPluginBuilders; +using Sholo.CommandLine.CommandPlugins; using Sholo.CommandLine.Context; // ReSharper disable UnusedMember.Global -namespace Sholo.CommandLine.AppBuilder +namespace Sholo.CommandLine.AppBuilder; + +[PublicAPI] +public abstract class BaseCommandLineAppBuilder : ICommandLineAppBuilder + where TSelf : BaseCommandLineAppBuilder, new() { - public abstract class BaseCommandLineAppBuilder : ICommandLineAppBuilder - where TSelf : BaseCommandLineAppBuilder, new() - { - private string Name { get; set; } - private string Description { get; set; } + private string Name { get; set; } + private string Description { get; set; } - private IList> LoggingBuilderConfiguration { get; } = new List>(); - private IList> HostServicesConfiguration { get; } = new List>(); - private IList> HostConfigurationConfiguration { get; } = new List>(); + private IList> LoggingBuilderConfiguration { get; } = new List>(); + private IList> HostServicesConfiguration { get; } = new List>(); + private IList> HostConfigurationConfiguration { get; } = new List>(); - private IList> CommonCommandConfigurationConfiguration { get; } = new List>(); - private IList> CommonCommandServicesConfiguration { get; } = new List>(); + private IList> CommonCommandConfigurationConfiguration { get; } = new List>(); + private IList> CommonCommandServicesConfiguration { get; } = new List>(); - private IDictionary CommandPlugins { get; } = new Dictionary(StringComparer.OrdinalIgnoreCase); + private IDictionary CommandPlugins { get; } = new Dictionary(StringComparer.OrdinalIgnoreCase); - public TSelf WithName(string commandName) - { - Name = commandName; - return (TSelf)this; - } + public TSelf WithName(string commandName) + { + Name = commandName; + return (TSelf)this; + } - public TSelf WithDescription(string description) - { - Description = description; - return (TSelf)this; - } + public TSelf WithDescription(string description) + { + Description = description; + return (TSelf)this; + } - public TSelf ConfigureHostConfiguration(Action configuration) - { - HostConfigurationConfiguration.Add(configuration); - return (TSelf)this; - } + public TSelf ConfigureHostConfiguration(Action configuration) + { + HostConfigurationConfiguration.Add(configuration); + return (TSelf)this; + } - public TSelf ConfigureHostServices(Action services) - { - HostServicesConfiguration.Add(services); - return (TSelf)this; - } + public TSelf ConfigureHostServices(Action services) + { + HostServicesConfiguration.Add(services); + return (TSelf)this; + } - public TSelf ConfigureLogging(Action loggingConfiguration) - { - LoggingBuilderConfiguration.Add(loggingConfiguration); - return (TSelf)this; - } + public TSelf ConfigureLogging(Action loggingConfiguration) + { + LoggingBuilderConfiguration.Add(loggingConfiguration); + return (TSelf)this; + } - public TSelf ConfigureCommonCommandConfiguration(Action configuration) - { - CommonCommandConfigurationConfiguration.Add(configuration); - return (TSelf)this; - } + public TSelf ConfigureCommonCommandConfiguration(Action configuration) + { + CommonCommandConfigurationConfiguration.Add(configuration); + return (TSelf)this; + } - public TSelf ConfigureCommonCommandServices(Action services) - { - CommonCommandServicesConfiguration.Add(services); - return (TSelf)this; - } + public TSelf ConfigureCommonCommandServices(Action services) + { + CommonCommandServicesConfiguration.Add(services); + return (TSelf)this; + } - public TSelf WithCommand() - where TCommandPlugin : class, ICommonCommandPlugin, new() - { - var commandPlugin = new TCommandPlugin(); + public TSelf WithCommand() + where TCommandPlugin : class, ICommonCommandPlugin, new() + { + var commandPlugin = new TCommandPlugin(); - CommandPlugins.Add(commandPlugin.CommandName, commandPlugin); - return (TSelf)this; - } + CommandPlugins.Add(commandPlugin.CommandName, commandPlugin); + return (TSelf)this; + } - public TSelf WithCommand(ICommandPlugin commandPlugin) - { - CommandPlugins.Add(commandPlugin.CommandName, commandPlugin); - return (TSelf)this; - } + public TSelf WithCommand(ICommandPlugin commandPlugin) + { + CommandPlugins.Add(commandPlugin.CommandName, commandPlugin); + return (TSelf)this; + } - public ICommandLineApp Build() - { - var hostContext = new HostContext(); + public ICommandLineApp Build() + { + var hostContext = new HostContext(); - var hostConfiguration = BuildHostConfiguration(hostContext); + var hostConfiguration = BuildHostConfiguration(hostContext); - var hostServicesContext = new HostServicesContext(hostConfiguration); + var hostServicesContext = new HostServicesContext(hostConfiguration); - var hostServices = BuildHostServices(hostServicesContext); + var hostServices = BuildHostServices(hostServicesContext); - var configureLogBuilder = new Action( - lb => + var configureLogBuilder = new Action( + (ctx, lb) => + { + foreach (var configurator in LoggingBuilderConfiguration) { - foreach (var configurator in this.LoggingBuilderConfiguration) - { - configurator.Invoke(lb); - } - }); + configurator.Invoke(ctx, lb); + } + }); - var configureCommonConfiguration = new Action( - (ctx, cb) => + var configureCommonConfiguration = new Action( + (ctx, cb) => + { + foreach (var configurator in CommonCommandConfigurationConfiguration) { - foreach (var configurator in this.CommonCommandConfigurationConfiguration) - { - configurator.Invoke(ctx, cb); - } - }); + configurator.Invoke(ctx, cb); + } + }); - var configureCommonCommandServices = new Action( - (ctx, sc) => + var configureCommonCommandServices = new Action( + (ctx, sc) => + { + foreach (var configurator in CommonCommandServicesConfiguration) { - foreach (var configurator in this.CommonCommandServicesConfiguration) - { - configurator.Invoke(ctx, sc); - } - - sc.TryAddSingleton(ctx.LoggerFactory); - sc.TryAdd(ServiceDescriptor.Singleton(typeof(ILogger<>), typeof(Logger<>))); + configurator.Invoke(ctx, sc); } - ); - - var pluginConfigurationContext = new PluginConfigurationContext( - hostConfiguration, - hostServices, - configureLogBuilder, - configureCommonConfiguration, - configureCommonCommandServices); - var rootCommandPlugin = CreateRootCommand(pluginConfigurationContext); + sc.TryAddSingleton(ctx.LoggerFactory); + sc.TryAdd(ServiceDescriptor.Singleton(typeof(ILogger<>), typeof(Logger<>))); + } + ); - var app = new CommandLineApplication(); - rootCommandPlugin.ConfigureCommand(pluginConfigurationContext, app); - return new CommandLineApp(app); - } + var pluginConfigurationContext = new PluginConfigurationContext( + hostConfiguration, + hostServices, + configureLogBuilder, + configureCommonConfiguration, + configureCommonCommandServices); - protected virtual ICommonCommandPlugin CreateRootCommand(IPluginConfigurationContext pluginConfigurationContext) - => new CommandPluginBuilder.CommandPluginBuilder() - .WithName(this.Name) - .WithDescription(this.Description) - .ConfigureCommand((ctx, commandLineApp) => - { - commandLineApp.HelpOption(true); + var rootCommandPlugin = CreateRootCommand(pluginConfigurationContext); - foreach (var commandLinePlugin in CommandPlugins) - { - var commandName = commandLinePlugin.Key; - var plugin = commandLinePlugin.Value; + var app = new CommandLineApplication(); + rootCommandPlugin.ConfigureCommand(pluginConfigurationContext, app); + return new CommandLineApp(app); + } - commandLineApp.Command(commandName, childCommand => - { - childCommand.Description = plugin.Description; + protected virtual ICommonCommandPlugin CreateRootCommand(IPluginConfigurationContext pluginConfigurationContext) + => new CommandPluginBuilder() + .WithName(Name ?? Assembly.GetEntryAssembly()?.GetName().Name ?? "Unknown") + .WithDescription(Description ?? "My awesome utility") + .ConfigureCommand((_, commandLineApp) => + { + commandLineApp.HelpOption(true); - plugin.ConfigureCommand(pluginConfigurationContext, childCommand); - }); - } + foreach (var commandLinePlugin in CommandPlugins) + { + var commandName = commandLinePlugin.Key; + var plugin = commandLinePlugin.Value; - commandLineApp.OnExecute(() => + commandLineApp.Command(commandName, childCommand => { - commandLineApp.ShowHelp(); - return 1; + childCommand.Description = plugin.Description; + + plugin.ConfigureCommand(pluginConfigurationContext, childCommand); }); - }) - .Build(); + } - protected virtual IConfigurationRoot BuildHostConfiguration(IHostContext hostContext) - { - var hostConfigurationBuilder = new ConfigurationBuilder(); - foreach (var hostConfigurator in HostConfigurationConfiguration) - { - hostConfigurator.Invoke(hostContext, hostConfigurationBuilder); - } + commandLineApp.OnExecute(() => + { + commandLineApp.ShowHelp(); + return 1; + }); + }) + .Build(); - var hostConfiguration = hostConfigurationBuilder.Build(); - return hostConfiguration; + protected virtual IConfigurationRoot BuildHostConfiguration(IHostContext hostContext) + { + var hostConfigurationBuilder = new ConfigurationBuilder(); + foreach (var hostConfigurator in HostConfigurationConfiguration) + { + hostConfigurator.Invoke(hostContext, hostConfigurationBuilder); } - protected virtual ServiceProvider BuildHostServices(IHostServicesContext hostServicesContext) - { - var hostServiceCollection = new ServiceCollection(); + var hostConfiguration = hostConfigurationBuilder.Build(); + return hostConfiguration; + } - hostServiceCollection.AddLogging(loggingBuilder => - { - foreach (var loggingBuilderConfigurator in this.LoggingBuilderConfiguration) - { - loggingBuilderConfigurator.Invoke(loggingBuilder); - } - }); + protected virtual ServiceProvider BuildHostServices(IHostServicesContext hostServicesContext) + { + var hostServiceCollection = new ServiceCollection(); + var emptyServiceProvider = new ServiceCollection().BuildServiceProvider(); - foreach (var hostServicesConfigurator in this.HostServicesConfiguration) + var earlyHostConfiguration = new HostLoggingContext(hostServicesContext.HostConfiguration, emptyServiceProvider); + hostServiceCollection.AddLogging(loggingBuilder => + { + foreach (var loggingBuilderConfigurator in LoggingBuilderConfiguration) { - hostServicesConfigurator.Invoke(hostServicesContext, hostServiceCollection); + loggingBuilderConfigurator.Invoke(earlyHostConfiguration, loggingBuilder); } + }); - var hostServices = hostServiceCollection.BuildServiceProvider(); - return hostServices; + foreach (var hostServicesConfigurator in HostServicesConfiguration) + { + hostServicesConfigurator.Invoke(hostServicesContext, hostServiceCollection); } + + hostServiceCollection.AddSingleton(sp => new HostLoggingContext(hostServicesContext.HostConfiguration, sp)); + + var hostServices = hostServiceCollection.BuildServiceProvider(); + return hostServices; } } diff --git a/Source/Sholo.CommandLine/Command/ICommand.cs b/Source/Sholo.CommandLine/Command/ICommand.cs deleted file mode 100644 index bbfaf26..0000000 --- a/Source/Sholo.CommandLine/Command/ICommand.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Threading; -using System.Threading.Tasks; -using Sholo.CommandLine.Context; - -namespace Sholo.CommandLine.Command -{ - public interface ICommand - where TParameters : class, new() - { - Task RunAsync(ICommandContext context, CancellationToken cancellationToken); - } - - public interface ICommand - { - Task RunAsync(ICommandContext context, CancellationToken cancellationToken); - } -} diff --git a/Source/Sholo.CommandLine/CommandLineApp.cs b/Source/Sholo.CommandLine/CommandLineApp.cs index 6cdb7bc..1b04127 100644 --- a/Source/Sholo.CommandLine/CommandLineApp.cs +++ b/Source/Sholo.CommandLine/CommandLineApp.cs @@ -5,94 +5,93 @@ using System.Threading.Tasks; using McMaster.Extensions.CommandLineUtils; -namespace Sholo.CommandLine +namespace Sholo.CommandLine; + +internal class CommandLineApp : ICommandLineApp { - internal class CommandLineApp : ICommandLineApp + // https://github.com/natemcmaster/CommandLineUtils/issues/111#issuecomment-401276354 + private static readonly int ExitCodeOperationCanceled; + private static readonly int ExitCodeUnhandledException; + + static CommandLineApp() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // values from http://www.febooti.com/products/automation-workshop/online-help/events/run-dos-cmd-command/exit-codes/ + ExitCodeOperationCanceled = unchecked((int)0xC000013A); + ExitCodeUnhandledException = unchecked((int)0xE0434F4D); + } + else + { + // Match Process.ExitCode (cfr bash) which uses 128 + signo. + ExitCodeOperationCanceled = 130; // SIGINT + ExitCodeUnhandledException = 134; // SIGABRT + } + } + + private CommandLineApplication Application { get; } + + public CommandLineApp(CommandLineApplication application) { - // https://github.com/natemcmaster/CommandLineUtils/issues/111#issuecomment-401276354 - private static readonly int ExitCodeOperationCanceled; - private static readonly int ExitCodeUnhandledException; + Application = application; + } + + public async Task ExecuteAsync(string[] args, CancellationToken cancellationToken) + { + var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); - static CommandLineApp() + void CancelHandler(object o, ConsoleCancelEventArgs e) { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + // ReSharper disable AccessToDisposedClosure + + if (!cts.IsCancellationRequested) { - // values from http://www.febooti.com/products/automation-workshop/online-help/events/run-dos-cmd-command/exit-codes/ - ExitCodeOperationCanceled = unchecked((int)0xC000013A); - ExitCodeUnhandledException = unchecked((int)0xE0434F4D); + cts.Cancel(); + e.Cancel = true; } else { - // Match Process.ExitCode (cfr bash) which uses 128 + signo. - ExitCodeOperationCanceled = 130; // SIGINT - ExitCodeUnhandledException = 134; // SIGABRT + e.Cancel = false; } - } - private CommandLineApplication Application { get; } - - public CommandLineApp(CommandLineApplication application) - { - Application = application; + // ReSharper restore AccessToDisposedClosure } - public async Task ExecuteAsync(string[] args, CancellationToken cancellationToken) + void UnloadingHandler(AssemblyLoadContext ctx) { - var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); + // ReSharper disable AccessToDisposedClosure - void CancelHandler(object o, ConsoleCancelEventArgs e) + if (!cts.IsCancellationRequested) { - // ReSharper disable AccessToDisposedClosure - - if (!cts.IsCancellationRequested) - { - cts.Cancel(); - e.Cancel = true; - } - else - { - e.Cancel = false; - } - - // ReSharper restore AccessToDisposedClosure + cts.Cancel(); } - void UnloadingHandler(AssemblyLoadContext ctx) - { - // ReSharper disable AccessToDisposedClosure - - if (!cts.IsCancellationRequested) - { - cts.Cancel(); - } - - // ReSharper restore AccessToDisposedClosure - } + // ReSharper restore AccessToDisposedClosure + } - try - { - Console.CancelKeyPress += CancelHandler; - AssemblyLoadContext.Default.Unloading += UnloadingHandler; + try + { + Console.CancelKeyPress += CancelHandler; + AssemblyLoadContext.Default.Unloading += UnloadingHandler; - var result = await Application.ExecuteAsync(args, cts.Token); + var result = await Application.ExecuteAsync(args, cts.Token); - return result; - } - catch (OperationCanceledException) - { - return ExitCodeOperationCanceled; - } - catch (Exception e) - { - await Console.Error.WriteLineAsync($"Unhandled exception: {e}"); - return ExitCodeUnhandledException; - } - finally - { - AssemblyLoadContext.Default.Unloading -= UnloadingHandler; - Console.CancelKeyPress -= CancelHandler; - cts.Dispose(); - } + return result; + } + catch (OperationCanceledException) + { + return ExitCodeOperationCanceled; + } + catch (Exception e) + { + await Console.Error.WriteLineAsync($"Unhandled exception: {e}"); + return ExitCodeUnhandledException; + } + finally + { + AssemblyLoadContext.Default.Unloading -= UnloadingHandler; + Console.CancelKeyPress -= CancelHandler; + cts.Dispose(); } } } diff --git a/Source/Sholo.CommandLine/CommandLineAppBuilder.cs b/Source/Sholo.CommandLine/CommandLineAppBuilder.cs index e2c42bd..13c5d06 100644 --- a/Source/Sholo.CommandLine/CommandLineAppBuilder.cs +++ b/Source/Sholo.CommandLine/CommandLineAppBuilder.cs @@ -1,9 +1,8 @@ using Sholo.CommandLine.AppBuilder; -namespace Sholo.CommandLine +namespace Sholo.CommandLine; + +// Inherit from the base class. +public sealed class CommandLineAppBuilder : BaseCommandLineAppBuilder { - // Inherit from the base class. - public sealed class CommandLineAppBuilder : BaseCommandLineAppBuilder - { - } } diff --git a/Source/Sholo.CommandLine/CommandLineAppBuilderExtensions.cs b/Source/Sholo.CommandLine/CommandLineAppBuilderExtensions.cs new file mode 100644 index 0000000..15b411a --- /dev/null +++ b/Source/Sholo.CommandLine/CommandLineAppBuilderExtensions.cs @@ -0,0 +1,13 @@ +using Sholo.Utils.Logging; + +namespace Sholo.CommandLine; + +public static class CommandLineAppBuilderExtensions +{ + public static ICommandLineAppBuilder UseSerilogConsole(this ICommandLineAppBuilder builder) + where TSelf : ICommandLineAppBuilder + { + builder.ConfigureLogging((ctx, lb) => lb.AddSerilogConsole(ctx.HostConfiguration)); + return builder; + } +} diff --git a/Source/Sholo.CommandLine/CommandPlugin/BaseCommandPlugin.cs b/Source/Sholo.CommandLine/CommandPlugin/BaseCommandPlugin.cs deleted file mode 100644 index 4e27dec..0000000 --- a/Source/Sholo.CommandLine/CommandPlugin/BaseCommandPlugin.cs +++ /dev/null @@ -1,41 +0,0 @@ -using McMaster.Extensions.CommandLineUtils; -using Microsoft.Extensions.Configuration; -using Sholo.CommandLine.Context; - -namespace Sholo.CommandLine.CommandPlugin -{ - public abstract class BaseCommandPlugin : ICommonCommandPlugin - { - public string CommandName { get; } - public string Description { get; } - - protected BaseCommandPlugin(string commandName, string description) - { - CommandName = commandName; - Description = description; - } - - public virtual void ConfigureCommandConfiguration(ICommandConfigurationContext context, IConfigurationBuilder builder) - { - } - - public virtual void ConfigureCommand(IPluginConfigurationContext context, CommandLineApplication command) - { - } - - protected virtual (ICommandConfigurationContext, IConfigurationRoot) BuildCommandConfiguration( - IPluginConfigurationContext buildContext) - { - var commandConfigurationContext = new CommandConfigurationContext( - buildContext.HostConfiguration, - buildContext.HostServices); - - var commandConfigurationBuilder = new ConfigurationBuilder(); - buildContext.ConfigureCommonConfiguration(commandConfigurationContext, commandConfigurationBuilder); - ConfigureCommandConfiguration(commandConfigurationContext, commandConfigurationBuilder); - var commandConfiguration = commandConfigurationBuilder.Build(); - - return (commandConfigurationContext, commandConfiguration); - } - } -} \ No newline at end of file diff --git a/Source/Sholo.CommandLine/CommandPlugin/BaseLambdaCommandPlugin.cs b/Source/Sholo.CommandLine/CommandPlugin/BaseLambdaCommandPlugin.cs deleted file mode 100644 index dc5f53c..0000000 --- a/Source/Sholo.CommandLine/CommandPlugin/BaseLambdaCommandPlugin.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using McMaster.Extensions.CommandLineUtils; -using Microsoft.Extensions.Configuration; -using Sholo.CommandLine.Context; - -namespace Sholo.CommandLine.CommandPlugin -{ - public abstract class BaseLambdaCommandPlugin - { - public string CommandName { get; } - public string Description { get; } - - private Action[] CommandConfigurationConfiguration { get; } - private Action[] CommandConfiguration { get; } - - protected BaseLambdaCommandPlugin( - string commandName, - string description, - IEnumerable> commandConfigurationConfiguration, - IEnumerable> commandConfiguration) - { - CommandName = commandName ?? throw new ArgumentNullException(nameof(commandName)); - Description = description ?? throw new ArgumentNullException(nameof(description)); - CommandConfigurationConfiguration = commandConfigurationConfiguration.ToArray(); - CommandConfiguration = commandConfiguration.ToArray(); - } - - public void ConfigureCommandConfiguration(ICommandConfigurationContext context, IConfigurationBuilder builder) - { - foreach (var configurator in CommandConfigurationConfiguration) - { - configurator.Invoke(context, builder); - } - } - - public void ConfigureCommand(IPluginConfigurationContext context, CommandLineApplication command) - { - foreach (var configurator in CommandConfiguration) - { - configurator.Invoke(context, command); - } - } - } -} \ No newline at end of file diff --git a/Source/Sholo.CommandLine/CommandPlugin/CommandPlugin.cs b/Source/Sholo.CommandLine/CommandPlugin/CommandPlugin.cs deleted file mode 100644 index ecaade3..0000000 --- a/Source/Sholo.CommandLine/CommandPlugin/CommandPlugin.cs +++ /dev/null @@ -1,221 +0,0 @@ -using System; -using System.Threading; -using System.Threading.Tasks; -using McMaster.Extensions.CommandLineUtils; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Sholo.CommandLine.Command; -using Sholo.CommandLine.Context; - -// ReSharper disable UnusedVariable -// ReSharper disable UnusedMember.Global -// ReSharper disable UnusedParameter.Local -namespace Sholo.CommandLine.CommandPlugin -{ - public class CommandPlugin : BaseCommandPlugin, ICommandPlugin - where TCommand : class, ICommand - { - public CommandPlugin(string commandName, string description) - : base(commandName, description) - { - } - - public virtual void ConfigureCommandServices(ICommandServicesContext context, IServiceCollection services) - { - } - - public override void ConfigureCommand(IPluginConfigurationContext buildContext, CommandLineApplication command) - { - command.OnExecuteAsync(async cancellationToken => - { - var (commandConfigurationContext, commandConfiguration) = BuildCommandConfiguration(buildContext); - - var (commandServicesContext, serviceProvider) = BuildCommandServiceProvider( - buildContext, - commandConfiguration); - - var scopeFactory = serviceProvider.GetRequiredService(); - using (var scope = scopeFactory.CreateScope()) - { - var scopeServiceProvider = scope.ServiceProvider; - - return await BuildAndRunCommand( - buildContext, - command, - commandConfiguration, - scopeServiceProvider, - commandServicesContext, - cancellationToken); - } - }); - } - - protected (ICommandServicesContext, IServiceProvider) BuildCommandServiceProvider( - IPluginConfigurationContext buildContext, - IConfigurationRoot commandConfiguration) - { - var commandServicesContext = new CommandServicesContext( - buildContext.HostConfiguration, - buildContext.HostServices, - commandConfiguration); - - var commandServices = new ServiceCollection(); - commandServices.AddLogging(loggingBuilder => - { - buildContext.ConfigureLogBuilder(loggingBuilder); - }); - commandServices.AddSingleton(); - - buildContext.ConfigureCommonCommandServices(commandServicesContext, commandServices); - ConfigureCommandServices(commandServicesContext, commandServices); - - var serviceProvider = commandServices.BuildServiceProvider(); - - return (commandServicesContext, serviceProvider); - } - -#pragma warning disable CA1801 - private async Task BuildAndRunCommand( - IPluginConfigurationContext buildContext, - CommandLineApplication command, - IConfigurationRoot commandConfiguration, - IServiceProvider scopeServiceProvider, - ICommandServicesContext commandServicesContext, - CancellationToken cancellationToken) - { - var commandContext = new CommandContext( - commandServicesContext.HostConfiguration, - commandServicesContext.HostServices, - commandConfiguration, - scopeServiceProvider, - command); - - var commandInstance = scopeServiceProvider.GetRequiredService(); - return await commandInstance.RunAsync(commandContext, cancellationToken); - } -#pragma warning restore CA1801 - } - - public class CommandPlugin : BaseCommandPlugin, ICommandPlugin - where TCommand : class, ICommand - where TCommandParameters : class, new() - { - public CommandPlugin(string commandName, string description) - : base(commandName, description) - { - } - - public virtual void ConfigureParameters(ICommandParameterizationContext context, TCommandParameters parameters) - { - } - - public virtual void ConfigureCommandServices(ICommandServicesContext context, IServiceCollection services) - { - } - - public override void ConfigureCommand(IPluginConfigurationContext buildContext, CommandLineApplication command) - { - command.OnExecuteAsync(async cancellationToken => - { - var (commandConfigurationContext, commandConfiguration) = BuildCommandConfiguration(buildContext); - - var (commandParameterizationContext, parameters) = BuildParameters( - buildContext, - command, - commandConfiguration); - - var (commandServicesContext, serviceProvider) = BuildCommandServiceProvider( - buildContext, - commandConfiguration, - parameters, - this); - - var scopeFactory = serviceProvider.GetRequiredService(); - using (var scope = scopeFactory.CreateScope()) - { - var scopeServiceProvider = scope.ServiceProvider; - - return await BuildAndRunCommand( - buildContext, - command, - commandConfiguration, - scopeServiceProvider, - commandServicesContext, - parameters, - cancellationToken); - } - }); - } - - protected (ICommandServicesContext, IServiceProvider) BuildCommandServiceProvider( - IPluginConfigurationContext buildContext, - IConfigurationRoot commandConfiguration, - TCommandParameters parameters, -#pragma warning disable CA1801 - TCommandPlugin commandPlugin -#pragma warning restore CA1801 - ) - where TCommandPlugin : ICommandPlugin - { - var commandServicesContext = new CommandServicesContext( - buildContext.HostConfiguration, - buildContext.HostServices, - commandConfiguration, - parameters); - - var commandServices = new ServiceCollection(); - commandServices.AddLogging(loggingBuilder => - { - buildContext.ConfigureLogBuilder(loggingBuilder); - }); - commandServices.AddSingleton, TCommand>(); - - buildContext.ConfigureCommonCommandServices(commandServicesContext, commandServices); - ConfigureCommandServices(commandServicesContext, commandServices); - - var serviceProvider = commandServices.BuildServiceProvider(); - - return (commandServicesContext, serviceProvider); - } - -#pragma warning disable CA1801 - private async Task BuildAndRunCommand( - IPluginConfigurationContext buildContext, - CommandLineApplication command, - IConfigurationRoot commandConfiguration, - IServiceProvider scopeServiceProvider, - ICommandServicesContext commandServicesContext, - TCommandParameters parameters, - CancellationToken cancellationToken) - { - var commandContext = new CommandContext( - commandServicesContext.HostConfiguration, - commandServicesContext.HostServices, - commandConfiguration, - scopeServiceProvider, - command, - parameters); - - var commandInstance = scopeServiceProvider.GetRequiredService>(); - return await commandInstance.RunAsync(commandContext, cancellationToken); - } -#pragma warning restore CA1801 - - private (ICommandParameterizationContext, TCommandParameters) BuildParameters( - IPluginConfigurationContext buildContext, - CommandLineApplication command, - IConfigurationRoot commandConfiguration) - { - var commandParameterizationContext = new CommandParameterizationContext( - buildContext.HostConfiguration, - buildContext.HostServices, - commandConfiguration, - command); - - var parameters = new TCommandParameters(); - - ConfigureParameters(commandParameterizationContext, parameters); - return (commandParameterizationContext, parameters); - } - } -} diff --git a/Source/Sholo.CommandLine/CommandPlugin/ICommandPlugin.cs b/Source/Sholo.CommandLine/CommandPlugin/ICommandPlugin.cs deleted file mode 100644 index ad81bfd..0000000 --- a/Source/Sholo.CommandLine/CommandPlugin/ICommandPlugin.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using Sholo.CommandLine.Command; -using Sholo.CommandLine.Context; - -// ReSharper disable UnusedMemberInSuper.Global -// ReSharper disable UnusedMember.Global -// ReSharper disable UnusedTypeParameter -namespace Sholo.CommandLine.CommandPlugin -{ - public interface ICommandPlugin : ICommonCommandPlugin - { - void ConfigureCommandServices(ICommandServicesContext context, IServiceCollection services); - } - - public interface ICommandPlugin : ICommonCommandPlugin - where TCommand : ICommand - { - void ConfigureCommandServices(ICommandServicesContext context, IServiceCollection services); - } - - public interface ICommandPlugin : ICommonCommandPlugin - where TCommand : ICommand - where TParameters : class, new() - { - void ConfigureCommandServices(ICommandServicesContext context, IServiceCollection services); - void ConfigureParameters(ICommandParameterizationContext context, TParameters parameters); - } -} diff --git a/Source/Sholo.CommandLine/CommandPlugin/ICommonCommandPlugin.cs b/Source/Sholo.CommandLine/CommandPlugin/ICommonCommandPlugin.cs deleted file mode 100644 index 7a6874f..0000000 --- a/Source/Sholo.CommandLine/CommandPlugin/ICommonCommandPlugin.cs +++ /dev/null @@ -1,16 +0,0 @@ -using McMaster.Extensions.CommandLineUtils; -using Microsoft.Extensions.Configuration; -using Sholo.CommandLine.Context; - -// ReSharper disable UnusedMemberInSuper.Global -namespace Sholo.CommandLine.CommandPlugin -{ - public interface ICommonCommandPlugin - { - string CommandName { get; } - string Description { get; } - - void ConfigureCommandConfiguration(ICommandConfigurationContext context, IConfigurationBuilder builder); - void ConfigureCommand(IPluginConfigurationContext context, CommandLineApplication command); - } -} diff --git a/Source/Sholo.CommandLine/CommandPlugin/LambdaCommandPlugin.cs b/Source/Sholo.CommandLine/CommandPlugin/LambdaCommandPlugin.cs deleted file mode 100644 index 188cc49..0000000 --- a/Source/Sholo.CommandLine/CommandPlugin/LambdaCommandPlugin.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using McMaster.Extensions.CommandLineUtils; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Sholo.CommandLine.Command; -using Sholo.CommandLine.Context; - -namespace Sholo.CommandLine.CommandPlugin -{ - public class LambdaCommandPlugin : BaseLambdaCommandPlugin, ICommandPlugin - where TCommand : ICommand - where TParameters : class, new() - { - private Action, IServiceCollection>[] CommandServicesConfiguration { get; } - private Action[] ParameterConfiguration { get; } - - public LambdaCommandPlugin( - string commandName, - string description, - IEnumerable> commandConfigurationConfiguration, - IEnumerable, IServiceCollection>> commandServicesConfiguration, - IEnumerable> commandConfiguration, - IEnumerable> parameterConfiguration - ) - : base( - commandName, - description, - commandConfigurationConfiguration, - commandConfiguration - ) - { - CommandServicesConfiguration = commandServicesConfiguration.ToArray(); - ParameterConfiguration = parameterConfiguration.ToArray(); - } - - public void ConfigureCommandServices(ICommandServicesContext context, IServiceCollection services) - { - foreach (var configurator in CommandServicesConfiguration) - { - configurator.Invoke(context, services); - } - } - - public void ConfigureParameters(ICommandParameterizationContext context, TParameters parameters) - { - foreach (var configurator in ParameterConfiguration) - { - configurator.Invoke(context, parameters); - } - } - } - - public class LambdaCommandPlugin : BaseLambdaCommandPlugin, ICommandPlugin - where TCommand : ICommand - { - private Action[] CommandServicesConfiguration { get; } - - public LambdaCommandPlugin( - string commandName, - string description, - IEnumerable> commandConfigurationConfiguration, - IEnumerable> commandServicesConfiguration, - IEnumerable> commandConfiguration) - : base( - commandName, - description, - commandConfigurationConfiguration, - commandConfiguration) - { - CommandServicesConfiguration = commandServicesConfiguration.ToArray(); - } - - public void ConfigureCommandServices(ICommandServicesContext context, IServiceCollection services) - { - foreach (var configurator in CommandServicesConfiguration) - { - configurator.Invoke(context, services); - } - } - } - - public class LambdaCommandPlugin : BaseLambdaCommandPlugin, ICommandPlugin - { - private Action[] CommandServicesConfiguration { get; } - - public LambdaCommandPlugin( - string commandName, - string description, - IEnumerable> commandConfigurationConfiguration, - IEnumerable> commandServicesConfiguration, - IEnumerable> commandConfiguration) - : base(commandName, description, commandConfigurationConfiguration, commandConfiguration) - { - CommandServicesConfiguration = commandServicesConfiguration.ToArray(); - } - - public void ConfigureCommandServices(ICommandServicesContext context, IServiceCollection services) - { - foreach (var configurator in CommandServicesConfiguration) - { - configurator.Invoke(context, services); - } - } - } -} diff --git a/Source/Sholo.CommandLine/CommandPluginBuilder/BaseCommandPluginBuilder.cs b/Source/Sholo.CommandLine/CommandPluginBuilder/BaseCommandPluginBuilder.cs deleted file mode 100644 index b75249e..0000000 --- a/Source/Sholo.CommandLine/CommandPluginBuilder/BaseCommandPluginBuilder.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.Extensions.DependencyInjection; -using Sholo.CommandLine.Command; -using Sholo.CommandLine.Context; - -namespace Sholo.CommandLine.CommandPluginBuilder -{ - public abstract class BaseCommandPluginBuilder : BaseCommonCommandPluginBuilder, ICommandPluginBuilder - where TSelf : BaseCommandPluginBuilder, new() - where TCommand : ICommand - where TParameters : class, new() - { - protected List> ParameterConfiguration { get; } = new List>(); - protected List, IServiceCollection>> CommandServicesConfiguration { get; } = new List, IServiceCollection>>(); - - public TSelf ConfigureParameters(Action parameters) - { - ParameterConfiguration.Add(parameters); - return (TSelf)this; - } - - public TSelf ConfigureCommandServices(Action, IServiceCollection> services) - { - CommandServicesConfiguration.Add(services); - return (TSelf)this; - } - } - - public abstract class BaseCommandPluginBuilder : BaseCommonCommandPluginBuilder, ICommandPluginBuilder - where TSelf : BaseCommandPluginBuilder, new() - where TCommand : ICommand - { - protected List> CommandServicesConfiguration { get; } = new List>(); - - public TSelf ConfigureCommandServices(Action services) - { - CommandServicesConfiguration.Add(services); - return (TSelf)this; - } - } - - public abstract class BaseCommandPluginBuilder : BaseCommonCommandPluginBuilder, ICommandPluginBuilder - where TSelf : BaseCommandPluginBuilder, new() - { - protected List> CommandServicesConfiguration { get; } = new List>(); - - public TSelf ConfigureCommandServices(Action services) - { - CommandServicesConfiguration.Add(services); - return (TSelf)this; - } - } -} diff --git a/Source/Sholo.CommandLine/CommandPluginBuilder/BaseCommonCommandPluginBuilder.cs b/Source/Sholo.CommandLine/CommandPluginBuilder/BaseCommonCommandPluginBuilder.cs deleted file mode 100644 index 1cfca6d..0000000 --- a/Source/Sholo.CommandLine/CommandPluginBuilder/BaseCommonCommandPluginBuilder.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Collections.Generic; -using McMaster.Extensions.CommandLineUtils; -using Microsoft.Extensions.Configuration; -using Sholo.CommandLine.CommandPlugin; -using Sholo.CommandLine.Context; - -namespace Sholo.CommandLine.CommandPluginBuilder -{ - public abstract class BaseCommonCommandPluginBuilder - : ICommonCommandPluginBuilder - where TSelf : BaseCommonCommandPluginBuilder, new() - { - protected string Name { get; set; } - protected string Description { get; set; } - - protected List> CommandConfigurationConfiguration { get; } = new List>(); - protected List> CommandConfiguration { get; } = new List>(); - protected IDictionary CommandPlugins { get; } = new Dictionary(StringComparer.OrdinalIgnoreCase); - - public TSelf WithName(string commandName) - { - Name = commandName; - return (TSelf)this; - } - - public TSelf WithDescription(string description) - { - Description = description; - return (TSelf)this; - } - - public TSelf ConfigureCommand(Action command) - { - CommandConfiguration.Add(command); - return (TSelf)this; - } - - public TSelf WithCommand() - where TCommandPlugin : class, ICommandPlugin, new() - { - var commandPlugin = new TCommandPlugin(); - CommandPlugins.Add(commandPlugin.CommandName, commandPlugin); - return (TSelf)this; - } - - public TSelf WithCommand(ICommandPlugin commandPlugin) - { - CommandPlugins.Add(commandPlugin.CommandName, commandPlugin); - return (TSelf)this; - } - - public TSelf ConfigureCommandConfiguration(Action configurationBuilder) - { - CommandConfigurationConfiguration.Add(configurationBuilder); - return (TSelf)this; - } - - public abstract ICommonCommandPlugin Build(); - } -} \ No newline at end of file diff --git a/Source/Sholo.CommandLine/CommandPluginBuilder/CommandPluginBuilder.cs b/Source/Sholo.CommandLine/CommandPluginBuilder/CommandPluginBuilder.cs deleted file mode 100644 index 60f1a5d..0000000 --- a/Source/Sholo.CommandLine/CommandPluginBuilder/CommandPluginBuilder.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Sholo.CommandLine.Command; -using Sholo.CommandLine.CommandPlugin; - -namespace Sholo.CommandLine.CommandPluginBuilder -{ - public sealed class CommandPluginBuilder - : BaseCommandPluginBuilder, TCommand, TParameters> - where TParameters : class, new() - where TCommand : ICommand - { - public override ICommonCommandPlugin Build() - => new LambdaCommandPlugin( - Name, - Description, - CommandConfigurationConfiguration, - CommandServicesConfiguration, - CommandConfiguration, - ParameterConfiguration); - } - - public sealed class CommandPluginBuilder - : BaseCommandPluginBuilder, TCommand> - where TCommand : ICommand - { - public override ICommonCommandPlugin Build() - => new LambdaCommandPlugin( - Name, - Description, - CommandConfigurationConfiguration, - CommandServicesConfiguration, - CommandConfiguration); - } - - public sealed class CommandPluginBuilder - : BaseCommandPluginBuilder - { - public override ICommonCommandPlugin Build() - => new LambdaCommandPlugin( - Name, - Description, - CommandConfigurationConfiguration, - CommandServicesConfiguration, - CommandConfiguration); - } -} diff --git a/Source/Sholo.CommandLine/CommandPluginBuilder/ICommandPluginBuilder.cs b/Source/Sholo.CommandLine/CommandPluginBuilder/ICommandPluginBuilder.cs deleted file mode 100644 index f6cec0b..0000000 --- a/Source/Sholo.CommandLine/CommandPluginBuilder/ICommandPluginBuilder.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using Microsoft.Extensions.DependencyInjection; -using Sholo.CommandLine.Command; -using Sholo.CommandLine.Context; - -// ReSharper disable UnusedMember.Global -namespace Sholo.CommandLine.CommandPluginBuilder -{ - public interface ICommandPluginBuilder : ICommonCommandPluginBuilder - where TSelf : ICommandPluginBuilder - where TCommand : ICommand - where TParameters : class, new() - { - TSelf ConfigureParameters(Action parameters); - TSelf ConfigureCommandServices(Action, IServiceCollection> services); - } - - public interface ICommandPluginBuilder : ICommonCommandPluginBuilder - where TSelf : ICommandPluginBuilder - where TCommand : ICommand - { - TSelf ConfigureCommandServices(Action services); - } - - public interface ICommandPluginBuilder : ICommonCommandPluginBuilder - where TSelf : ICommandPluginBuilder - { - TSelf ConfigureCommandServices(Action services); - } -} diff --git a/Source/Sholo.CommandLine/CommandPluginBuilder/ICommonCommandPluginBuilder.cs b/Source/Sholo.CommandLine/CommandPluginBuilder/ICommonCommandPluginBuilder.cs deleted file mode 100644 index 1741ac8..0000000 --- a/Source/Sholo.CommandLine/CommandPluginBuilder/ICommonCommandPluginBuilder.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using McMaster.Extensions.CommandLineUtils; -using Microsoft.Extensions.Configuration; -using Sholo.CommandLine.CommandPlugin; -using Sholo.CommandLine.Context; - -// ReSharper disable UnusedMember.Global -// ReSharper disable UnusedMemberInSuper.Global -namespace Sholo.CommandLine.CommandPluginBuilder -{ - public interface ICommonCommandPluginBuilder - where TSelf : ICommonCommandPluginBuilder - { - TSelf WithName(string name); - TSelf WithDescription(string description); - TSelf ConfigureCommandConfiguration(Action configurationBuilder); - TSelf ConfigureCommand(Action command); - - TSelf WithCommand() - where TCommandPlugin : class, ICommandPlugin, new(); - - TSelf WithCommand(ICommandPlugin commandPlugin); - ICommonCommandPlugin Build(); - } -} diff --git a/Source/Sholo.CommandLine/CommandPluginBuilders/BaseCommandPluginBuilder.cs b/Source/Sholo.CommandLine/CommandPluginBuilders/BaseCommandPluginBuilder.cs new file mode 100644 index 0000000..39a90e5 --- /dev/null +++ b/Source/Sholo.CommandLine/CommandPluginBuilders/BaseCommandPluginBuilder.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; +using Sholo.CommandLine.Commands; +using Sholo.CommandLine.Context; + +namespace Sholo.CommandLine.CommandPluginBuilders; + +public abstract class BaseCommandPluginBuilder : BaseCommonCommandPluginBuilder, ICommandPluginBuilder + where TSelf : BaseCommandPluginBuilder, new() + where TCommand : ICommand + where TParameters : class, new() +{ + protected List> ParameterConfiguration { get; } = new List>(); + protected List, IServiceCollection>> CommandServicesConfiguration { get; } = new List, IServiceCollection>>(); + + public TSelf ConfigureParameters(Action parameters) + { + ParameterConfiguration.Add(parameters); + return (TSelf)this; + } + + public TSelf ConfigureCommandServices(Action, IServiceCollection> services) + { + CommandServicesConfiguration.Add(services); + return (TSelf)this; + } +} + +public abstract class BaseCommandPluginBuilder : BaseCommonCommandPluginBuilder, ICommandPluginBuilder + where TSelf : BaseCommandPluginBuilder, new() + where TCommand : ICommand +{ + protected List> CommandServicesConfiguration { get; } = new List>(); + + public TSelf ConfigureCommandServices(Action services) + { + CommandServicesConfiguration.Add(services); + return (TSelf)this; + } +} + +public abstract class BaseCommandPluginBuilder : BaseCommonCommandPluginBuilder, ICommandPluginBuilder + where TSelf : BaseCommandPluginBuilder, new() +{ + protected List> CommandServicesConfiguration { get; } = new List>(); + + public TSelf ConfigureCommandServices(Action services) + { + CommandServicesConfiguration.Add(services); + return (TSelf)this; + } +} diff --git a/Source/Sholo.CommandLine/CommandPluginBuilders/BaseCommonCommandPluginBuilder.cs b/Source/Sholo.CommandLine/CommandPluginBuilders/BaseCommonCommandPluginBuilder.cs new file mode 100644 index 0000000..06f16b7 --- /dev/null +++ b/Source/Sholo.CommandLine/CommandPluginBuilders/BaseCommonCommandPluginBuilder.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using McMaster.Extensions.CommandLineUtils; +using Microsoft.Extensions.Configuration; +using Sholo.CommandLine.CommandPlugins; +using Sholo.CommandLine.Context; + +namespace Sholo.CommandLine.CommandPluginBuilders; + +public abstract class BaseCommonCommandPluginBuilder + : ICommonCommandPluginBuilder + where TSelf : BaseCommonCommandPluginBuilder, new() +{ + protected string Name { get; set; } + protected string Description { get; set; } + + protected List> CommandConfigurationConfiguration { get; } = new List>(); + protected List> CommandConfiguration { get; } = new List>(); + protected IDictionary CommandPlugins { get; } = new Dictionary(StringComparer.OrdinalIgnoreCase); + + public TSelf WithName(string commandName) + { + Name = commandName; + return (TSelf)this; + } + + public TSelf WithDescription(string description) + { + Description = description; + return (TSelf)this; + } + + public TSelf ConfigureCommand(Action command) + { + CommandConfiguration.Add(command); + return (TSelf)this; + } + + public TSelf WithCommand() + where TCommandPlugin : class, ICommandPlugin, new() + { + var commandPlugin = new TCommandPlugin(); + CommandPlugins.Add(commandPlugin.CommandName, commandPlugin); + return (TSelf)this; + } + + public TSelf WithCommand(ICommandPlugin commandPlugin) + { + CommandPlugins.Add(commandPlugin.CommandName, commandPlugin); + return (TSelf)this; + } + + public TSelf ConfigureCommandConfiguration(Action configurationBuilder) + { + CommandConfigurationConfiguration.Add(configurationBuilder); + return (TSelf)this; + } + + public abstract ICommonCommandPlugin Build(); +} diff --git a/Source/Sholo.CommandLine/CommandPluginBuilders/CommandPluginBuilder.cs b/Source/Sholo.CommandLine/CommandPluginBuilders/CommandPluginBuilder.cs new file mode 100644 index 0000000..3c0f7ed --- /dev/null +++ b/Source/Sholo.CommandLine/CommandPluginBuilders/CommandPluginBuilder.cs @@ -0,0 +1,44 @@ +using Sholo.CommandLine.CommandPlugins; +using Sholo.CommandLine.Commands; + +namespace Sholo.CommandLine.CommandPluginBuilders; + +public sealed class CommandPluginBuilder + : BaseCommandPluginBuilder, TCommand, TParameters> + where TParameters : class, new() + where TCommand : ICommand +{ + public override ICommonCommandPlugin Build() + => new LambdaCommandPlugin( + Name, + Description, + CommandConfigurationConfiguration, + CommandServicesConfiguration, + CommandConfiguration, + ParameterConfiguration); +} + +public sealed class CommandPluginBuilder + : BaseCommandPluginBuilder, TCommand> + where TCommand : ICommand +{ + public override ICommonCommandPlugin Build() + => new LambdaCommandPlugin( + Name, + Description, + CommandConfigurationConfiguration, + CommandServicesConfiguration, + CommandConfiguration); +} + +public sealed class CommandPluginBuilder + : BaseCommandPluginBuilder +{ + public override ICommonCommandPlugin Build() + => new LambdaCommandPlugin( + Name, + Description, + CommandConfigurationConfiguration, + CommandServicesConfiguration, + CommandConfiguration); +} diff --git a/Source/Sholo.CommandLine/CommandPluginBuilders/ICommandPluginBuilder.cs b/Source/Sholo.CommandLine/CommandPluginBuilders/ICommandPluginBuilder.cs new file mode 100644 index 0000000..3c324be --- /dev/null +++ b/Source/Sholo.CommandLine/CommandPluginBuilders/ICommandPluginBuilder.cs @@ -0,0 +1,29 @@ +using System; +using Microsoft.Extensions.DependencyInjection; +using Sholo.CommandLine.Commands; +using Sholo.CommandLine.Context; + +// ReSharper disable UnusedMember.Global +namespace Sholo.CommandLine.CommandPluginBuilders; + +public interface ICommandPluginBuilder : ICommonCommandPluginBuilder + where TSelf : ICommandPluginBuilder + where TCommand : ICommand + where TParameters : class, new() +{ + TSelf ConfigureParameters(Action parameters); + TSelf ConfigureCommandServices(Action, IServiceCollection> services); +} + +public interface ICommandPluginBuilder : ICommonCommandPluginBuilder + where TSelf : ICommandPluginBuilder + where TCommand : ICommand +{ + TSelf ConfigureCommandServices(Action services); +} + +public interface ICommandPluginBuilder : ICommonCommandPluginBuilder + where TSelf : ICommandPluginBuilder +{ + TSelf ConfigureCommandServices(Action services); +} diff --git a/Source/Sholo.CommandLine/CommandPluginBuilders/ICommonCommandPluginBuilder.cs b/Source/Sholo.CommandLine/CommandPluginBuilders/ICommonCommandPluginBuilder.cs new file mode 100644 index 0000000..484d5bd --- /dev/null +++ b/Source/Sholo.CommandLine/CommandPluginBuilders/ICommonCommandPluginBuilder.cs @@ -0,0 +1,24 @@ +using System; +using McMaster.Extensions.CommandLineUtils; +using Microsoft.Extensions.Configuration; +using Sholo.CommandLine.CommandPlugins; +using Sholo.CommandLine.Context; + +// ReSharper disable UnusedMember.Global +// ReSharper disable UnusedMemberInSuper.Global +namespace Sholo.CommandLine.CommandPluginBuilders; + +public interface ICommonCommandPluginBuilder + where TSelf : ICommonCommandPluginBuilder +{ + TSelf WithName(string name); + TSelf WithDescription(string description); + TSelf ConfigureCommandConfiguration(Action configurationBuilder); + TSelf ConfigureCommand(Action command); + + TSelf WithCommand() + where TCommandPlugin : class, ICommandPlugin, new(); + + TSelf WithCommand(ICommandPlugin commandPlugin); + ICommonCommandPlugin Build(); +} diff --git a/Source/Sholo.CommandLine/CommandPlugins/BaseCommandPlugin.cs b/Source/Sholo.CommandLine/CommandPlugins/BaseCommandPlugin.cs new file mode 100644 index 0000000..8c89a75 --- /dev/null +++ b/Source/Sholo.CommandLine/CommandPlugins/BaseCommandPlugin.cs @@ -0,0 +1,40 @@ +using McMaster.Extensions.CommandLineUtils; +using Microsoft.Extensions.Configuration; +using Sholo.CommandLine.Context; + +namespace Sholo.CommandLine.CommandPlugins; + +public abstract class BaseCommandPlugin : ICommonCommandPlugin +{ + public string CommandName { get; } + public string Description { get; } + + protected BaseCommandPlugin(string commandName, string description) + { + CommandName = commandName; + Description = description; + } + + public virtual void ConfigureCommandConfiguration(ICommandConfigurationContext context, IConfigurationBuilder builder) + { + } + + public virtual void ConfigureCommand(IPluginConfigurationContext context, CommandLineApplication command) + { + } + + protected virtual (ICommandConfigurationContext, IConfigurationRoot) BuildCommandConfiguration( + IPluginConfigurationContext buildContext) + { + var commandConfigurationContext = new CommandConfigurationContext( + buildContext.HostConfiguration, + buildContext.HostServices); + + var commandConfigurationBuilder = new ConfigurationBuilder(); + buildContext.ConfigureCommonConfiguration(commandConfigurationContext, commandConfigurationBuilder); + ConfigureCommandConfiguration(commandConfigurationContext, commandConfigurationBuilder); + var commandConfiguration = commandConfigurationBuilder.Build(); + + return (commandConfigurationContext, commandConfiguration); + } +} diff --git a/Source/Sholo.CommandLine/CommandPlugins/BaseLambdaCommandPlugin.cs b/Source/Sholo.CommandLine/CommandPlugins/BaseLambdaCommandPlugin.cs new file mode 100644 index 0000000..c956e5f --- /dev/null +++ b/Source/Sholo.CommandLine/CommandPlugins/BaseLambdaCommandPlugin.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using McMaster.Extensions.CommandLineUtils; +using Microsoft.Extensions.Configuration; +using Sholo.CommandLine.Context; + +namespace Sholo.CommandLine.CommandPlugins; + +public abstract class BaseLambdaCommandPlugin +{ + public string CommandName { get; } + public string Description { get; } + + private Action[] CommandConfigurationConfiguration { get; } + private Action[] CommandConfiguration { get; } + + protected BaseLambdaCommandPlugin( + string commandName, + string description, + IEnumerable> commandConfigurationConfiguration, + IEnumerable> commandConfiguration) + { + CommandName = commandName ?? throw new ArgumentNullException(nameof(commandName)); + Description = description ?? throw new ArgumentNullException(nameof(description)); + CommandConfigurationConfiguration = commandConfigurationConfiguration.ToArray(); + CommandConfiguration = commandConfiguration.ToArray(); + } + + public void ConfigureCommandConfiguration(ICommandConfigurationContext context, IConfigurationBuilder builder) + { + foreach (var configurator in CommandConfigurationConfiguration) + { + configurator.Invoke(context, builder); + } + } + + public void ConfigureCommand(IPluginConfigurationContext context, CommandLineApplication command) + { + foreach (var configurator in CommandConfiguration) + { + configurator.Invoke(context, command); + } + } +} diff --git a/Source/Sholo.CommandLine/CommandPlugins/CommandPlugin.cs b/Source/Sholo.CommandLine/CommandPlugins/CommandPlugin.cs new file mode 100644 index 0000000..a4d1adb --- /dev/null +++ b/Source/Sholo.CommandLine/CommandPlugins/CommandPlugin.cs @@ -0,0 +1,214 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using McMaster.Extensions.CommandLineUtils; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Sholo.CommandLine.Commands; +using Sholo.CommandLine.Context; + +// ReSharper disable UnusedVariable +// ReSharper disable UnusedMember.Global +// ReSharper disable UnusedParameter.Local +namespace Sholo.CommandLine.CommandPlugins; + +[PublicAPI] +public class CommandPlugin : BaseCommandPlugin, ICommandPlugin + where TCommand : class, ICommand +{ + public CommandPlugin(string commandName, string description) + : base(commandName, description) + { + } + + public virtual void ConfigureCommandServices(ICommandServicesContext context, IServiceCollection services) + { + } + + public override void ConfigureCommand(IPluginConfigurationContext buildContext, CommandLineApplication command) + { + command.OnExecuteAsync(async cancellationToken => + { + var (commandConfigurationContext, commandConfiguration) = BuildCommandConfiguration(buildContext); + + var (commandServicesContext, serviceProvider) = BuildCommandServiceProvider( + buildContext, + commandConfiguration); + + var scopeFactory = serviceProvider.GetRequiredService(); + using var scope = scopeFactory.CreateScope(); + var scopeServiceProvider = scope.ServiceProvider; + + return await BuildAndRunCommandAsync( + command, + commandConfiguration, + scopeServiceProvider, + commandServicesContext, + cancellationToken); + }); + } + + protected (ICommandServicesContext, IServiceProvider) BuildCommandServiceProvider( + IPluginConfigurationContext buildContext, + IConfigurationRoot commandConfiguration) + { + var commandServicesContext = new CommandServicesContext( + this, + buildContext.HostConfiguration, + buildContext.HostServices, + commandConfiguration); + + var hostLoggingContext = buildContext.HostServices.GetRequiredService(); + + var commandServices = new ServiceCollection(); + + commandServices.AddLogging(loggingBuilder => + { + buildContext.ConfigureLogBuilder(hostLoggingContext, loggingBuilder); + }); + commandServices.AddSingleton(); + + buildContext.ConfigureCommonCommandServices(commandServicesContext, commandServices); + ConfigureCommandServices(commandServicesContext, commandServices); + + var serviceProvider = commandServices.BuildServiceProvider(); + + return (commandServicesContext, serviceProvider); + } + + private async Task BuildAndRunCommandAsync( + CommandLineApplication command, + IConfigurationRoot commandConfiguration, + IServiceProvider scopeServiceProvider, + ICommandServicesContext commandServicesContext, + CancellationToken cancellationToken) + { + var commandContext = new CommandContext( + commandServicesContext.HostConfiguration, + commandServicesContext.HostServices, + commandConfiguration, + scopeServiceProvider, + command); + + var commandInstance = scopeServiceProvider.GetRequiredService(); + return await commandInstance.RunAsync(commandContext, cancellationToken); + } +} + +[PublicAPI] +public class CommandPlugin : BaseCommandPlugin, ICommandPlugin + where TCommand : class, ICommand + where TCommandParameters : class, new() +{ + public CommandPlugin(string commandName, string description) + : base(commandName, description) + { + } + + public virtual void ConfigureParameters(ICommandParameterizationContext context, TCommandParameters parameters) + { + } + + public virtual void ConfigureCommandServices(ICommandServicesContext context, IServiceCollection services) + { + } + + public override void ConfigureCommand(IPluginConfigurationContext buildContext, CommandLineApplication command) + { + command.OnExecuteAsync(async cancellationToken => + { + var (commandConfigurationContext, commandConfiguration) = BuildCommandConfiguration(buildContext); + + var (commandParameterizationContext, parameters) = BuildParameters( + buildContext, + command, + commandConfiguration); + + var (commandServicesContext, serviceProvider) = BuildCommandServiceProvider( + buildContext, + commandConfiguration, + parameters, + this); + + var scopeFactory = serviceProvider.GetRequiredService(); + using var scope = scopeFactory.CreateScope(); + var scopeServiceProvider = scope.ServiceProvider; + + return await BuildAndRunCommandAsync( + command, + commandConfiguration, + scopeServiceProvider, + commandServicesContext, + parameters, + cancellationToken); + }); + } + + protected (ICommandServicesContext, IServiceProvider) BuildCommandServiceProvider( + IPluginConfigurationContext buildContext, + IConfigurationRoot commandConfiguration, + TCommandParameters parameters, + TCommandPlugin commandPlugin + ) + where TCommandPlugin : ICommandPlugin + { + var commandServicesContext = new CommandServicesContext( + commandPlugin, + buildContext.HostConfiguration, + buildContext.HostServices, + commandConfiguration, + parameters); + + var hostLoggingContext = buildContext.HostServices.GetRequiredService(); + var commandServices = new ServiceCollection(); + commandServices.AddLogging(loggingBuilder => + { + buildContext.ConfigureLogBuilder(hostLoggingContext, loggingBuilder); + }); + commandServices.AddSingleton, TCommand>(); + + buildContext.ConfigureCommonCommandServices(commandServicesContext, commandServices); + ConfigureCommandServices(commandServicesContext, commandServices); + + var serviceProvider = commandServices.BuildServiceProvider(); + + return (commandServicesContext, serviceProvider); + } + + private async Task BuildAndRunCommandAsync( + CommandLineApplication command, + IConfigurationRoot commandConfiguration, + IServiceProvider scopeServiceProvider, + ICommandServicesContext commandServicesContext, + TCommandParameters parameters, + CancellationToken cancellationToken) + { + var commandContext = new CommandContext( + commandServicesContext.HostConfiguration, + commandServicesContext.HostServices, + commandConfiguration, + scopeServiceProvider, + command, + parameters); + + var commandInstance = scopeServiceProvider.GetRequiredService>(); + return await commandInstance.RunAsync(commandContext, cancellationToken); + } + + private (ICommandParameterizationContext, TCommandParameters) BuildParameters( + IPluginConfigurationContext buildContext, + CommandLineApplication command, + IConfigurationRoot commandConfiguration) + { + var commandParameterizationContext = new CommandParameterizationContext( + buildContext.HostConfiguration, + buildContext.HostServices, + commandConfiguration, + command); + + var parameters = new TCommandParameters(); + + ConfigureParameters(commandParameterizationContext, parameters); + return (commandParameterizationContext, parameters); + } +} diff --git a/Source/Sholo.CommandLine/CommandPlugins/ICommandPlugin.cs b/Source/Sholo.CommandLine/CommandPlugins/ICommandPlugin.cs new file mode 100644 index 0000000..411bf8a --- /dev/null +++ b/Source/Sholo.CommandLine/CommandPlugins/ICommandPlugin.cs @@ -0,0 +1,27 @@ +using Microsoft.Extensions.DependencyInjection; +using Sholo.CommandLine.Commands; +using Sholo.CommandLine.Context; + +// ReSharper disable UnusedMemberInSuper.Global +// ReSharper disable UnusedMember.Global +// ReSharper disable UnusedTypeParameter +namespace Sholo.CommandLine.CommandPlugins; + +public interface ICommandPlugin : ICommonCommandPlugin +{ + void ConfigureCommandServices(ICommandServicesContext context, IServiceCollection services); +} + +public interface ICommandPlugin : ICommonCommandPlugin + where TCommand : ICommand +{ + void ConfigureCommandServices(ICommandServicesContext context, IServiceCollection services); +} + +public interface ICommandPlugin : ICommonCommandPlugin + where TCommand : ICommand + where TParameters : class, new() +{ + void ConfigureCommandServices(ICommandServicesContext context, IServiceCollection services); + void ConfigureParameters(ICommandParameterizationContext context, TParameters parameters); +} diff --git a/Source/Sholo.CommandLine/CommandPlugins/ICommonCommandPlugin.cs b/Source/Sholo.CommandLine/CommandPlugins/ICommonCommandPlugin.cs new file mode 100644 index 0000000..cf96e7c --- /dev/null +++ b/Source/Sholo.CommandLine/CommandPlugins/ICommonCommandPlugin.cs @@ -0,0 +1,15 @@ +using McMaster.Extensions.CommandLineUtils; +using Microsoft.Extensions.Configuration; +using Sholo.CommandLine.Context; + +// ReSharper disable UnusedMemberInSuper.Global +namespace Sholo.CommandLine.CommandPlugins; + +public interface ICommonCommandPlugin +{ + string CommandName { get; } + string Description { get; } + + void ConfigureCommandConfiguration(ICommandConfigurationContext context, IConfigurationBuilder builder); + void ConfigureCommand(IPluginConfigurationContext context, CommandLineApplication command); +} diff --git a/Source/Sholo.CommandLine/CommandPlugins/LambdaCommandPlugin.cs b/Source/Sholo.CommandLine/CommandPlugins/LambdaCommandPlugin.cs new file mode 100644 index 0000000..6a7be8f --- /dev/null +++ b/Source/Sholo.CommandLine/CommandPlugins/LambdaCommandPlugin.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using McMaster.Extensions.CommandLineUtils; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Sholo.CommandLine.Commands; +using Sholo.CommandLine.Context; + +namespace Sholo.CommandLine.CommandPlugins; + +public class LambdaCommandPlugin : BaseLambdaCommandPlugin, ICommandPlugin + where TCommand : ICommand + where TParameters : class, new() +{ + private Action, IServiceCollection>[] CommandServicesConfiguration { get; } + private Action[] ParameterConfiguration { get; } + + public LambdaCommandPlugin( + string commandName, + string description, + IEnumerable> commandConfigurationConfiguration, + IEnumerable, IServiceCollection>> commandServicesConfiguration, + IEnumerable> commandConfiguration, + IEnumerable> parameterConfiguration + ) + : base( + commandName, + description, + commandConfigurationConfiguration, + commandConfiguration + ) + { + CommandServicesConfiguration = commandServicesConfiguration.ToArray(); + ParameterConfiguration = parameterConfiguration.ToArray(); + } + + public void ConfigureCommandServices(ICommandServicesContext context, IServiceCollection services) + { + foreach (var configurator in CommandServicesConfiguration) + { + configurator.Invoke(context, services); + } + } + + public void ConfigureParameters(ICommandParameterizationContext context, TParameters parameters) + { + foreach (var configurator in ParameterConfiguration) + { + configurator.Invoke(context, parameters); + } + } +} + +public class LambdaCommandPlugin : BaseLambdaCommandPlugin, ICommandPlugin + where TCommand : ICommand +{ + private Action[] CommandServicesConfiguration { get; } + + public LambdaCommandPlugin( + string commandName, + string description, + IEnumerable> commandConfigurationConfiguration, + IEnumerable> commandServicesConfiguration, + IEnumerable> commandConfiguration) + : base( + commandName, + description, + commandConfigurationConfiguration, + commandConfiguration) + { + CommandServicesConfiguration = commandServicesConfiguration.ToArray(); + } + + public void ConfigureCommandServices(ICommandServicesContext context, IServiceCollection services) + { + foreach (var configurator in CommandServicesConfiguration) + { + configurator.Invoke(context, services); + } + } +} + +public class LambdaCommandPlugin : BaseLambdaCommandPlugin, ICommandPlugin +{ + private Action[] CommandServicesConfiguration { get; } + + public LambdaCommandPlugin( + string commandName, + string description, + IEnumerable> commandConfigurationConfiguration, + IEnumerable> commandServicesConfiguration, + IEnumerable> commandConfiguration) + : base(commandName, description, commandConfigurationConfiguration, commandConfiguration) + { + CommandServicesConfiguration = commandServicesConfiguration.ToArray(); + } + + public void ConfigureCommandServices(ICommandServicesContext context, IServiceCollection services) + { + foreach (var configurator in CommandServicesConfiguration) + { + configurator.Invoke(context, services); + } + } +} diff --git a/Source/Sholo.CommandLine/Commands/ICommand.cs b/Source/Sholo.CommandLine/Commands/ICommand.cs new file mode 100644 index 0000000..5724367 --- /dev/null +++ b/Source/Sholo.CommandLine/Commands/ICommand.cs @@ -0,0 +1,16 @@ +using System.Threading; +using System.Threading.Tasks; +using Sholo.CommandLine.Context; + +namespace Sholo.CommandLine.Commands; + +public interface ICommand + where TParameters : class, new() +{ + Task RunAsync(ICommandContext context, CancellationToken cancellationToken); +} + +public interface ICommand +{ + Task RunAsync(ICommandContext context, CancellationToken cancellationToken); +} diff --git a/Source/Sholo.CommandLine/Context/BasePluginConfigurationContext.cs b/Source/Sholo.CommandLine/Context/BasePluginConfigurationContext.cs index 214dfea..77e7e41 100644 --- a/Source/Sholo.CommandLine/Context/BasePluginConfigurationContext.cs +++ b/Source/Sholo.CommandLine/Context/BasePluginConfigurationContext.cs @@ -2,25 +2,24 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; -namespace Sholo.CommandLine.Context +namespace Sholo.CommandLine.Context; + +internal class BasePluginConfigurationContext { - internal class BasePluginConfigurationContext - { - public IConfigurationRoot HostConfiguration { get; } - public IServiceProvider HostServices { get; } - public Action ConfigureLogBuilder { get; } - public Action ConfigureCommonConfiguration { get; } + public IConfigurationRoot HostConfiguration { get; } + public IServiceProvider HostServices { get; } + public Action ConfigureLogBuilder { get; } + public Action ConfigureCommonConfiguration { get; } - protected BasePluginConfigurationContext( - IConfigurationRoot hostConfiguration, - IServiceProvider hostServices, - Action configureLogBuilder, - Action configureCommonConfiguration) - { - HostConfiguration = hostConfiguration; - HostServices = hostServices; - ConfigureLogBuilder = configureLogBuilder; - ConfigureCommonConfiguration = configureCommonConfiguration; - } + protected BasePluginConfigurationContext( + IConfigurationRoot hostConfiguration, + IServiceProvider hostServices, + Action configureLogBuilder, + Action configureCommonConfiguration) + { + HostConfiguration = hostConfiguration; + HostServices = hostServices; + ConfigureLogBuilder = configureLogBuilder; + ConfigureCommonConfiguration = configureCommonConfiguration; } -} \ No newline at end of file +} diff --git a/Source/Sholo.CommandLine/Context/CommandConfigurationContext.cs b/Source/Sholo.CommandLine/Context/CommandConfigurationContext.cs index a24f0f1..aa7d064 100644 --- a/Source/Sholo.CommandLine/Context/CommandConfigurationContext.cs +++ b/Source/Sholo.CommandLine/Context/CommandConfigurationContext.cs @@ -3,19 +3,18 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -namespace Sholo.CommandLine.Context +namespace Sholo.CommandLine.Context; + +internal class CommandConfigurationContext : ICommandConfigurationContext { - internal class CommandConfigurationContext : ICommandConfigurationContext - { - public ILoggerFactory LoggerFactory { get; } - public IConfiguration HostConfiguration { get; } - public IServiceProvider HostServices { get; } + public ILoggerFactory LoggerFactory { get; } + public IConfiguration HostConfiguration { get; } + public IServiceProvider HostServices { get; } - public CommandConfigurationContext(IConfigurationRoot hostConfiguration, IServiceProvider hostServices) - { - HostConfiguration = hostConfiguration; - HostServices = hostServices; - LoggerFactory = hostServices.GetRequiredService(); - } + public CommandConfigurationContext(IConfigurationRoot hostConfiguration, IServiceProvider hostServices) + { + HostConfiguration = hostConfiguration; + HostServices = hostServices; + LoggerFactory = hostServices.GetRequiredService(); } -} \ No newline at end of file +} diff --git a/Source/Sholo.CommandLine/Context/CommandContext.cs b/Source/Sholo.CommandLine/Context/CommandContext.cs index 8dbbb96..a71c319 100644 --- a/Source/Sholo.CommandLine/Context/CommandContext.cs +++ b/Source/Sholo.CommandLine/Context/CommandContext.cs @@ -2,53 +2,52 @@ using McMaster.Extensions.CommandLineUtils; using Microsoft.Extensions.Configuration; -namespace Sholo.CommandLine.Context +namespace Sholo.CommandLine.Context; + +public class CommandContext : CommandContext, ICommandContext + where TParameters : class, new() { - public class CommandContext : CommandContext, ICommandContext - where TParameters : class, new() - { - public TParameters Parameters { get; } + public TParameters Parameters { get; } - public CommandContext( - IConfiguration hostConfiguration, - IServiceProvider hostServices, - IConfiguration commandConfiguration, - IServiceProvider serviceProvider, - CommandLineApplication command, - TParameters parameters + public CommandContext( + IConfiguration hostConfiguration, + IServiceProvider hostServices, + IConfiguration commandConfiguration, + IServiceProvider serviceProvider, + CommandLineApplication command, + TParameters parameters + ) + : base( + hostConfiguration, + hostServices, + commandConfiguration, + serviceProvider, + command ) - : base( - hostConfiguration, - hostServices, - commandConfiguration, - serviceProvider, - command - ) - { - Parameters = parameters; - } + { + Parameters = parameters; } +} - public class CommandContext : ICommandContext - { - public IConfiguration HostConfiguration { get; } - public IServiceProvider HostServices { get; } - public IConfiguration CommandConfiguration { get; } - public IServiceProvider ServiceProvider { get; set; } - public CommandLineApplication Command { get; } +public class CommandContext : ICommandContext +{ + public IConfiguration HostConfiguration { get; } + public IServiceProvider HostServices { get; } + public IConfiguration CommandConfiguration { get; } + public IServiceProvider ServiceProvider { get; set; } + public CommandLineApplication Command { get; } - public CommandContext( - IConfiguration hostConfiguration, - IServiceProvider hostServices, - IConfiguration commandConfiguration, - IServiceProvider serviceProvider, - CommandLineApplication command) - { - HostConfiguration = hostConfiguration; - HostServices = hostServices; - CommandConfiguration = commandConfiguration; - ServiceProvider = serviceProvider; - Command = command; - } + public CommandContext( + IConfiguration hostConfiguration, + IServiceProvider hostServices, + IConfiguration commandConfiguration, + IServiceProvider serviceProvider, + CommandLineApplication command) + { + HostConfiguration = hostConfiguration; + HostServices = hostServices; + CommandConfiguration = commandConfiguration; + ServiceProvider = serviceProvider; + Command = command; } } diff --git a/Source/Sholo.CommandLine/Context/CommandParameterizationContext.cs b/Source/Sholo.CommandLine/Context/CommandParameterizationContext.cs index 85ebee7..3ec1340 100644 --- a/Source/Sholo.CommandLine/Context/CommandParameterizationContext.cs +++ b/Source/Sholo.CommandLine/Context/CommandParameterizationContext.cs @@ -2,26 +2,25 @@ using McMaster.Extensions.CommandLineUtils; using Microsoft.Extensions.Configuration; -namespace Sholo.CommandLine.Context +namespace Sholo.CommandLine.Context; + +public class CommandParameterizationContext : ICommandParameterizationContext { - public class CommandParameterizationContext : ICommandParameterizationContext - { - public IConfigurationRoot HostConfiguration { get; } - public IServiceProvider HostServices { get; } - public IConfigurationRoot CommandConfiguration { get; } - public IServiceProvider ServiceProvider { get; set; } - public CommandLineApplication Command { get; } + public IConfigurationRoot HostConfiguration { get; } + public IServiceProvider HostServices { get; } + public IConfigurationRoot CommandConfiguration { get; } + public IServiceProvider ServiceProvider { get; set; } + public CommandLineApplication Command { get; } - public CommandParameterizationContext( - IConfigurationRoot hostConfiguration, - IServiceProvider hostServices, - IConfigurationRoot commandConfiguration, - CommandLineApplication command) - { - HostConfiguration = hostConfiguration; - HostServices = hostServices; - CommandConfiguration = commandConfiguration; - Command = command; - } + public CommandParameterizationContext( + IConfigurationRoot hostConfiguration, + IServiceProvider hostServices, + IConfigurationRoot commandConfiguration, + CommandLineApplication command) + { + HostConfiguration = hostConfiguration; + HostServices = hostServices; + CommandConfiguration = commandConfiguration; + Command = command; } -} \ No newline at end of file +} diff --git a/Source/Sholo.CommandLine/Context/CommandServicesContext.cs b/Source/Sholo.CommandLine/Context/CommandServicesContext.cs index ab01724..03d6ea3 100644 --- a/Source/Sholo.CommandLine/Context/CommandServicesContext.cs +++ b/Source/Sholo.CommandLine/Context/CommandServicesContext.cs @@ -2,47 +2,56 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Sholo.CommandLine.CommandPlugins; -namespace Sholo.CommandLine.Context +namespace Sholo.CommandLine.Context; + +internal class CommandServicesContext : ICommandServicesContext { - internal class CommandServicesContext : ICommandServicesContext + public string CommandName { get; } + public string Description { get; } + + public ILoggerFactory LoggerFactory { get; } + public IConfiguration HostConfiguration { get; } + public IConfiguration CommandConfiguration { get; } + public IServiceProvider HostServices { get; } + + public CommandServicesContext( + ICommonCommandPlugin commandPlugin, + IConfiguration hostConfiguration, + IServiceProvider hostServices, + IConfiguration commandConfiguration + ) { - public ILoggerFactory LoggerFactory { get; } - public IConfiguration HostConfiguration { get; } - public IConfiguration CommandConfiguration { get; } - public IServiceProvider HostServices { get; } + CommandName = commandPlugin.CommandName; + Description = commandPlugin.Description; - public CommandServicesContext( - IConfiguration hostConfiguration, - IServiceProvider hostServices, - IConfiguration commandConfiguration - ) - { - HostConfiguration = hostConfiguration; - HostServices = hostServices; - LoggerFactory = hostServices.GetRequiredService(); - CommandConfiguration = commandConfiguration; - } + HostConfiguration = hostConfiguration; + HostServices = hostServices; + LoggerFactory = hostServices.GetRequiredService(); + CommandConfiguration = commandConfiguration; } +} - internal class CommandServicesContext : CommandServicesContext, ICommandServicesContext - where TCommandParameters : class, new() - { - public TCommandParameters Parameters { get; } +internal class CommandServicesContext : CommandServicesContext, ICommandServicesContext + where TCommandParameters : class, new() +{ + public TCommandParameters Parameters { get; } - public CommandServicesContext( - IConfiguration hostConfiguration, - IServiceProvider hostServices, - IConfiguration commandConfiguration, - TCommandParameters parameters + public CommandServicesContext( + ICommonCommandPlugin commandPlugin, + IConfiguration hostConfiguration, + IServiceProvider hostServices, + IConfiguration commandConfiguration, + TCommandParameters parameters + ) + : base( + commandPlugin, + hostConfiguration, + hostServices, + commandConfiguration ) - : base( - hostConfiguration, - hostServices, - commandConfiguration - ) - { - Parameters = parameters; - } + { + Parameters = parameters; } } diff --git a/Source/Sholo.CommandLine/Context/HostContext.cs b/Source/Sholo.CommandLine/Context/HostContext.cs index 1c859a6..d3176e1 100644 --- a/Source/Sholo.CommandLine/Context/HostContext.cs +++ b/Source/Sholo.CommandLine/Context/HostContext.cs @@ -1,6 +1,5 @@ -namespace Sholo.CommandLine.Context +namespace Sholo.CommandLine.Context; + +internal class HostContext : IHostContext { - internal class HostContext : IHostContext - { - } -} \ No newline at end of file +} diff --git a/Source/Sholo.CommandLine/Context/HostLoggingContext.cs b/Source/Sholo.CommandLine/Context/HostLoggingContext.cs new file mode 100644 index 0000000..6e30cc7 --- /dev/null +++ b/Source/Sholo.CommandLine/Context/HostLoggingContext.cs @@ -0,0 +1,16 @@ +using System; +using Microsoft.Extensions.Configuration; + +namespace Sholo.CommandLine.Context; + +public class HostLoggingContext : IHostLoggingContext +{ + public IConfiguration HostConfiguration { get; } + public IServiceProvider HostServices { get; } + + public HostLoggingContext(IConfiguration hostConfiguration, IServiceProvider hostServices) + { + HostConfiguration = hostConfiguration; + HostServices = hostServices; + } +} diff --git a/Source/Sholo.CommandLine/Context/HostServicesContext.cs b/Source/Sholo.CommandLine/Context/HostServicesContext.cs index afd7f66..3ee983c 100644 --- a/Source/Sholo.CommandLine/Context/HostServicesContext.cs +++ b/Source/Sholo.CommandLine/Context/HostServicesContext.cs @@ -1,14 +1,13 @@ using Microsoft.Extensions.Configuration; -namespace Sholo.CommandLine.Context +namespace Sholo.CommandLine.Context; + +internal class HostServicesContext : IHostServicesContext { - internal class HostServicesContext : IHostServicesContext - { - public IConfigurationRoot HostConfiguration { get; } + public IConfigurationRoot HostConfiguration { get; } - public HostServicesContext(IConfigurationRoot hostConfiguration) - { - HostConfiguration = hostConfiguration; - } + public HostServicesContext(IConfigurationRoot hostConfiguration) + { + HostConfiguration = hostConfiguration; } -} \ No newline at end of file +} diff --git a/Source/Sholo.CommandLine/Context/ICommandConfigurationContext.cs b/Source/Sholo.CommandLine/Context/ICommandConfigurationContext.cs index 03d12f9..2532bbb 100644 --- a/Source/Sholo.CommandLine/Context/ICommandConfigurationContext.cs +++ b/Source/Sholo.CommandLine/Context/ICommandConfigurationContext.cs @@ -3,12 +3,11 @@ using Microsoft.Extensions.Logging; // ReSharper disable UnusedMemberInSuper.Global -namespace Sholo.CommandLine.Context +namespace Sholo.CommandLine.Context; + +public interface ICommandConfigurationContext { - public interface ICommandConfigurationContext - { - ILoggerFactory LoggerFactory { get; } - IConfiguration HostConfiguration { get; } - IServiceProvider HostServices { get; } - } + ILoggerFactory LoggerFactory { get; } + IConfiguration HostConfiguration { get; } + IServiceProvider HostServices { get; } } diff --git a/Source/Sholo.CommandLine/Context/ICommandContext.cs b/Source/Sholo.CommandLine/Context/ICommandContext.cs index b368eef..50f5e51 100644 --- a/Source/Sholo.CommandLine/Context/ICommandContext.cs +++ b/Source/Sholo.CommandLine/Context/ICommandContext.cs @@ -3,20 +3,19 @@ using Microsoft.Extensions.Configuration; // ReSharper disable UnusedMemberInSuper.Global -namespace Sholo.CommandLine.Context +namespace Sholo.CommandLine.Context; + +public interface ICommandContext { - public interface ICommandContext - { - IConfiguration HostConfiguration { get; } - IServiceProvider HostServices { get; } - IConfiguration CommandConfiguration { get; } - IServiceProvider ServiceProvider { get; set; } - CommandLineApplication Command { get; } - } + IConfiguration HostConfiguration { get; } + IServiceProvider HostServices { get; } + IConfiguration CommandConfiguration { get; } + IServiceProvider ServiceProvider { get; set; } + CommandLineApplication Command { get; } +} - public interface ICommandContext : ICommandContext - where TParameters : class, new() - { - TParameters Parameters { get; } - } +public interface ICommandContext : ICommandContext + where TParameters : class, new() +{ + TParameters Parameters { get; } } diff --git a/Source/Sholo.CommandLine/Context/ICommandParameterizationContext.cs b/Source/Sholo.CommandLine/Context/ICommandParameterizationContext.cs index 31f18b2..9c279f8 100644 --- a/Source/Sholo.CommandLine/Context/ICommandParameterizationContext.cs +++ b/Source/Sholo.CommandLine/Context/ICommandParameterizationContext.cs @@ -4,14 +4,13 @@ // ReSharper disable UnusedMember.Global // ReSharper disable UnusedMemberInSuper.Global -namespace Sholo.CommandLine.Context +namespace Sholo.CommandLine.Context; + +public interface ICommandParameterizationContext { - public interface ICommandParameterizationContext - { - IConfigurationRoot HostConfiguration { get; } - IServiceProvider HostServices { get; } - IConfigurationRoot CommandConfiguration { get; } - IServiceProvider ServiceProvider { get; set; } - CommandLineApplication Command { get; } - } + IConfigurationRoot HostConfiguration { get; } + IServiceProvider HostServices { get; } + IConfigurationRoot CommandConfiguration { get; } + IServiceProvider ServiceProvider { get; set; } + CommandLineApplication Command { get; } } diff --git a/Source/Sholo.CommandLine/Context/ICommandServicesContext.cs b/Source/Sholo.CommandLine/Context/ICommandServicesContext.cs index 85f6bdc..8e2a1d4 100644 --- a/Source/Sholo.CommandLine/Context/ICommandServicesContext.cs +++ b/Source/Sholo.CommandLine/Context/ICommandServicesContext.cs @@ -3,19 +3,21 @@ using Microsoft.Extensions.Logging; // ReSharper disable UnusedMemberInSuper.Global -namespace Sholo.CommandLine.Context +namespace Sholo.CommandLine.Context; + +public interface ICommandServicesContext { - public interface ICommandServicesContext - { - ILoggerFactory LoggerFactory { get; } - IConfiguration HostConfiguration { get; } - IConfiguration CommandConfiguration { get; } - IServiceProvider HostServices { get; } - } + string CommandName { get; } + string Description { get; } + + ILoggerFactory LoggerFactory { get; } + IConfiguration HostConfiguration { get; } + IConfiguration CommandConfiguration { get; } + IServiceProvider HostServices { get; } +} - public interface ICommandServicesContext : ICommandServicesContext - where TParameters : class, new() - { - TParameters Parameters { get; } - } +public interface ICommandServicesContext : ICommandServicesContext + where TParameters : class, new() +{ + TParameters Parameters { get; } } diff --git a/Source/Sholo.CommandLine/Context/IHostContext.cs b/Source/Sholo.CommandLine/Context/IHostContext.cs index c509d13..6bd74e0 100644 --- a/Source/Sholo.CommandLine/Context/IHostContext.cs +++ b/Source/Sholo.CommandLine/Context/IHostContext.cs @@ -1,6 +1,5 @@ -namespace Sholo.CommandLine.Context +namespace Sholo.CommandLine.Context; + +public interface IHostContext { - public interface IHostContext - { - } } diff --git a/Source/Sholo.CommandLine/Context/IHostLoggingContext.cs b/Source/Sholo.CommandLine/Context/IHostLoggingContext.cs new file mode 100644 index 0000000..47f1217 --- /dev/null +++ b/Source/Sholo.CommandLine/Context/IHostLoggingContext.cs @@ -0,0 +1,10 @@ +using System; +using Microsoft.Extensions.Configuration; + +namespace Sholo.CommandLine.Context; + +public interface IHostLoggingContext +{ + IConfiguration HostConfiguration { get; } + IServiceProvider HostServices { get; } +} diff --git a/Source/Sholo.CommandLine/Context/IHostServicesContext.cs b/Source/Sholo.CommandLine/Context/IHostServicesContext.cs index 25b67d4..f2dce34 100644 --- a/Source/Sholo.CommandLine/Context/IHostServicesContext.cs +++ b/Source/Sholo.CommandLine/Context/IHostServicesContext.cs @@ -1,10 +1,9 @@ using Microsoft.Extensions.Configuration; // ReSharper disable UnusedMemberInSuper.Global -namespace Sholo.CommandLine.Context +namespace Sholo.CommandLine.Context; + +public interface IHostServicesContext { - public interface IHostServicesContext - { - IConfigurationRoot HostConfiguration { get; } - } + IConfigurationRoot HostConfiguration { get; } } diff --git a/Source/Sholo.CommandLine/Context/IPluginConfigurationContext.cs b/Source/Sholo.CommandLine/Context/IPluginConfigurationContext.cs index 534ba35..1a49138 100644 --- a/Source/Sholo.CommandLine/Context/IPluginConfigurationContext.cs +++ b/Source/Sholo.CommandLine/Context/IPluginConfigurationContext.cs @@ -4,24 +4,26 @@ using Microsoft.Extensions.Logging; // ReSharper disable UnusedMemberInSuper.Global -namespace Sholo.CommandLine.Context + +namespace Sholo.CommandLine.Context; + +[PublicAPI] +public interface IPluginConfigurationContext { - public interface IPluginConfigurationContext - { - IConfigurationRoot HostConfiguration { get; } - IServiceProvider HostServices { get; } - Action ConfigureLogBuilder { get; } - Action ConfigureCommonConfiguration { get; } - Action ConfigureCommonCommandServices { get; } - } + IConfigurationRoot HostConfiguration { get; } + IServiceProvider HostServices { get; } + Action ConfigureLogBuilder { get; } + Action ConfigureCommonConfiguration { get; } + Action ConfigureCommonCommandServices { get; } +} - public interface IPluginConfigurationContext - where TCommandParameters : class, new() - { - IConfigurationRoot HostConfiguration { get; } - IServiceProvider HostServices { get; } - Action ConfigureLogBuilder { get; } - Action ConfigureCommonConfiguration { get; } - Action, IServiceCollection> ConfigureCommonCommandServices { get; } - } +[PublicAPI] +public interface IPluginConfigurationContext + where TCommandParameters : class, new() +{ + IConfigurationRoot HostConfiguration { get; } + IServiceProvider HostServices { get; } + Action ConfigureLogBuilder { get; } + Action ConfigureCommonConfiguration { get; } + Action, IServiceCollection> ConfigureCommonCommandServices { get; } } diff --git a/Source/Sholo.CommandLine/Context/PluginConfigurationContext.cs b/Source/Sholo.CommandLine/Context/PluginConfigurationContext.cs index 6dcfe0d..bb5d799 100644 --- a/Source/Sholo.CommandLine/Context/PluginConfigurationContext.cs +++ b/Source/Sholo.CommandLine/Context/PluginConfigurationContext.cs @@ -4,46 +4,46 @@ using Microsoft.Extensions.Logging; // ReSharper disable UnusedMember.Global -namespace Sholo.CommandLine.Context +namespace Sholo.CommandLine.Context; + +internal class PluginConfigurationContext : BasePluginConfigurationContext, IPluginConfigurationContext { - internal class PluginConfigurationContext : BasePluginConfigurationContext, IPluginConfigurationContext - { - public Action ConfigureCommonCommandServices { get; } + public Action ConfigureCommonCommandServices { get; } - public PluginConfigurationContext( - IConfigurationRoot hostConfiguration, - IServiceProvider hostServices, - Action configureLogBuilder, - Action configureCommonConfiguration, - Action configureCommonCommandServices) - : base( - hostConfiguration, - hostServices, - configureLogBuilder, - configureCommonConfiguration) - { - ConfigureCommonCommandServices = configureCommonCommandServices; - } + public PluginConfigurationContext( + IConfigurationRoot hostConfiguration, + IServiceProvider hostServices, + Action configureLogBuilder, + Action configureCommonConfiguration, + Action configureCommonCommandServices) + : base( + hostConfiguration, + hostServices, + configureLogBuilder, + configureCommonConfiguration) + { + ConfigureCommonCommandServices = configureCommonCommandServices; } +} - internal class PluginConfigurationContext : BasePluginConfigurationContext, IPluginConfigurationContext - where TCommandParameters : class, new() - { - public Action, IServiceCollection> ConfigureCommonCommandServices { get; } +// ReSharper disable once UnusedType.Global - TODO: WiP +internal class PluginConfigurationContext : BasePluginConfigurationContext, IPluginConfigurationContext + where TCommandParameters : class, new() +{ + public Action, IServiceCollection> ConfigureCommonCommandServices { get; } - public PluginConfigurationContext( - IConfigurationRoot hostConfiguration, - IServiceProvider hostServices, - Action configureLogBuilder, - Action configureCommonConfiguration, - Action, IServiceCollection> configureCommonCommandServices) - : base( - hostConfiguration, - hostServices, - configureLogBuilder, - configureCommonConfiguration) - { - ConfigureCommonCommandServices = configureCommonCommandServices; - } + public PluginConfigurationContext( + IConfigurationRoot hostConfiguration, + IServiceProvider hostServices, + Action configureLogBuilder, + Action configureCommonConfiguration, + Action, IServiceCollection> configureCommonCommandServices) + : base( + hostConfiguration, + hostServices, + configureLogBuilder, + configureCommonConfiguration) + { + ConfigureCommonCommandServices = configureCommonCommandServices; } } diff --git a/Source/Sholo.CommandLine/GlobalUsings.cs b/Source/Sholo.CommandLine/GlobalUsings.cs new file mode 100644 index 0000000..f3b5eaa --- /dev/null +++ b/Source/Sholo.CommandLine/GlobalUsings.cs @@ -0,0 +1,3 @@ +// Global using directives + +global using JetBrains.Annotations; \ No newline at end of file diff --git a/Source/Sholo.CommandLine/ICommandLineApp.cs b/Source/Sholo.CommandLine/ICommandLineApp.cs index dfc28ac..50f5b8c 100644 --- a/Source/Sholo.CommandLine/ICommandLineApp.cs +++ b/Source/Sholo.CommandLine/ICommandLineApp.cs @@ -2,10 +2,9 @@ using System.Threading.Tasks; // ReSharper disable UnusedMember.Global -namespace Sholo.CommandLine +namespace Sholo.CommandLine; + +public interface ICommandLineApp { - public interface ICommandLineApp - { - Task ExecuteAsync(string[] args, CancellationToken cancellationToken = default); - } + Task ExecuteAsync(string[] args, CancellationToken cancellationToken = default); } diff --git a/Source/Sholo.CommandLine/ICommandLineAppBuilder.cs b/Source/Sholo.CommandLine/ICommandLineAppBuilder.cs index 89816e0..76a94e5 100644 --- a/Source/Sholo.CommandLine/ICommandLineAppBuilder.cs +++ b/Source/Sholo.CommandLine/ICommandLineAppBuilder.cs @@ -5,24 +5,17 @@ using Sholo.CommandLine.Context; // ReSharper disable UnusedMember.Global -namespace Sholo.CommandLine -{ - public interface ICommandLineAppBuilder - where TSelf : ICommandLineAppBuilder - { - TSelf WithName(string name); - TSelf WithDescription(string description); - TSelf ConfigureHostConfiguration(Action configuration); - TSelf ConfigureLogging(Action loggingConfiguration); - TSelf ConfigureHostServices(Action services); - TSelf ConfigureCommonCommandConfiguration(Action configuration); - TSelf ConfigureCommonCommandServices(Action services); - - // TSelf WithCommand() - // where TCommandPlugin : class, TCommandPluginInterface, new(); +namespace Sholo.CommandLine; - // TSelf WithCommand(Action configurator); - - // ICommandLineApp Build(); - } +[PublicAPI] +public interface ICommandLineAppBuilder + where TSelf : ICommandLineAppBuilder +{ + TSelf WithName(string name); + TSelf WithDescription(string description); + TSelf ConfigureHostConfiguration(Action configuration); + TSelf ConfigureLogging(Action loggingConfiguration); + TSelf ConfigureHostServices(Action services); + TSelf ConfigureCommonCommandConfiguration(Action configuration); + TSelf ConfigureCommonCommandServices(Action services); } diff --git a/Source/Sholo.CommandLine/Sholo.CommandLine.csproj b/Source/Sholo.CommandLine/Sholo.CommandLine.csproj index b5ba853..a02d4c0 100644 --- a/Source/Sholo.CommandLine/Sholo.CommandLine.csproj +++ b/Source/Sholo.CommandLine/Sholo.CommandLine.csproj @@ -1,15 +1,23 @@ - netstandard2.0 + net7.0 - - - - - + + + + + + + + + + + + +