Module dcli.program_commands
Handles program commands, which are arguments passed to a program that are not prefixed with - or --. So that
    you handle programs that can be executed in this format:
$  ./program -v --global-option=7 command1 --parameter="yo" sub-command --another-parameter=42
Usage
The basic idea is to create a ProgramCommands structure and then define a number of Commands that it can handle and
    optionally, a set of ProgramOptions that it can handle. Each Command can in
    turn have it's own ProgramCommands.
Handlers
Handlers are provided to be able to eacily handle when a command is encountered. This will allow you to structure your program with a module based architecture, where each "handler" can e.g. pass the commands to a module that is build specifically for handling that command.
E.g.:
// install.d
void commandHandler(T)(T commands) {
    writeln(commands .install); // prints true
}
// main.d
static import install, build;
void main(string[] args) {
    auto commands = ProgramCommands!(
        Command!"build" .handler!(build .commandHandler)
        Command!"install" .handler!(install .commandHandler)
    )();
    commands .parse(args);
    commands .executeHandlers();
}
// Run it
$  ./program install
$ >> true
Inner ProgramOptions
The first argument to a ProgramCommands object can optionally be a ProgramOptions
    object. In this case, the program options are accessible with an internal variable named options
E.g.:
auto commands = ProgramCommands!(
    ProgramOptions!(Options!("opt1", string)),
    Command!"command1",
    Command!"command2" .args!(
        ProgramOptions!(Options!("opt2", string))
    )
)();
commands .options .opt1; // access the option
commands .command1; // access the command
commands .command2 .op2; // access the options of command2
Inner ProgramCommands
You can also pass in sub commands to a Command object in the args parameter:
auto commands = ProgramCommands!(
    ProgramOptions!(Options!("opt1", string)),
    Command!"command1" .args!(
        ProgramCommands!(
            ProgramOptions!(Options!("opt2", string)),
            Command!"sub-command1",
        ),
    ),
)();
commands .options .opt1; // access the option
commands .command1 .subCommand1; // access the command
commands .command1 .options .op2; // access the options of command2
Example
import dcli .program_options;
alias MainCommands = ProgramCommands!(
    ProgramOptions!(
        Option!("glob1", string) .shortName!"a" .description!"desc",
    ),
    Command!"cmd1"
         .args!(
            ProgramOptions!(
                Option!("opt1", string) .shortName!"b" .description!"desc",
            ),
    ),
    Command!"cmd2"
         .handler!(Fixtures .handleCommand2)
         .description!"desc",
    Command!"cmd3"
         .args!(
            ProgramCommands!(
                ProgramOptions!(
                    Option!("opt3", string) .shortName!"d" .description!"desc",
                ),
                Command!"sub1"
                     .args!(
                        ProgramOptions!(
                            Option!("opt4", string) .shortName!"e" .description!"desc",
                        ),
                    )
                     .handler!(Fixtures .handleCommand3)
                     .description!"desc",
            ),
        )
         .handler!(Fixtures .handleCommand3Sub1)
         .description!"desc",
);
auto commands = MainCommands();
commands .parse([
    "-ayo",
    "cmd3",
    "-d",
    "hi",
    "sub1",
    "-e",
    "boo",
]);
assert(cast(bool)commands .cmd1 == false);
assert(cast(bool)commands .cmd2 == false);
assert(cast(bool)commands .cmd3 == true);
assert(commands .options .glob1 == "yo");
assert(commands .cmd3 .options .opt3 == "hi");
assert(commands .cmd3 .sub1 .opt4 == "boo");
assert(commands .helpText ==
`Options:
-h  --help    Displays this help message
-a  --glob1   desc
Commands:
cmd1
cmd2  desc
cmd3  desc`
);
commands .executeHandlers;
assert(!Fixtures .checkResetHandledCommand2);
assert( Fixtures .checkResetHandledCommand3);
assert( Fixtures .checkResetHandledCommand3Sub1);
Structs
| Name | Description | 
|---|---|
							
								ProgramCommands
							
						 | 
						You can configure a ProgramCommands object with a number of Commands and then use it to parse
    an list of command line arguments
 | 
					
Aliases
| Name | Type | Description | 
|---|---|---|
							
								Command
							
						 | 
						
							CommandImpl!(name,ProgramOptions!())
						 | 
						Represents one program command which identified the expected string on the command line. One of more of these can be given to
    a ProgramCommands object as template arguments.
 |