bilal-fazlani / commanddotnet

A modern framework for building modern CLI apps
https://commanddotnet.bilal-fazlani.com
MIT License
570 stars 29 forks source link

System.InvalidCastException: Unable to cast object of type 'CommandDotNet.Command' to type 'CommandDotNet.Option'. #346

Closed poison2k closed 3 years ago

poison2k commented 3 years ago

Hello I have the current Problem: if a user tried to use a known command with leading -- I get an error.

I am using Oracle Linux with .netcore 3.1.1. All other defined commands and options running perfect.

Example: myapp has some known commands myapp setup myapp update myapp do something

If I use now: myapp --setup or myapp --update or myapp do --something

I get the Error on end of my post:


Update 30.07.2021 I can reproduce the error on Windows and with the CommandDotNet.Example App in this git repo If you use the following command of the example app:

CommandDotNet.Example.exe git commit all works fine, but if you enter CommandDotNet.Example.exe git **--commit** The program runs in the same parse error.

So I would say this is a real bug and must be fixed.


System.InvalidCastException: Unable to cast object of type 'CommandDotNet.Command' to type 'CommandDotNet.Option'.
   at CommandDotNet.Command.Find[TArgumentNode](String alias) in CommandDotNet/Command.cs:line 121
   at CommandDotNet.Parsing.CommandParser.ParseOption(ParseContext parseContext, Token token) in CommandDotNet/Parsing/CommandParser.cs:line 91
   at CommandDotNet.Parsing.CommandParser.ParseCommand(CommandContext commandContext, ParseContext parseContext) in CommandDotNet/Parsing/CommandParser.cs:line 36
   at CommandDotNet.Parsing.CommandParser.ParseInputMiddleware(CommandContext commandContext, ExecutionDelegate next) in CommandDotNet/Parsing/CommandParser.cs:line 17
   at CommandDotNet.Execution.ExecutionMiddlewareExtensions.<>c__DisplayClass1_1.<InvokePipeline>b__3(CommandContext c) in CommandDotNet/Execution/ExecutionMiddlewareExtensions.cs:line 27
   at CommandDotNet.ClassModeling.ClassModelingMiddleware.CreateRootCommand(CommandContext commandContext, ExecutionDelegate next) in CommandDotNet/ClassModeling/ClassModelingMiddleware.cs:line 39
   at CommandDotNet.Execution.ExecutionMiddlewareExtensions.<>c__DisplayClass1_1.<InvokePipeline>b__3(CommandContext c) in CommandDotNet/Execution/ExecutionMiddlewareExtensions.cs:line 27
   at CommandDotNet.Tokens.TokenizerPipeline.TokenizeInputMiddleware(CommandContext commandContext, ExecutionDelegate next) in CommandDotNet/Tokens/TokenizerPipeline.cs:line 24
   at CommandDotNet.Execution.ExecutionMiddlewareExtensions.<>c__DisplayClass1_1.<InvokePipeline>b__3(CommandContext c) in CommandDotNet/Execution/ExecutionMiddlewareExtensions.cs:line 27
   at CommandDotNet.Help.HelpMiddleware.PrintHelp(CommandContext ctx, ExecutionDelegate next) in CommandDotNet/Help/HelpMiddleware.cs:line 72
   at CommandDotNet.Execution.ExecutionMiddlewareExtensions.<>c__DisplayClass1_1.<InvokePipeline>b__3(CommandContext c) in CommandDotNet/Execution/ExecutionMiddlewareExtensions.cs:line 27
   at CommandDotNet.AppRunner.OnRunCompleted(CommandContext context, ExecutionDelegate next) in CommandDotNet/AppRunner.cs:line 141
   at CommandDotNet.Execution.ExecutionMiddlewareExtensions.<>c__DisplayClass1_0.<InvokePipeline>b__2(CommandContext ctx, ExecutionDelegate next) in CommandDotNet/Execution/ExecutionMiddlewareExtensions.cs:line 17
   at CommandDotNet.Execution.ExecutionMiddlewareExtensions.<>c__DisplayClass1_0.<InvokePipeline>b__2(CommandContext ctx, ExecutionDelegate next) in CommandDotNet/Execution/ExecutionMiddlewareExtensions.cs:line 17
   at CommandDotNet.Execution.ExecutionMiddlewareExtensions.<>c__DisplayClass1_0.<InvokePipeline>b__2(CommandContext ctx, ExecutionDelegate next) in CommandDotNet/Execution/ExecutionMiddlewareExtensions.cs:line 17
   at CommandDotNet.Execution.ExecutionMiddlewareExtensions.<>c__DisplayClass1_0.<InvokePipeline>b__2(CommandContext ctx, ExecutionDelegate next) in CommandDotNet/Execution/ExecutionMiddlewareExtensions.cs:line 17
   at CommandDotNet.Execution.ExecutionMiddlewareExtensions.<>c__DisplayClass1_0.<InvokePipeline>b__2(CommandContext ctx, ExecutionDelegate next) in CommandDotNet/Execution/ExecutionMiddlewareExtensions.cs:line 17
   at CommandDotNet.Execution.ExecutionMiddlewareExtensions.<>c__DisplayClass1_0.<InvokePipeline>b__2(CommandContext ctx, ExecutionDelegate next) in CommandDotNet/Execution/ExecutionMiddlewareExtensions.cs:line 17
   at CommandDotNet.Execution.ExecutionMiddlewareExtensions.<>c__DisplayClass1_0.<InvokePipeline>b__2(CommandContext ctx, ExecutionDelegate next) in CommandDotNet/Execution/ExecutionMiddlewareExtensions.cs:line 17
   at CommandDotNet.Execution.ExecutionMiddlewareExtensions.<>c__DisplayClass1_0.<InvokePipeline>b__2(CommandContext ctx, ExecutionDelegate next) in CommandDotNet/Execution/ExecutionMiddlewareExtensions.cs:line 17
   at CommandDotNet.Execution.ExecutionMiddlewareExtensions.<>c__DisplayClass1_0.<InvokePipeline>b__2(CommandContext ctx, ExecutionDelegate next) in CommandDotNet/Execution/ExecutionMiddlewareExtensions.cs:line 17
   at CommandDotNet.Execution.ExecutionMiddlewareExtensions.InvokePipeline(IEnumerable`1 pipeline, CommandContext commandContext) in CommandDotNet/Execution/ExecutionMiddlewareExtensions.cs:line 33
   at CommandDotNet.AppRunner.Run(String[] args) in CommandDotNet/AppRunner.cs:line 77
--- End of stack trace from previous location where exception was thrown ---
   at CommandDotNet.AppRunner.HandleException(Exception ex, IConsole console, CommandContext commandContext) in CommandDotNet/AppRunner.cs:line 162
   at CommandDotNet.AppRunner.Run(String[] args) in CommandDotNet/AppRunner.cs:line 83
poison2k commented 3 years ago

Updated Issue report after I can reproduce the error on Windwos with CommandDotNet.Example App

drewburlingame commented 3 years ago

Thank you for posting this. I will investigate over the weekend.

drewburlingame commented 3 years ago

Good catch. This one was easy to test and resolve. The framework will now fail with a suggestion to remove the prefix. @poison2k I'm considering a few different options.

If you look at git branch, if we git --branch , it prints the unknown option: --branch. I can keep that at the minimum but am considering the following two options for suggestion to the user

Unrecognized option '--branch'. If you intended to use the 'branch' command, try again without the '--'

or

Unrecognized option '--branch'. 
If you intended to use the 'branch' command, try again with the following 

branch

in you last of example of myapp do --something, the latter would be

Unrecognized option '--something'. 
If you intended to use the 'something' command, try again with the following 

myapp do something

Which do you think will be more helpful?

poison2k commented 3 years ago

Hello and thanks for your fast work. I would prefer the last option:

Unrecognized option '--something'. 
If you intended to use the 'something' command, try again with the following 

myapp do something

This is very clear and helps the user to do it the right way.

drewburlingame commented 3 years ago

That's my preference too. I'm doing a simple replace text on what the user entered. If the entered text also includes an option with the same name as the command, that could be unintentionally replaced, but I consider that highly unlikely.

poison2k commented 3 years ago

Works fine, tested is :)

Can you please upload the nuget package file for the 4.1.9 release on nuget.org that I can add it to our build server.

Thank you.

drewburlingame commented 3 years ago

@poison2k we're having some issues with Travis. I've asked @bilal-fazlani to publish CommandDotNet_4.1.9 the package to Nuget in the meantime.

bilal-fazlani commented 3 years ago

nuget https://www.nuget.org/packages/CommandDotNet/4.1.13 just published