Open flupkede opened 2 months ago
An interesting idea.
Although interesting, I think this is outside the scope of the project, and probably more suited as an external extension to Spectre.Console.
Yes, indeed. We still need to think about what other wigets may qualify for it too, and see how a new project/NuGet package for them might be setup.
An external extension would be fine, however it would mean that some of the sealed classes need to become public to be able to achieve this ?
@flupkede What classes would that be?
@patriksvensson , to my understanding which might be wrong. I used public sealed class CommandApp to get the configurator I used internal sealed class CommandConfigurator to get the registered commands.
A recent discussion about this idea FYI, see: https://github.com/spectreconsole/spectre.console/discussions/1610
@flupkede, @patriksvensson - I would be keen to investigate this further, as the idea of future community extensions is of personal interest to me. However @flupkede, I probably won't have spare capacity for another 4 weeks until my current CLI work is complete. Don't hesitate to ping me around that time to ensure this hasn't slipped my mind.
(nb. happy for others to work on this ahead of me, if they wish)
@FrankRay78 I would be more then happy to collaborate on this project, however I will require some of your guidance and direction.
@FrankRay78 I would be more then happy to collaborate on this project, however I will require some of your guidance and direction.
@flupkede I've got a proposal for you, which I will write up shortly for your consideration. My support comes free 😉
Hello @flupkede, apologies for the delay - I had a few things to finish off first. So, I'm not entirely sure why, but I'm personally interested in the idea of extensibility points and enabling community plugins (perhaps more so than other maintainers... 😉). I extended the help provider to make it pluggable, see here, a worthy labour of love. It's not yet entirely done in my eyes, but the foundation has been set.
There is a long-standing, not to be broken, design decision within Spectre.Console that internal, sealed
classes will never be exposed. However, as per the help provider above, exposing necessary functionality through interfaces and DI is allowable, if well reasoned. I've spoken with the other maintainers, and whilst there is no guarantee of merging, I've got the greenlight to proceed with investigating this further, and potentially making the case for exposing necessary interfaces for your Choice menu.
The most mature community extension we currently have is Spectre.Console AutoCompletion, however, that's been implemented without input from the core maintainer team, so the author 'liberated' internal classes (in a similar way to your use of Reflection). Access modifiers were basically turned off on a blanket basis ie:
<PackageReference Include="IgnoresAccessChecksToGenerator" Version="0.6.0" PrivateAssets="All" />
See here.
My proposal to you, and the same I put to the other maintainers, is you could create a repo somewhere for your Choice widget, reference Spectre.Console and turn off access checks by including the above in your project file. Author the widget to a good professional standard, and once done, we'd remove the line from the project file, enforcing access checks to show exactly where the project fails to compile. We would then have a clear understanding of what classes need to be exposed, and could look to POC that through interfaces on a branch.
Baring an unforeseen act of god, I can commit to supporting you with this, up to the point where the Spectre.Console team make their decision. I'd be happy to 'present' the findings of this piece of work, so it doesn't end up ignored. Have a think about it and let me know your thoughts.
Really interesting timing running across this. I've started building another dotnet global tool and naturally Spectre is my first choice as I've used it in the past and have enjoyed it (Thanks!!)
In this new console app, I was searching if there was an existing way to have the app be able to pivot between specifying the full command / branches and options without requiring any interactivity, but I'd also like to have the app intelligent enough to prompt for the information that's required but not specified...
So for instance I'm working on an app to help synchronize dev certificates and profiles for mobile apps...
I might have a command like gizmo create apple certificate --type=Development --common-name="Acme"
. I'd also like the user to be able to invoke the app with gizmo create apple
or gizmo create
or gizmo
and have it prompt for branching selections based on how the CommandApp is composed. So if I start with gizmo create
I get a list of choices (eg: Apple, Google, Token, etc) and as I make choices I navigate the branches.
Similarly I'd like to be able to 'fill in' Command Settings for those not specified. So, prompt for --type
and as an enum, give me the list of choices. If it's text/numeric/etc input, parse out the input from a prompt. The command option description and name could be displayed during this interactive set of prompts. The information is all basically here, we just need a way to drive the experience :)
Unfortunately I won't have any time to help contribute myself, so I'm merely adding a +1 request and some thoughts for how I'd like to use something like this, and will again express my gratitude to everyone who's put effort into this project as I've enjoyed using it.
Hello @Redth, thank you for taking the time to comment above — It's useful context and helps us to gauge community needs. If the app you are working on is open source, would you be kind enough to share the repo URL here? The choice functionality, can of course, be implemented generically, however it would be great to see at least one real world app that's an intended consumer.
Description When we build console programs we often want to invoke them with direct commands and parameters from a commandline, as well as to run them interactively from some kind of menu system to select a command from that you want to run. To achieve this I added a default command "Menu" that shows a numbered list of all the commands and uses a selectionprompt to chose the command. I know the menu system wouldn't handle the command arguments, however we use appsettings a lot.
Describe the solution you'd like It would be nice to have such a command OOB, and if that is a to specific request to have at least the possibility to have somewhere a list of the registered commands available in the context in a way we can also Run them.
Describe alternatives you've considered An awfull solution I quickly put together, however it works for me. It was (at least to my understanding) rather difficult to achieve this currently and I had to do a lot of workaround to make it work, the execute method of the default Menu command: public override int Execute(CommandContext context) { var type = GetType().Assembly.GetName(); _con.MarkupLine($"[yellow]{type.Name} v.{type.Version.Major}.{type.Version.Minor}[/] dotnetcore REST Client"); _con.MarkupLine("[blue]--help for info[/]");
and
public sealed class SelectionCommandItem(byte sequence, string commandTitle, Type commandType, Type settingsType, string executeType) { public byte Sequence { get; } = sequence; public string CommandTitle { get; } = commandTitle; public Type CommandType { get; } = commandType; public Type SettingsType { get; } = settingsType; public string ExecuteType { get; } = executeType; }
Please upvote :+1: this issue if you are interested in it.