{"id":46323947,"url":"https://github.com/modpm/cmd","last_synced_at":"2026-03-04T16:01:38.859Z","repository":{"id":313966050,"uuid":"1053461854","full_name":"modpm/cmd","owner":"modpm","description":"Simple, intuitive library for building CLI applications in D.","archived":false,"fork":false,"pushed_at":"2025-11-26T10:01:47.000Z","size":99,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-27T23:04:34.137Z","etag":null,"topics":["args-parser","argument-parser","arguments-parser","chainable","cli","cli-framework","cli-library","cli-parser","command-line","command-line-parser","commander","dlang","library","option-parser","options-parsing","subcommands"],"latest_commit_sha":null,"homepage":"https://modpm.github.io/cmd/","language":"D","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/modpm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-09T13:35:50.000Z","updated_at":"2025-11-26T09:57:42.000Z","dependencies_parsed_at":"2025-09-09T21:08:56.681Z","dependency_job_id":"2532f32f-05fb-445f-953d-79bc78c9dbb0","html_url":"https://github.com/modpm/cmd","commit_stats":null,"previous_names":["modpm/cmd"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/modpm/cmd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/modpm%2Fcmd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/modpm%2Fcmd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/modpm%2Fcmd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/modpm%2Fcmd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/modpm","download_url":"https://codeload.github.com/modpm/cmd/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/modpm%2Fcmd/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30085805,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T15:40:14.053Z","status":"ssl_error","status_checked_at":"2026-03-04T15:40:13.655Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["args-parser","argument-parser","arguments-parser","chainable","cli","cli-framework","cli-library","cli-parser","command-line","command-line-parser","commander","dlang","library","option-parser","options-parsing","subcommands"],"created_at":"2026-03-04T16:01:38.172Z","updated_at":"2026-03-04T16:01:38.850Z","avatar_url":"https://github.com/modpm.png","language":"D","readme":"# cmd\n\n[![Documentation](https://img.shields.io/badge/Documentation-blue)](https://modpm.github.io/cmd)\n[![GitHub](https://img.shields.io/badge/GitHub-181717?logo=github)](https://github.com/modpm/cmd)\n[![CI](https://github.com/modpm/cmd/actions/workflows/build.yaml/badge.svg)](https://github.com/modpm/cmd/actions/workflows/build.yaml)\n[![Version](https://img.shields.io/dub/v/cmd)](https://code.dlang.org/packages/cmd)\n[![Licence](https://img.shields.io/dub/l/cmd)](https://github.com/modpm/cmd/blob/main/COPYING)\n[![Score](https://img.shields.io/dub/score/cmd)](https://code.dlang.org/packages/cmd)\n[![Downloads](https://img.shields.io/dub/dt/cmd)](https://code.dlang.org/packages/cmd)\n\nA simple, intuitive library for building CLI applications in D.\n\n[**API Reference Documentation**](https://modpm.github.io/cmd)\n\n## Features\n\n- **Nested subcommands** — Supports hierarchical command structures, allowing commands to contain other commands.\n- **Flexible arguments** — Required (`\u003c\u003e`) and optional (`[]`) arguments with variadic support (`...`).\n- **Rich option handling** — Supports `--option=value`, `--option value`, and grouped short flags such as `-abc`\n(equivalent to `-a -b -c`).\n- **Automatic help generation** — Built-in help and usage text generation.\n- **Array collection** — Repeated options are automatically collected as arrays.\n- **Type-safe parsing** — Clean API for accessing parsed arguments and options.\n\n## Quick Start\n\nHere’s a minimal example that splits a string:\n\n```d\nimport std.stdio;\nimport std.string;\n\nimport cmd.program;\n\nvoid main(string[] argv)\n{\n    auto args = new Program(\"split\")\n        .description(\"Split a string\")\n        .versionString(\"1.0.0\")\n        .versionOption(\"--version\", \"Show version information\")\n        .helpOption(\"-h, --help\", \"Show help for command\")\n        .argument(\"\u003cstring\u003e\", \"String to split\")\n        .option(\"-s, --separator \u003cchar\u003e\", \"Separator character\")\n        .option(\"--first\", \"Return only the first element\")\n        .parse(argv);\n\n    auto parts = args.argument(\"string\").split(args.option(\"separator\"));\n    if (args.hasFlag(\"first\"))\n        writeln(parts[0]);\n    else\n        writeln(parts);\n}\n```\n\n### Usage\n\n```bash\n$ ./split \"hello,world,foo\" --separator \",\"\n[\"hello\", \"world\", \"foo\"]\n\n$ ./split \"hello,world,foo\" --separator \",\" --first\nhello\n```\n\n**Note:** [`versionOption()`](https://modpm.github.io/cmd/cmd.program.Program.versionOption.2.html) enables a version flag for your program (e.g., `--version`), and [`helpOption()`](https://modpm.github.io/cmd/cmd.program.Program.helpOption.1.html) enables a help flag (e.g., `-h` or `--help`). When specified, these flags are handled automatically: the library will print the version or help message and exit.\n\n## Options and Flags\n\nUse [`option()`](https://modpm.github.io/cmd/cmd.command.Command.option.html) to add named parameters to your commands:\n\n### Option Types\n\n```d\nParsedArgs args = new Program(\"example\")\n    // Required option - user must provide a value\n    .option(\"-t, --target \u003cname\u003e\", \"Target name\")\n\n    // Optional with default value\n    .option(\"-p, --port [number]\", \"Port number\", \"8080\")\n\n    // Optional without default\n    .option(\"-c, --config [file]\", \"Configuration file\")\n\n    // Boolean flag - without a parameter\n    .option(\"--verbose\", \"Enable verbose output\")\n    .option(\"-q, --quiet\", \"Suppress output\")\n\n    .parse(argv);\n```\n\n### Accessing Values\n\nPlease see the API reference page for [`ParsedArgs`](https://modpm.github.io/cmd/cmd.parsed_args.ParsedArgs.html).\n\n```d\n// Get option value (first occurrence)\nconst string target = args.option(\"target\");\nconst string port = args.option(\"port\");\n\n\n// Get all values for repeated options\n// const string[] targets = args.optionList(\"target\");\n\n// Check if optional option is present\nif (args.hasOption(\"--config\")) {\n    const string config = args.option(\"--config\");\n    // ...\n}\n\n// Check boolean flags\nif (args.hasFlag(\"verbose\"))\n    writeln(\"Verbose mode enabled\");\nconst bool quiet = args.hasFlag(\"-q\");\n```\n\nYou can access options using:\n- `option(\"target\")` - access by long name (explicit for long names)\n- `option(\"t\")` - access by short name (implicit, could be ambiguous)\n- `option(\"-t\")` - access by short name (explicit)\n- `option(\"--target\")` - access by long name (explicit, stylistic)\n\n(also applies for `hasOption()`, `hasFlag()`, etc.)\n\n## Arguments\n\nUse [`argument()`](https://modpm.github.io/cmd/cmd.command.Command.argument.html) to add positional arguments that users provide in order:\n\n```d\nnew Program(\"file-processor\")\n    .argument(\"\u003cinput\u003e\", \"Input file path\")    // Required\n    .argument(\"[output]\", \"Output file path\")  // Optional\n```\n\n### Variadic Arguments\n\nVariadic (rest) arguments can be added as the last argument in your command to accept multiple values. Optional variadic `[files...]` accepts ≥ 0 values, required variadic `\u003cfiles...\u003e` needs ≥ 1.\n\n```d\nnew Program(\"search\")\n    // …\n    .argument(\"\u003cfiles...\u003e\", \"Files to search\")\n```\n\n### Accessing Arguments\n```d\nconst string inputFile = args.argument(\"input\");\n\n// Check if optional argument was provided\nif (args.hasArgument(\"output\")) {\n    const string outputFile = args.argument(\"output\");\n}\n\n// Get all values of variadic\nconst string[] files = args.argumentList(\"files\");\n```\n\n\n**Note:** Required arguments after optional ones are technically allowed, but behave counter-intuitively and ambiguously for the user. It is strongly recommended not to use optional positional arguments before required ones—consider re-ordering the arguments, or using named parameters (options).\n\n## Working with Subcommands\n\nBuild complex CLI applications with nested subcommands using [`command()`](https://modpm.github.io/cmd/cmd.command.Command.command.html). Here’s an example with basic subcommands.\n\n```d\nimport std.stdio;\nimport std.string;\n\nimport cmd.program;\nimport cmd.command;\n\nvoid main(string[] args)\n{\n    new Program(\"subcommands\")\n        .description(\"A CLI application with subcommands\")\n        .versionString(\"1.0.0\")\n        .helpOption(\"-h, --help\", \"Show help for command\")\n        .command(new Command(\"split\")\n            .description(\"Split a string\")\n            .argument(\"\u003cstring\u003e\", \"String to split\")\n            .option(\"-s, --separator \u003cchar\u003e\", \"Separator character\")\n            .action((args) {\n                auto parts = args.argument(\"string\").split(args.option(\"separator\"));\n                writeln(parts);\n                return 0;\n            })\n        )\n        .command(new Command(\"greet\")\n            .description(\"Greet someone\")\n            .argument(\"\u003cname\u003e\", \"Name of the person to greet\")\n            .option(\"--excited\", \"Add excitement to the greeting\")\n            .action((args) {\n                auto msg = \"Hello, \" ~ args.argument(\"name\");\n                if (args.hasFlag(\"excited\"))\n                    msg ~= \"!!!\";\n                writeln(msg);\n                return 0;\n            })\n        )\n        .run(args);\n}\n```\n\n### Usage\n\n```bash\n$ ./subcommands split \"hello,world\" --separator \",\"\n$ ./subcommands greet Alice --excited\n$ ./subcommands split --help  # Shows help for the split subcommand\n```\n\n**Important:** A command cannot have both subcommands and arguments. Choose one pattern per command level.\n\nCommands can be nested endlessly.\n\n## Custom Command Classes\n\nCreate modular command implementations by extending [`Command`](https://modpm.github.io/cmd/cmd.command.Command.html) (or [`Program`](https://modpm.github.io/cmd/cmd.program.Program.html)):\n\n```d\nmodule modular.commands.greet;\n\nimport std.stdio;\n\nimport cmd.command;\nimport cmd.parsed_args;\n\nclass GreetCommand : Command\n{\n    public this()\n    {\n        super(\"greet\")\n            .description(\"Greet someone\")\n            .argument(\"\u003cname\u003e\", \"Name of the person to greet\")\n            .option(\"--excited\", \"Add excitement to the greeting\")\n            .action(\u0026execute);\n    }\n\n    private int execute(ParsedArgs args)\n    {\n        auto msg = \"Hello, \" ~ args.argument(\"name\");\n        if (args.hasFlag(\"excited\"))\n            msg ~= \"!!!\";\n        writeln(msg);\n        return 0;\n    }\n}\n```\n\n### Integration\n```d\n// …\nimport modular.commands.greet;\nimport cmd.program;\n\nvoid main(string[] args)\n{\n    new Program(\"modular\")\n        .command(new GreetCommand())\n        .run(args);\n}\n```\n\n## Built-in Help Command\n\nEnable `help` as a subcommand using [`HelpCommand`](https://modpm.github.io/cmd/cmd.help_command.HelpCommand.html):\n\n```d\n// …\nimport cmd.help_command;\n\nnew Program(\"myapp\")\n    .description(\"My CLI application\")\n    .command(new Command(\"deploy\").description(\"Deploy the application\"))\n    .command(new Command(\"status\").description(\"Check application status\"))\n    .command(new HelpCommand())  // Adds the built-in ‘help’ subcommand\n    .run(args);\n```\n\n### Usage\n\n```bash\n$ myapp help         # Show help for program\n$ myapp help deploy  # Show help for deploy command\n```\n\n## Error Handling\n\nThe library provides clear error messages for common mistakes during args parsing and exits with status code `2`:\n\n```\nerror: unknown command 'unknown-command'\nerror: missing value for option 'target'\nerror: unknown option 'invalid-option'\nerror: unexpected argument 'extra'\nerror: missing required option '-t, --target \u003cname\u003e'\nerror: missing required argument 'input'\n```\n\nYou can also trigger custom errors in your command actions using the [`error(string)`](https://modpm.github.io/cmd/cmd.command.Command.error.1.html) and [`noreturn error(string, int)`](https://modpm.github.io/cmd/cmd.command.Command.error.2.html) methods on `Command`:\n\n```d\n.action((args) {\n    if (someCondition) {\n        args.command.error(\"error message\");     // Does not exit (only prints error)\n        // or\n        args.command.error(\"error message\", 1);  // Exits with status\n    }\n    return 0;\n});\n```\n\nThe `error` methods can be overridden to customise the error format.\n\n## Licence\n\nCopyright © 2025 Zefir Kirilov.\n\nThis project is licenced under the [GPL-3.0](https://github.com/modpm/cmd/blob/main/COPYING) licence.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmodpm%2Fcmd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmodpm%2Fcmd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmodpm%2Fcmd/lists"}