dotnet / dotnet/command-line-api

Command handlers are always executed

Offen
#2,013 6 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
Vorherrschende Sprache
C#
Sterne
3.7k
Forks
428
PR-Merge-Kennzahlen
Keine gemergten PRs in 30 T.

Beschreibung

If I run this basic test program(almost verbatim with the MSDN docs), the main argument handler is executed even when no command line arguments are specified at all

```cs
using System.CommandLine;
using Stacks.Parsing;

Option mainArgument = new(
aliases: new string[] { "--main", "-m" },
description: "path to stacks main sdl file");

RootCommand stacksCommands = new()
{
mainArgument
};

stacksCommands.SetHandler(MainArgumentHandler, mainArgument);

await stacksCommands.InvokeAsync(args);

Console.ReadKey();

void MainArgumentHandler(string path)
{
new Parser(path).TryParse(out var appModel);
}
```

Maybe I'm missing something really silly from the docs? I would assume no commands would be executed with cli arguments missing. If I run the program with a malformed argument, it fails during parsing, and the glossary/index of commands pops up. I would assume this would be the case when there are no command line arguments are specified as well.

This is what I would think would popup when args(string[] args in a top-level statement based project) is empty:
![image](https://user-images.githubusercontent.com/55720292/210502891-d8b9c4f2-0e5a-48fe-beba-4c6c39387bb2.png)

Also, what is the reason handlers cannot be bound to Options themselves? That code is kind of smelly to me. Even if there is - obvious - internal binding of handlers to options in a command, they're just Action/Action<T>'s. RootCommand could just grab that from the Option<T> from it. Then it could just be a constructor argument or propety on an Option itself. Much more clean IMO. The code above now becomes:

```cs
using System.CommandLine;
using Stacks.Parsing;

await new RootCommand()
{
new Option(
aliases: new string[] { "--main", "-m" },
description: "path to stacks main sdl file",
handler: MainArgumentHandler)
}
.InvokeAsync(args);

Console.ReadKey();

void MainArgumentHandler(string path)
{
new Parser(path).TryParse(out var appModel);
}
```

Beitragsleitfaden

Beitragsleitfaden öffnen

Rechercherichtung

Reproduziere das Problem mit dem C#-Beispiel und einem leeren args-Array und untersuche anschließend die RootCommand-Invocation von System.CommandLine sowie das Verhalten von SetHandler. Vergleiche die Behandlung leerer Argumente mit der Behandlung fehlerhafter Argumente und prüfe, wie Option-Handler gebunden werden könnten; erledigt ist die Aufgabe, wenn das beabsichtigte Verhalten bei leerer Eingabe feststeht und die Anfrage zur Optionsbindung eindeutig geklärt ist.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
csharp
Bereich
cli
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.