Getting Started
Requirements
HatTrick.CommandLine targets .NET 9 or later. The package has one runtime dependency (HatTrick.Text.Templating) which NuGet resolves automatically.
Installation
dotnet add package HatTrick.CommandLineNamespace: HatTrick.CommandLine
Features
| Feature | Supported | Details |
|---|---|---|
| Dot-path command naming & namespace grouping | ✅ | Commands and Namespaces |
Terse (-f) and verbose (--format) flags | ✅ | Options and Flags |
| Positional arguments | ✅ | Options and Flags |
Boolean flags (implicit true) | ✅ | Options and Flags |
Terse flag chaining (-osf) | ✅ | Options and Flags |
Built-in type conversion (numerics, DateOnly, Guid, TimeSpan, etc.) | ✅ | Option Types |
| Custom type converters (arrays, enums, domain types) | ✅ | Option Types |
| Default option values (static or dynamic) | ✅ | Constraints |
| Accepted-value lists | ✅ | Constraints |
| Custom option-level validation | ✅ | Constraints |
| Command-level validation (mutually exclusive / one-of sets) | ✅ | Constraints |
| Synchronous and async handlers | ✅ | Handlers |
| Pre-execution argument rewriting | ✅ | Pre-Execution Hooks |
| Masked console input (passwords/secrets) | ✅ | Masked Input |
| POCO hydration / typed delegate mapping and invocation | ✅ | Object Mapping |
| Global, scoped, and wildcard help output | ✅ | Default Command |
Built-in --version (assembly + dependency versions) | ✅ | Default Command |
Interactive command loop (--run) | ✅ | Default Command |
| Typed exceptions for definition/parse/runtime errors | ✅ | Exceptions |
A complete first program
static void Main(string[] args)
{
//Register commands
RegisterGuidCommand();
//build and execute
var registry = DefinitionRegistry.GetInstance();
Command cmd = CommandBuilder.Build(args);
CommandExecutor executor = registry.GetCommandExecutor(cmd);
executor.Execute();
}
static void RegisterGuidCommand()
{
//get a ref to the command definition registry
var registry = DefinitionRegistry.GetInstance();
//build a complete command definition
var cmdDef = new CommandDefinition("guid");
cmdDef.Help = "Generates one or many GUID values.";
cmdDef.AddOption<string>(
key: "format",
defaultArg: "D",
help: "GUID format specifier.",
(terse: "-f", verbose: "--format")
);
cmdDef["format"].AcceptedValues("N", "D", "B", "P", "X");
cmdDef.AddOption<int>(
key: "count",
defaultArg: 1,
help: "Number of GUIDs to generate.",
(terse: "-c", verbose: "--count")
);
cmdDef["count"].ApplyConstraint<int>(
constraint: (cnt) => cnt > 0 && cnt <= 100,
name: "Allowed Range",
description: "1..100."
);
cmdDef.Handler = (cmd) =>
{
int count = cmd["count"].GetValue<int>();
string format = cmd["format"].GetValue<string>();
for (int i = 0; i < count; i++)
Console.WriteLine(Guid.NewGuid().ToString(format));
};
//register the command definition
registry.Add(cmdDef);
}Next steps
- Definition and Registry — the singleton container and command registration
- Commands and Namespaces — naming and dot-path structure
- Options and Flags — flags, positional arguments, and boolean options
- Constraints — validation before handler invocation