Skip to content

Conversation

@dusrdev
Copy link
Contributor

@dusrdev dusrdev commented Nov 18, 2025

Previously, when a root command and other commands were registered, executing the CLI with no arguments would output only the root command's help text, omitting the other available commands.

This behavior was inconsistent with running -h | --help, which correctly displayed the global help text including all command descriptions.

This PR fixes this inconsistency to better align with common CLI semantics. Now, when the CLI is run with no arguments, it displays the global help text, assuming the user is requesting usage guidelines.

And it adds tests for this scenario.

@neuecc
Copy link
Member

neuecc commented Nov 19, 2025

In this case, wouldn't there be no way to call the root command?

var app = ConsoleApp.Create();
app.Add("", () => Console.WriteLine("foo"));
app.Add("a", (int x, int y) => { });
app.Add("ab", (int x, int y) => { });
app.Add("a b c", (int x, int y) => { });
app.Run(args);

@dusrdev
Copy link
Contributor Author

dusrdev commented Nov 19, 2025

@neuecc about:

In this case, wouldn't there be no way to call the root command?

The root command will be called if there are arguments/options specific to it in the input. But yes, if the user wants to trigger a no args root command this will not work as in your example.

It would require the user to hack this in some form like:

// Add "default" command

if (args.Length == 0) args = ["default"];

or if he wants to hide this from help:

app.Add("", ([Hidden] bool trigger) => Console.WriteLine("foo"));

if (args.Length == 0) args = ["--trigger"];

The question is which convention is better to support by default, git, rm, docker, cargo - all of them just trigger the global help text when there is no args... dotnet and curl trigger a more minimal version of the help.

If you wanted to support both, It is possible to add a static toggle ConsoleApp.ShowHelpOnEmptyInput and set to the default you decide, and take it into account in Emitter.EmitRunBody. Then no user hacks would be necessary.

@neuecc
Copy link
Member

neuecc commented Nov 19, 2025

I have concerns about losing the ability to call no-args root commands directly.
Not being able to execute root commands is a deal-breaker.
I'm against adding configuration options - the complexity trade-off isn't worth it, and we should have a single default behavior.

My proposal:

  • If the root command has no parameters (or only optional parameters) → execute it (current behavior)
  • If the root command has required parameters → show global help (your improvement)
  • If no root command is registered → show global help (your improvement)

What do you think?

@dusrdev
Copy link
Contributor Author

dusrdev commented Nov 19, 2025

  • If the root command has required parameters → show global help (your improvement)
  • If no root command is registered → show global help (your improvement)

Both of these are also current behavior.

So scrap the PR for now?

@neuecc
Copy link
Member

neuecc commented Nov 19, 2025

If the root command has required parameters → show global help (your improvement)

Currently, the behavior in this case shows the help for the root command, not the global help (the command list is not displayed).
So the behavior differs between the PR and the current implementation.

Also, in reality, I think the root command in applications built with multiple commands + a root command will have required parameters, so I believe most cases will follow your suggestion...

@dusrdev
Copy link
Contributor Author

dusrdev commented Nov 19, 2025

Currently, the behavior in this case shows the help for the root command, not the global help (the command list is not displayed).

You're right, I'll make the changes.

@dusrdev
Copy link
Contributor Author

dusrdev commented Nov 19, 2025

I added RequiredParsableParameterCount to CommandWithId so that we cache this and remove the complicated calculations.

This also simplifies the branch in EmitRunBody and will show global help text when there is a root command that requires parameters.

@neuecc
Copy link
Member

neuecc commented Nov 19, 2025

OK, thanks!

@neuecc neuecc merged commit cc68b96 into Cysharp:master Nov 19, 2025
1 check passed
@dusrdev
Copy link
Contributor Author

dusrdev commented Nov 19, 2025

@neuecc Thanks for merging! by the way, I tried emailing you at [email protected] from your profile but I’m not sure it is still in use. Is there a better way to reach you privately?

@neuecc
Copy link
Member

neuecc commented Nov 19, 2025

Oh, the email is alive.
I received them on 10/9 and 10/19.
Sorry for not replying...!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants