You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The goal of this project is to provide a simple and effective way to handle command-line commands and parameters, allowing developers to create POSIX-like CLI applications with minimal hassle in parsing the command line and enabling them to focus on application logic. Additionally, it facilitates providing all necessary information for the application's help system, making it easily accessible to end users. The [DragonFruit](https://github.com/dotnet/command-line-api/blob/main/docs/DragonFruit-overview.md) project was a step in this direction, but is very limited in abilities it provides.
9
+
The goal of this project is to enable developers to create POSIX-like Command Line Interface (CLI) applications without the need to parse the command line themselves, allowing them to focus on application logic. The library automatically handles command-line commands and parameters using the provided metadata, simplifying the development process. It also streamlines the creation of the application's help system, ensuring that all necessary information is easily accessible to end users.
10
+
11
+
The [DragonFruit](https://github.com/dotnet/command-line-api/blob/main/docs/DragonFruit-overview.md) project was a step in this direction, but is very limited in abilities it provides.
10
12
11
13
# API Paradigm
12
14
The API paradigm of this project is to use [attributes](https://learn.microsoft.com/en-us/dotnet/csharp/advanced-topics/reflection-and-attributes/) to declare and describe CLI commands, options, and arguments.
13
15
14
16
Any public static method can be declared as a CLI command handler using the `[Command]` attribute, and effectively represent an entry point to the CLI application for that command. Any parameter of command handler method automatically becomes a command option. See the [usage](#usage) section and examples below for more details.
15
17
16
18
## What about classes?
17
-
There are multiple CLI frameworks that require separate class implementation for each command. In my opinion, creating a per-command classes adds unnecessary bloat to the code with little to no benefit. To provide additional information such as descriptions and aliases, attributes are anyway required on top of the class declaration. Since the goal is to simplify things as much as possible, I decided not to use classes at all in my approach. While this approach may not be as flexible as some other solutions, it meets the basic needs of most CLI applications.
19
+
Many CLI frameworks require separate class implementations for each command. In my opinion, creating individual classes for each command adds unnecessary bloat to the code with minimal benefit. Using attributes is easier to maintain and understand, as they are declared close to the entities they describe, keeping all related information in one place. Additionally, attributes allow for extra details, such as descriptions and aliases. Since the goal is to simplify the implementation as much as possible, I decided not to use classes at all in my approach. While this method may not be as flexible as some other solutions, it effectively meets the needs of most CLI applications.
18
20
19
21
## Command line syntax
20
22
Since this project is based on the [System.CommandLine](https://learn.microsoft.com/en-us/dotnet/standard/commandline/) library, the parsing rules are exactly the same as those for that package. The Microsoft documentation provides detailed explanations of the [command-line syntax](https://learn.microsoft.com/en-us/dotnet/standard/commandline/syntax) recognized by `System.CommandLine`. I will include more links to this documentation throughout the text below.
21
23
22
24
## Main method
23
-
Normally, the `Main` method is the entry point of a C# application. However, to simplify startup code and usage, this library overrides the program's entry point and uses command handler methods as the entry points instead. This means that if you include your own `Main` function in the program, it will **not** be invoked. If you need some initialization code to run before command, it can be placed in [Startup](#startup) method.
25
+
Typically, the `Main` method serves as the entry point of a C# application. However, to simplify startup code and usage, this library overrides the program's entry point and uses command handler methods as the entry points instead. This means you don't need to write any startup boilerplate code for your CLI application and can dive straight into implementing the application logic, i.e. commands.
26
+
27
+
It’s important to note that since the library overrides the entry point, if you include your own `Main` function in the program, it will **not** be invoked. If you need some initialization code to run before command, it can be placed in [Startup](#startup) method.
24
28
25
29
If you really need to use your own `Main`, you can still do so:
26
30
1. Add `<AutoGenerateEntryPoint>false</AutoGenerateEntryPoint>` property into your program .csproj file
Youcanprovideoptionsbeforeargumentsorargumentsbeforeoptionsonthecommandline. See [documentation](https://learn.microsoft.com/en-us/dotnet/standard/commandline/syntax#order-of-options-and-arguments) for details.
212
216
@@ -216,7 +220,7 @@ The [arity](https://learn.microsoft.com/en-us/dotnet/standard/commandline/syntax
/// Provides access to currently executing command definition.
407
358
/// </summary>
408
-
publicstaticCommandCurrentCommand{
409
-
get=>_currentCommand??thrownewInvalidOperationException($"Cannot access {nameof(CurrentCommand)} from outside of CLI command handler method");
410
-
privateset=>_currentCommand=value;
411
-
}
412
-
privatestaticCommand?_currentCommand=null;
413
-
359
+
publicstaticCommand?CurrentCommand;
414
360
/// <summary>
415
361
/// Handler to use when exception is occured during command execution. Set <code>null</code> to suppress exception handling.
416
362
/// </summary>
@@ -451,8 +397,7 @@ private static int DefaultExceptionHandler(Exception exception)
451
397
/// <summary>
452
398
/// Current command invocation context provides access to parsed command line, CancellationToken, ExitCode and other properties.
453
399
/// </summary>
454
-
publicstaticInvocationContextCurrentContext=>_currentContext??thrownewInvalidOperationException($"Cannot access {nameof(CurrentContext)} from outside of command handler method");
0 commit comments