More examples ​
The repository includes three deterministic, runnable tools adapted from the larger collection in jpetrucciani/nix:
batwhich, executable completion, runtime inputs, and normal error handling.jwt-decode, a boolean flag, completion message, and JSON transformation.nix-summary, repeatable flags, rich static values, directory completion, and filenames containing spaces.
Build or run them from a Pog checkout:
nix build .#example-batwhich
nix run .#example-jwt-decode -- --help
nix run .#example-nix-summary -- \
--directory examples \
--extension nix \
--extension mdInspect the generated completion interface:
nix build .#example-nix-summary
result/bin/_nix-summary_complete export nix-summary --extension n
find -L result/share/pog/completions -type f -print | sortThe source definitions live in the repository's examples directory and run as regression fixtures through nix build .#ordinary-examples. The external collection remains useful for larger wrappers involving cloud APIs, media tools, containers, databases, and local services.
Subcommands ​
Pass a commands list to build a clap-style tool that dispatches to nested subcommands. Each command can have its own flags, arguments, help, and script, and can nest further commands to any depth. A parent command may also define a script that runs as the default action when no subcommand is given.
tool = pog {
name = "tool";
description = "a tester for pog's recursive subcommands";
flags = [ _.flags.common.color ];
# top-level exit hook (runs last, after any command's hook)
beforeExit = ''echo "[tool] root cleanup"'';
# default action when invoked with no subcommand
script = ''echo -e "''${!color}tool root - no subcommand given''${RESET}"'';
commands = [
{
name = "remote";
description = "manage remotes";
# parent default action (bare `tool remote`)
script = ''echo "listing remotes (default action)"'';
commands = [
{
name = "add";
description = "add a remote";
arguments = [ "remote_name" ];
# per-command exit hook (runs first, before the root hook)
beforeExit = ''echo "[tool remote add] cleanup"'';
flags = [
{ name = "url"; description = "the remote url"; required = true; }
_.flags.k8s.namespace
];
script = ''echo "adding remote '$1' -> $url (ns=$namespace)"'';
}
{
name = "remove";
description = "remove a remote";
script = ''echo "removing remote '$1'"'';
}
{
# subcommand names may be hyphenated
name = "list-all";
description = "list every remote";
script = ''echo "listing all remotes"'';
}
];
}
{
name = "status";
description = "show status";
flags = [ { name = "short"; description = "short output"; bool = true; } ];
script = ''echo "status (short=''${short:-0})"'';
}
];
};This generates a single tool binary that supports:
tool # runs the root default action
tool --help # lists the `remote` and `status` subcommands
tool remote # runs the `remote` default action
tool remote add --url x myremote
tool remote list-all
tool status --shortTab completion works recursively: completing after tool offers the subcommand names, after tool remote offers add remove list-all, and after a leaf command offers that command's flags and argument completions.
See Commands and parsing for aliases, command groups, persistent flags, exclusive flags, and pass-through wrappers.
Each command can also define a beforeExit hook. Every command on the active path runs its hook as the process exits, deepest command first. So tool remote add --url x foo prints:
adding remote 'foo' -> x (ns=default)
[tool remote add] cleanup
[tool] root cleanup