Inherited commands for processing global options #1831
-
|
I might be asking a question that has already been asked, or don't know the proper/better way to approach this. Basically I have this option at the top level that all commands need access to, I have implemented an inheritance structure that works at the top level (with no subcommands/branches), but when I go down a command branch, the top-level code doesn't run. I'm confused as to why and can't seem to figure out what is going on. Here is my Main function where the commands are registered. public static async Task<int> Main(string[] args)
{
IServiceCollection services = App.ConfigureServices();
using DependencyInjectionRegistrar? registrar = new DependencyInjectionRegistrar(services);
CommandApp<App> app = new CommandApp<App>(registrar);
app.Configure(static config =>
{
config.PropagateExceptions();
config.ValidateExamples();
config.SetApplicationName("pseudoseer");
config.AddBranch<UserSettings>("user", static user =>
{
user.SetDescription("Manage users in the database");
user.AddCommand<ListUsers>("list")
.WithAlias("ls")
.WithDescription("List users in the database");
user.AddCommand<CreateUser>("create")
.WithDescription("Create a new user");
});
});
return await app.RunAsync(args);
}Below is my top level default command and settings for it. public class AppSettings : CommandSettings
{
[CommandOption("-d|--database-path")]
public string? DatabasePath { get; set; }
}
public class App : AppCommand<AppSettings>
{
public App(AppContext appContext) : base(appContext)
{
}
protected override Task<int> ExecuteCommandAsync([NotNull] CommandContext context, [NotNull] AppSettings settings)
{
return Task.FromResult(0);
}
public static IServiceCollection ConfigureServices()
{
IServiceCollection services = new ServiceCollection();
services.AddSingleton<AppContext>();
services.AddDbContextFactory<ApplicationDbContext>((serviceProvider, options) =>
{
AppContext appContext = serviceProvider.GetRequiredService<AppContext>();
options.UseSqlite(appContext.ConnectionString);
});
services.AddDataProtection();
services.AddIdentityCore<ApplicationUser>(options =>
{
options.SignIn.RequireConfirmedAccount = true;
options.User.RequireUniqueEmail = true;
})
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
return services;
}Here is my base command: public abstract class AppCommand<TSettings> : AsyncCommand<TSettings> where TSettings : AppSettings
{
protected readonly AppContext _appContext;
protected AppCommand(AppContext appContext)
{
_appContext = appContext;
}
public override async Task<int> ExecuteAsync(CommandContext context, TSettings settings)
{
AnsiConsole.WriteLine(settings.DatabasePath);
if (_appContext != null && !_appContext.IsInitialised)
{
_appContext.Initialise(databasePath: settings.DatabasePath);
}
return await ExecuteCommandAsync(context, settings);
}
protected abstract Task<int> ExecuteCommandAsync(CommandContext context, TSettings settings);
}And below is a command branch and a command for that branch: public class UserSettings : AppSettings
{
}
public class UserCommand : AppCommand<UserSettings>
{
public UserCommand(AppContext appContext) : base(appContext)
{
}
protected override async Task<int> ExecuteCommandAsync([NotNull] CommandContext context, [NotNull] UserSettings settings)
{
return await Task.FromResult(0);
}
}
//===========
public class ListUsersSettings : UserSettings
{
//...
}
public class ListUsers : AppCommand<ListUsersSettings>
{
public ListUsers(AppContext appContext) : base(appContext) { }
protected override async Task<int> ExecuteCommandAsync([NotNull] CommandContext context, [NotNull] ListUsersSettings settings)
{
AnsiConsole.MarkupLine("Hello [green]World[/]");
// TODO: Fill this out, need to interact with AspNetCore Identity and get all users
// and filter by roles.
return await Task.FromResult(0);
}
}And to show what I mean as to why I'm confused: According to how I believe the inheritance works and how the parsing works, this should be a valid working option |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
|
This seems to be a bug. I opened an issue at: https://github.com/spectreconsole/spectre.console/issues/1833 |
Beta Was this translation helpful? Give feedback.
-
|
Oh cool, wasn't expecting to run into that. Will look further into it, maybe I can find a solution and make a PR |
Beta Was this translation helpful? Give feedback.
This seems to be a bug.
I opened an issue at: https://github.com/spectreconsole/spectre.console/issues/1833