Cmdr.Core
Useful POSIX command line arguments parser for .Net. Hierarchical-configuration Store for app.
Install / Use
/learn @hedzr/Cmdr.CoreREADME
Cmdr.Core
Useful POSIX command line arguments parser for dotNet. Hierarchical configurations Store for app.
Supported:
- dotNet 6 (since v1.3+)
- dotNet Core 3.1 (since v1.1+)
- dotNet Standard 2.1+ (since v1.1+)
- ~~dotNet 4.8+ [?] (NOT SURE)~~
NOTED .NET 5 has been ignored.
NuGet
PM> Install-Package HzNS.Cmdr.Core -Version 1.0.29
# Or CLI
$ dotnet add package HzNS.Cmdr.Core --version 1.0.29
Please replace 1.0.29 with the newest version (stable or pre-release), see the nuget badge icon.
Features
Cmdr.Core has rich features:
- [x] POSIX Compatible (Unix getopt(3))
- [x] IEEE Standard Compartiblities
- [x] builds multi-level command and sub-commands
- [x] builds short, long and alias options with kinds of data types
- [x] defines commands and options via fluent api style
- [x] full featured
Options Storefor hosting any application configurations- watchable external config file and child directory
conf.d. - watchable option value merging event: while option value modified in external config file, it'll be loaded and merged automatically.
- watchable option value modifying event: while option value modified (from config file, or programmatically)
- connectable with external configuration-center
- watchable external config file and child directory
More
-
Unix getopt(3) representation but without its programmatic interface.
- [x] Options with short names (
-h) - [x] Options with long names (
--help) - [x] Options with aliases (
--helpme,--usage,--info) - [x] Options with and without arguments (bool v.s. other type)
- [x] Options with optional arguments and default values
- [x] Multiple option groups each containing a set of options
- [x] Supports the compat short options
-aux==-a -u -x,-vvv==-v -v -v(HitCount=3) - [x] Supports namespaces for (nested) option groups see also: option store and hierarchical data
- [x] Options with short names (
-
[x] Supports for
-D+,-D-to enable/disable a bool option. -
[x] Supports for PassThrough by
--. (Passing remaining command line arguments after -- (optional)) -
[x] Automatic help screen generation (Generates and prints well-formatted help message)
-
[x] Predefined commands and flags:
- Help:
-h,-?,--help,--info,--usage,--helpme, ... - Version & Build Info:
--version/--ver/-V,--build-info/-#- Simulating version at runtime with
—version-sim 1.9.1 - [ ] generally,
conf.AppNameandconf.Versionare originally. --tree: list all commands and sub-commands.--config <location>: specify the location of the root config file.versioncommand available.
- Simulating version at runtime with
- Verbose & Debug:
—verbose/-v,—debug/-D,—quiet/-q
- Help:
-
[x] Sortable commands and options/flags: sorted by alphabetic order or not (
worker.SortByAlphabeticAscending). -
[x] Grouped commands and options/flags.
Group Title may have a non-displayable prefix for sorting, separated by '.'.
Sortable group name can be
[0-9A-Za-z]+\..+format typically, or any string tailed '.', eg:1001.c++,1100.golang,1200.java, …;abcd.c++,b999.golang,zzzz.java, …;
-
[x] Supports for unlimited multi-level sub-commands.
-
[x] Overrides by environment variables.
priority level:
defaultValue -> config-file -> env-var -> command-line opts -
[x]
Option Store- Unify option value extraction. -
[x] Walkable
- Customizable
Painterinterface to loop each command and flag. - Walks on all commands with
Walk(from, commandWalker, flagWalker).
- Customizable
-
[x] Supports
-I/usr/include -I=/usr/include-I /usr/include -I:/usroption argument specifications Automatically allows those formats (applied to long option too):-I file,-Ifile, and-I=files-I 'file',-I'file', and-I='files'-I "file",-I"file", and-I="files"
-
[x] Supports for PassThrough by
--. (Passing remaining command line arguments after -- (optional)) -
[x] Predefined external config file locations:
-
/etc/<appname>/<appname>.ymlandconf.dsub-directory. -
/usr/local/etc/<appname>/<appname>.ymlandconf.dsub-directory. -
$HOME/.config/<appname>/<appname>.ymlandconf.dsub-directory. -
$HOME/.<appname>/<appname>.ymlandconf.dsub-directory. -
the predefined locations are:
predefinedLocations: []string{ "./ci/etc/%s/%s.yml", // for developer "/etc/%s/%s.yml", // regular location: /etc/$APPNAME/$APPNAME.yml "/usr/local/etc/%s/%s.yml", // regular macOS HomeBrew location "$HOME/.config/%s/%s.yml", // per user: $HOME/.config/$APPNAME/$APPNAME.yml "$HOME/.%s/%s.yml", // ext location per user "$THIS/%s.yml", // executable's directory "%s.yml", // current directory }, -
[x] Watch
conf.ddirectory, the name is customizable (worker.). -
RegisterExternalConfigurationsLoader(loader, ...)
-
-
[x] Handlers
- Global Handlers:
RootCommand.OnPre/Post/Action(), OnSet()will be triggered before/after the concreteCommand.OnPre/Post/Action()/OnSet() - Command Actions:
Command.OnPreAction/OnAction/OnPostAction(), OnSet - Flag Actions:
Flag.OnPreAction/OnAction/OnPostAction(), OnSet - Parsing Events:
bool OnDuplicatedCommandChar(worker, cmd, isShort, matchingString)bool OnDuplicatedFlagChar(worker, cmd, flag, isShort, matchingString)bool OnCommandCannotMatched(ICommand parsedCommand, string matchingArg)bool OnCommandCannotMatched(ICommand parsingCommand, string fragment, bool isShort, string matchingArg)bool OnSuggestingForCommand(object worker, Dictionary<string, ICommand> dataset, string token)bool OnSuggestingForFlag(object worker, Dictionary<string, IFlag> dataset, string token)- ...
- More...
- Global Handlers:
-
Unhandled Exception
cmdrhandledAppDomain.CurrentDomain.UnhandledExceptionfor better display. But you can override it always:static int Main(string[] args) { AppDomain.CurrentDomain.UnhandledException+=(sender,e)=>{}; Cmdr.NewWorker(...).Run(); } -
Smart suggestions for wrong command and flags
based on Jaro-Winkler distance.

Option Store - Hierarchical Configurations Store
Standard primitive types and non-primitive types.
Get(), GetAs<T>()
Set<T>(), SetWithoutPrefix<T>()
Delete()
HasKeys(), HasKeysWithoutPrefix()
var exists = Cmdr.Instance.Store.HasKeys("tags.mode.s1.s2");
var exists = Cmdr.Instance.Store.HasKeys(new string[] { "tags", "mode", "s1", "s2" });
var exists = Cmdr.Instance.Store.HasKeysWithoutPrefix(new string[] { "app", "tags", "mode", "s1", "s2" });
Console.WriteLine(Cmdr.Instance.Store.Prefix);
FindBy()
var (slot, valueKey) = Cmdr.Instance.Store.FindBy("tags.mode.s1.s2");
if (slot != null){
if (string.IsNullOrWhiteSpace(valueKey)) {
// a child slot node matched
} else {
// a value entry matched, inside a slot node
}
}
Walk()
GetAsMap()
return a SlotEntries map so that you can yaml it:
// NOTE: Cmdr.Instance.Store == worker.OptionsStore
var map = worker.OptionsStore.GetAsMap("tags.mode");
// worker.log.Information("tag.mode => {OptionsMap}", map);
{
var serializer = new SerializerBuilder().Build();
var yaml = serializer.Serialize(map);
Console.WriteLine(yaml);
}
CMDR EnvVars
CMDR_DUMP
enable Store entries dumping at the end of help screen.
CMDR_DUMP_NO_STORE, CMDR_DUMP_NO_HIT
To prevent the store dump, or hit options dump.
CMDR_DEBUG
= Worker.EnableCmdrLogDebug
allows the display output in defaultOnSet.
CMDR_TRACE
= Worker.EnableCmdrLogTrace
allows the worker logDebug().
CMDR_VERBOSE
allows more logging output.
Getting Start
Fluent API
Basically, the Main program looks like:
static int Main(string[] args) =>
Cmdr.NewWorker(RootCommand.New(
new AppInfo(), // your app information, desc, ...
buildRootCmd(), // to attach the sub-commands and options to the RootCommand
workerOpts, // to customize the Cmdr Worker
))
.Run(args, postRun);
Your first app with Cmdr.Core could be:
namespace Simple
{
class Program
{
static int Main(string[] args) => Cmdr.NewWorker(
#region RootCmd Definitions
RootCommand.New(
new AppInfo
{
AppName = "tag-tool",
Author = "hedzr",
Copyright = "Copyright © Hedzr Studio, 2020. All Rights Reserved.",
},
(root) =>
{
root.Description = "description here";
root.DescriptionLong = "long description here";
root.Examples = "examples here";
// for "dz"
_a = 0;
root.AddCommand(new Command
{
Long = "dz", Short = "dz", Description = "test divide by zero",
Action = (worker, opt, remainArgs) => { C
Related Skills
node-connect
339.3kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
83.9kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
339.3kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
83.9kCommit, push, and open a PR
