diff --git a/src/MfGames.ToolBuilder/GlobalOptionHelper.cs b/src/MfGames.ToolBuilder/GlobalOptionHelper.cs index 824ffbe..7c83ddd 100644 --- a/src/MfGames.ToolBuilder/GlobalOptionHelper.cs +++ b/src/MfGames.ToolBuilder/GlobalOptionHelper.cs @@ -13,7 +13,15 @@ namespace MfGames.ToolBuilder string[] arguments, TType defaultValue) { - var rootCommand = new RootCommand + // Normally, we should be using `RootCommand` here because it does + // the "right" thing with regards to picking up the executable name + // and path from the environment. However, it appears when the + // library/executable is stripped, it blows up. So we use Command + // directly and fake the RootCommand. + // + // We don't need a "real" executable name here, so we just hard-code + // a faked one. + var rootCommand = new Command("_executable", string.Empty) { option, }; diff --git a/src/MfGames.ToolBuilder/Globals/ConfigToolGlobalService.cs b/src/MfGames.ToolBuilder/Globals/ConfigToolGlobalService.cs index 426fec5..46013d2 100644 --- a/src/MfGames.ToolBuilder/Globals/ConfigToolGlobalService.cs +++ b/src/MfGames.ToolBuilder/Globals/ConfigToolGlobalService.cs @@ -78,7 +78,7 @@ namespace MfGames.ToolBuilder.Globals /// Adds the common options to the command. /// /// - public void AddOptions(RootCommand root) + public void AddOptions(Command root) { root.AddGlobalOption(this.ConfigOption); } diff --git a/src/MfGames.ToolBuilder/Globals/LoggingToolGlobalService.cs b/src/MfGames.ToolBuilder/Globals/LoggingToolGlobalService.cs index a6ff6e8..c8b5809 100644 --- a/src/MfGames.ToolBuilder/Globals/LoggingToolGlobalService.cs +++ b/src/MfGames.ToolBuilder/Globals/LoggingToolGlobalService.cs @@ -34,7 +34,7 @@ namespace MfGames.ToolBuilder.Globals /// Adds the common options to the command. /// /// - public void AddOptions(RootCommand root) + public void AddOptions(Command root) { root.AddGlobalOption(this.LogLevelOption); } diff --git a/src/MfGames.ToolBuilder/Tables/TableToolService.cs b/src/MfGames.ToolBuilder/Tables/TableToolService.cs index b545162..e1d572c 100644 --- a/src/MfGames.ToolBuilder/Tables/TableToolService.cs +++ b/src/MfGames.ToolBuilder/Tables/TableToolService.cs @@ -410,6 +410,8 @@ namespace MfGames.ToolBuilder.Tables // Default is mostly like ConsoleTableExt but there is a separator // between the headers because it makes it harder to parse. builder + .WithPaddingLeft(string.Empty) + .WithPaddingRight(string.Empty) .WithCharMapDefinition( new Dictionary { @@ -418,7 +420,7 @@ namespace MfGames.ToolBuilder.Tables .WithHeaderCharMapDefinition( new Dictionary { - { HeaderCharMapPositions.BottomCenter, '+' }, + { HeaderCharMapPositions.BottomCenter, ' ' }, { HeaderCharMapPositions.Divider, ' ' }, { HeaderCharMapPositions.BorderBottom, '-' }, }); diff --git a/src/MfGames.ToolBuilder/ToolBuilder.cs b/src/MfGames.ToolBuilder/ToolBuilder.cs index 572e373..fa8f202 100644 --- a/src/MfGames.ToolBuilder/ToolBuilder.cs +++ b/src/MfGames.ToolBuilder/ToolBuilder.cs @@ -165,6 +165,12 @@ namespace MfGames.ToolBuilder .AsSelf() .SingleInstance(); + // Register the tool service since we have to use the factory to + // use it. + builder + .Register(this.CreateToolService) + .SingleInstance(); + // Register the components required to make the CLI work. builder.RegisterModule(); } @@ -174,7 +180,14 @@ namespace MfGames.ToolBuilder IServiceCollection services) { services.AddAutofac(); - services.AddHostedService(); + } + + private ToolService CreateToolService(IComponentContext context) + { + var factory = context.Resolve(); + var service = factory(this.InternalName); + + return service; } } } diff --git a/src/MfGames.ToolBuilder/ToolService.cs b/src/MfGames.ToolBuilder/ToolService.cs index d699b04..1448fd0 100644 --- a/src/MfGames.ToolBuilder/ToolService.cs +++ b/src/MfGames.ToolBuilder/ToolService.cs @@ -25,6 +25,8 @@ namespace MfGames.ToolBuilder /// public class ToolService : IHostedService { + private readonly string cliName; + private readonly IList commands; private readonly ConfigToolGlobalService configService; @@ -36,12 +38,15 @@ namespace MfGames.ToolBuilder private readonly LoggingToolGlobalService loggingService; public ToolService( + string cliName, ILogger logger, IHostApplicationLifetime lifetime, IList commands, ConfigToolGlobalService configService, LoggingToolGlobalService loggingService) { + this.cliName = cliName + ?? throw new ArgumentNullException(nameof(cliName)); this.lifetime = lifetime; this.commands = commands; this.configService = configService; @@ -49,6 +54,8 @@ namespace MfGames.ToolBuilder this.logger = logger.ForContext(); } + public delegate ToolService Factory(string cliName); + /// public Task StartAsync(CancellationToken cancellationToken) { @@ -71,11 +78,13 @@ namespace MfGames.ToolBuilder return Task.CompletedTask; } - private RootCommand CreateRootCommand() + private Command CreateRootCommand() { // Create the root command and add in the top-level commands - // underneath it. - var root = new RootCommand(); + // underneath it. We can't use the "real" `RootCommand` here because + // it doesn't work in stripped executables (because this is a + // library) so we fake it with a "normal" command. + var root = new Command(this.cliName, string.Empty); foreach (var command in this.commands) { @@ -116,7 +125,7 @@ namespace MfGames.ToolBuilder try { // Build the command tree. - RootCommand root = this.CreateRootCommand(); + Command root = this.CreateRootCommand(); string[] args = Environment.GetCommandLineArgs(); // Execute the command.