fix: switch from RootCommand to Command to handle stripped executables
This commit is contained in:
parent
6b03ca4c28
commit
e5e87770f9
6 changed files with 41 additions and 9 deletions
|
@ -13,7 +13,15 @@ namespace MfGames.ToolBuilder
|
||||||
string[] arguments,
|
string[] arguments,
|
||||||
TType defaultValue)
|
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,
|
option,
|
||||||
};
|
};
|
||||||
|
|
|
@ -78,7 +78,7 @@ namespace MfGames.ToolBuilder.Globals
|
||||||
/// Adds the common options to the command.
|
/// Adds the common options to the command.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="root"></param>
|
/// <param name="root"></param>
|
||||||
public void AddOptions(RootCommand root)
|
public void AddOptions(Command root)
|
||||||
{
|
{
|
||||||
root.AddGlobalOption(this.ConfigOption);
|
root.AddGlobalOption(this.ConfigOption);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace MfGames.ToolBuilder.Globals
|
||||||
/// Adds the common options to the command.
|
/// Adds the common options to the command.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="root"></param>
|
/// <param name="root"></param>
|
||||||
public void AddOptions(RootCommand root)
|
public void AddOptions(Command root)
|
||||||
{
|
{
|
||||||
root.AddGlobalOption(this.LogLevelOption);
|
root.AddGlobalOption(this.LogLevelOption);
|
||||||
}
|
}
|
||||||
|
|
|
@ -410,6 +410,8 @@ namespace MfGames.ToolBuilder.Tables
|
||||||
// Default is mostly like ConsoleTableExt but there is a separator
|
// Default is mostly like ConsoleTableExt but there is a separator
|
||||||
// between the headers because it makes it harder to parse.
|
// between the headers because it makes it harder to parse.
|
||||||
builder
|
builder
|
||||||
|
.WithPaddingLeft(string.Empty)
|
||||||
|
.WithPaddingRight(string.Empty)
|
||||||
.WithCharMapDefinition(
|
.WithCharMapDefinition(
|
||||||
new Dictionary<CharMapPositions, char>
|
new Dictionary<CharMapPositions, char>
|
||||||
{
|
{
|
||||||
|
@ -418,7 +420,7 @@ namespace MfGames.ToolBuilder.Tables
|
||||||
.WithHeaderCharMapDefinition(
|
.WithHeaderCharMapDefinition(
|
||||||
new Dictionary<HeaderCharMapPositions, char>
|
new Dictionary<HeaderCharMapPositions, char>
|
||||||
{
|
{
|
||||||
{ HeaderCharMapPositions.BottomCenter, '+' },
|
{ HeaderCharMapPositions.BottomCenter, ' ' },
|
||||||
{ HeaderCharMapPositions.Divider, ' ' },
|
{ HeaderCharMapPositions.Divider, ' ' },
|
||||||
{ HeaderCharMapPositions.BorderBottom, '-' },
|
{ HeaderCharMapPositions.BorderBottom, '-' },
|
||||||
});
|
});
|
||||||
|
|
|
@ -165,6 +165,12 @@ namespace MfGames.ToolBuilder
|
||||||
.AsSelf()
|
.AsSelf()
|
||||||
.SingleInstance();
|
.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.
|
// Register the components required to make the CLI work.
|
||||||
builder.RegisterModule<ToolBuilderModule>();
|
builder.RegisterModule<ToolBuilderModule>();
|
||||||
}
|
}
|
||||||
|
@ -174,7 +180,14 @@ namespace MfGames.ToolBuilder
|
||||||
IServiceCollection services)
|
IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddAutofac();
|
services.AddAutofac();
|
||||||
services.AddHostedService<ToolService>();
|
}
|
||||||
|
|
||||||
|
private ToolService CreateToolService(IComponentContext context)
|
||||||
|
{
|
||||||
|
var factory = context.Resolve<ToolService.Factory>();
|
||||||
|
var service = factory(this.InternalName);
|
||||||
|
|
||||||
|
return service;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@ namespace MfGames.ToolBuilder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ToolService : IHostedService
|
public class ToolService : IHostedService
|
||||||
{
|
{
|
||||||
|
private readonly string cliName;
|
||||||
|
|
||||||
private readonly IList<ITopCommand> commands;
|
private readonly IList<ITopCommand> commands;
|
||||||
|
|
||||||
private readonly ConfigToolGlobalService configService;
|
private readonly ConfigToolGlobalService configService;
|
||||||
|
@ -36,12 +38,15 @@ namespace MfGames.ToolBuilder
|
||||||
private readonly LoggingToolGlobalService loggingService;
|
private readonly LoggingToolGlobalService loggingService;
|
||||||
|
|
||||||
public ToolService(
|
public ToolService(
|
||||||
|
string cliName,
|
||||||
ILogger logger,
|
ILogger logger,
|
||||||
IHostApplicationLifetime lifetime,
|
IHostApplicationLifetime lifetime,
|
||||||
IList<ITopCommand> commands,
|
IList<ITopCommand> commands,
|
||||||
ConfigToolGlobalService configService,
|
ConfigToolGlobalService configService,
|
||||||
LoggingToolGlobalService loggingService)
|
LoggingToolGlobalService loggingService)
|
||||||
{
|
{
|
||||||
|
this.cliName = cliName
|
||||||
|
?? throw new ArgumentNullException(nameof(cliName));
|
||||||
this.lifetime = lifetime;
|
this.lifetime = lifetime;
|
||||||
this.commands = commands;
|
this.commands = commands;
|
||||||
this.configService = configService;
|
this.configService = configService;
|
||||||
|
@ -49,6 +54,8 @@ namespace MfGames.ToolBuilder
|
||||||
this.logger = logger.ForContext<ToolService>();
|
this.logger = logger.ForContext<ToolService>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public delegate ToolService Factory(string cliName);
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Task StartAsync(CancellationToken cancellationToken)
|
public Task StartAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
@ -71,11 +78,13 @@ namespace MfGames.ToolBuilder
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private RootCommand CreateRootCommand()
|
private Command CreateRootCommand()
|
||||||
{
|
{
|
||||||
// Create the root command and add in the top-level commands
|
// Create the root command and add in the top-level commands
|
||||||
// underneath it.
|
// underneath it. We can't use the "real" `RootCommand` here because
|
||||||
var root = new RootCommand();
|
// 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)
|
foreach (var command in this.commands)
|
||||||
{
|
{
|
||||||
|
@ -116,7 +125,7 @@ namespace MfGames.ToolBuilder
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Build the command tree.
|
// Build the command tree.
|
||||||
RootCommand root = this.CreateRootCommand();
|
Command root = this.CreateRootCommand();
|
||||||
string[] args = Environment.GetCommandLineArgs();
|
string[] args = Environment.GetCommandLineArgs();
|
||||||
|
|
||||||
// Execute the command.
|
// Execute the command.
|
||||||
|
|
Reference in a new issue