{"id":21428675,"url":"https://github.com/spikef/cmdu","last_synced_at":"2025-07-14T10:32:23.053Z","repository":{"id":57201179,"uuid":"61357402","full_name":"Spikef/cmdu","owner":"Spikef","description":"A comfortable way to create your command line app by nodejs.","archived":false,"fork":false,"pushed_at":"2018-05-07T13:59:26.000Z","size":95,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-10-31T17:54:20.227Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Spikef.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-06-17T08:15:03.000Z","updated_at":"2020-04-25T07:47:10.000Z","dependencies_parsed_at":"2022-09-15T11:22:06.889Z","dependency_job_id":null,"html_url":"https://github.com/Spikef/cmdu","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Spikef%2Fcmdu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Spikef%2Fcmdu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Spikef%2Fcmdu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Spikef%2Fcmdu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Spikef","download_url":"https://codeload.github.com/Spikef/cmdu/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225970900,"owners_count":17553410,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-11-22T22:14:20.076Z","updated_at":"2024-11-22T22:14:20.695Z","avatar_url":"https://github.com/Spikef.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cmdu\n\n[![Build Status](https://travis-ci.org/Spikef/cmdu.svg?branch=master)](https://travis-ci.org/Spikef/cmdu)\n[![Coverage Status](https://coveralls.io/repos/github/Spikef/cmdu/badge.svg?branch=master)](https://coveralls.io/github/Spikef/cmdu?branch=master)\n[![NPM Version](http://img.shields.io/npm/v/cmdu.svg?style=flat)](https://www.npmjs.org/package/cmdu)\n[![NPM Downloads](https://img.shields.io/npm/dm/cmdu.svg?style=flat)](https://www.npmjs.org/package/cmdu)\n[![cmdu starter](https://img.shields.io/badge/cmdu-starter-brightgreen.svg)](https://www.npmjs.org/package/cmdu-cli)\n\nA comfortable way to create your command line app with `node.js`.\n\n[点此阅读中文文档](/README_CN.md)\n\n## Install\n\n```bash\n$ npm install cmdu\n```\n\nor install a global cli to quickly start\n\n```bash\n$ npm install cmdu-cli -g\n```\n\n## Usage\n\n```javascript\n#!/usr/bin/env node\n\nvar app = require('cmdu');\n\n// do something as you like\n\napp.listen();   // listen the user input at last\n```\n\n## App properties\n\n### app.name\n\nThe `app.name` is only used by the `app.toSource()` method.\n\n### app.version\n\nSet the app version.\n\n```javascript\n#!/usr/bin/env node\n\nvar app = require('cmdu');\napp.version = '0.0.1';\n\n// node index -v\n// node index --version\n// prints: 0.0.1\n```\n\n### app.allowUnknowns\n\nBy default, the app would throw an error when user typed an undefined argument or option. You can set `app.allowUnknowns = true` to allow this.\n\n### app.allowTolerance\n\nBy default, the user must input the command exactly to execute, but you can set `app.allowTolerance = true` to allow a similarity.\n\n### app.language\n\nYou can set the `app.language` to support multiple languages. You may want to get more info from the `language` directory.\n\n```javascript\n// a predefined language name\napp.language = 'zh-CN';     // can be 'zh-CN, en-US'\n\n// or full language object\napp.language = {};\n```\n\n## App methods\n\n### app.toSource()\n\nReturn the full input for current command.\n\n### app.listen()\n\nListen the user input and parse the process.argv, and execute the relative command.\n\nThis is not always required, you can ignore it if you have no asynchronous action, the `listen` will be run automatically when process exit if you didn't `listen`.\n\n### app.command()\n\nDefine a new command and return a `Command` object, view [Command](#Command) for details.\n\n### app.extends()\n\nExtends a existing command, or create a new one if not exists.\n\n### app.log()\n\nUse the `render` method of [cubb](https://github.com/Spikef/cubb) to print strings to terminal.\n\n## Command\n\nA command includes the definition(cmd), name(name), description(description), configs, [arguments](#Command arguments) and [options](#Command options).\n\nThe full syntax for defining a new command:\n\n```javascript\napp.command(cmd, description, options);\n```\n\n**cmd**\n\nThe `cmd` is a string with several parts separated by space. The first part is the command name, and the rest parts are command's arguments. That means the [default command](#Default command) if you omit the first part.\n\n**description**\n\nThe `description` of a command is useful for building help information automatically. Also you can use `options.description` to specify it.\n\n**configs**\n\nThe `configs` is used to define some extra configs for the command.\n\n+ configs.noHelp: Boolean, `true` for removing this command from the auto generated help output.\n+ configs.isBase: Boolean, `true` means the command is only a definition as a mixin but not a real one\n+ configs.mixins: Array of some command's name, the command would extend their options automatically\n\nExample:\n\n```js\n#!/usr/bin/env node\n\nvar app = require('cmdu');\n\napp\n    .command('\u003ccmd\u003e [env=Linux]')\n    .describe('A demo for redefine the default command')\n    .describe('cmd', 'Can be init, install, uninstall, publish')\n    .action(function (cmd, env, options) {\n        console.log(cmd);\n        console.log(env);\n    });\n    \napp\n    .command('install [name]')\n    .describe('install a module')\n    .describe('name', 'the module name')\n    .alias('ins, i')\n    .action(function(name, options) {\n        if (name) {\n            // install the specify module\n        } else {\n            // install according to package.json\n        }\n    });\n    \napp\n    .command('rmdir \u003cdir\u003e [...otherDirs]')\n    .action(function (dir, otherDirs) {\n        console.log('rmdir %s', dir);\n        otherDirs.forEach(function (oDir) {\n            console.log('rmdir %s', oDir);\n        });\n    });\n\napp.listen();\n```\n\n### Command arguments\n\nA argument includes the name(name), description(description), required or not, type and default value.\n\n#### Optional or required\n\nThe argument value is required by default. And you can also declare it as `[optional]` or `\u003crequired\u003e` explicitly. It would throw an error if users forgot to give the required argument a value unless `app.allowUnknowns = true`.\n\nNote: `[optional]` arguments should be defined after `\u003crequired\u003e` ones.\n\n#### Type of arguments\n\nArgument value can be string or array. Just prepend '...' to the argument name to declare it as an array type.\n\nNote: only the last argument can be declared as array.\n\n#### Default value of arguments\n\nYou can specify a default value according to append the `=defaultValue` to the argument name.\n\nIf you didn't specify a default value, it should be:\n\n+ for string type, a empty string\n+ for array type, a empty array\n\n#### Passing values to arguments\n\nWhen passing values, the input order of arguments and options are not limited.\n\n**String**\n\nOne by one according to the order of definitions.\n\n**Array**\n\nValues are separated by space.\n\n### Command options\n\nYou can use `.option()` to add an option to the current command.\n\nA option includes the definition(opt), name(name), description(description), required or not, type, parse function and default value.\n\nThe full syntax for defining a option:\n\n```javascript\ncommand.option(flags, description, parseFn, defaultValue);\n```\n\n**flags**\n\nThe `flags` contains three parts: short flag(optional), long flag(required) and option attribute(optional).\n\nThe option's name will be the same as the long flag without `--` or `--no-`. Multiple words connected with `-` such as \"--template-engine\" will be camel cased, becoming to `app.options.templateEngine`.\n\nOption attribute is used to specify that this option is `[optional]` or `\u003crequired\u003e`.\n\n**description**\n\nThe `description` of a option is useful for building help information automatically.\n\n**parseFn**\n\nA function to parse the option's value, it's optional.\n\n**defaultValue**\n\nThe option's default value.\n\nExample:\n\n```javascript\n#!/usr/bin/env node\n\nvar app = require('cmdu');\n\nfunction range(val) {\n    return val.split('-').map(Number);\n}\n\nfunction list(val) {\n    return val.split(', ');\n}\n\n// parse and default value for options\napp\n    .option('-i, --integer \u003cn\u003e', 'An integer argument', parseInt)\n    .option('-f, --float \u003cn\u003e', 'A float argument', parseFloat)\n    .option('-r, --range \u003cm\u003e-\u003cn\u003e', 'A range', range)\n    .option('-l, --list \u003citems1, items2, ...\u003e', 'A list', list)\n    .option('-o, --optional [value]', 'An optional value', 'default value')\n    .option('-c, --collection \u003c...collections\u003e', 'A repeatable value', parseInt, [])\n    .action(function(options) {\n        console.log(' int: %j', options.integer);\n        console.log(' float: %j', options.float);\n        console.log(' range: from %j to %j', options.range[0], options.range[1]);\n        console.log(' list:', options.list);\n        console.log(' optional: %j', options.optional);\n        console.log(' collection:', options.collection);\n    });\n\napp.listen();\n```\n\n#### Optional or required\n\nThe option value is optional by default. And you can also declare it as `[optional]` or `\u003crequired\u003e` explicitly. It would throw an error if users forgot to give the required option a value unless `app.allowUnknowns = true`.\n\n#### Type of options\n\nOption value can be boolean(default), string or array. Just prepend '...' to the option name to declare it as an array type.\n\n#### Default value of options\n\nYou can specify a default value when define.\n\nIf you didn't specify a default value, it should be:\n\n+ for boolean type, false, or true when with `--no-`\n+ for string type, a empty string\n+ for array type, a empty array\n\n#### Passing values to options\n\nWhen passing values, the input order of arguments and options are not limited.\n\n**Boolean**\n\nSuppose there is an option `-o, --options`, it would be `true` under the following condition:\n\n* `-o` or `--options`\n* `-o=true` or `--options=true`\n* `-o true` or `--options true`\n\nor `false` under the following condition:\n\n* `--no-options`\n* `-o=false` or `--options=false`\n* `-o false` or `--options false`\n\n**String**\n\nFollowing the option flag.\n\n**Array**\n\nFollowing the option flag, values are separated by space.\n\n### Alias name\n\nYou can use `.alias(aliases)` to specify one or more alias names for the current command.\n\nThe argument `aliases` can be an array or a string(in this condition you should use `,` or `|` to separate the multiple aliases).\n\n### Descriptions\n\nYou can use `.describe(arg, description)` to specify description for the command or it's arguments.\n\nIt adds the description for the current command when no `arg` is specified, otherwise for the `arg`.\n\n### Hander of the command\n\nYou can use `.action(handler)` to defined a handler to response the user's input. You can pass a callback function or it's file path.\n\n#### Arguments of the callback\n\nThe command's arguments will also be the callback's arguments, and the next argument is a json object stores all the command's options, the last argument is also a json object which contains some useful command line args object.\n\n#### Context of the callback\n\nInside the callback function, `this` will point to the current command, which means you can use `this` to obtain all properties and methods of the current command.\n\n### Default command\n\nThere is an anonymous default command that takes over all undefined command inputs. This command has no handler by default, and can be redefined as needed.\n\n## Help information\n\n### Auto generated help\n\nThe help information is auto generated based on the descriptions. So when users typed `-h` or `--help` after a command, it would display the help information automatically.\n\n```text\n $ node ./examples/npm uninstall -h\n\n  About\n\n    This uninstalls a package, completely removing everything npm installed on its behalf.\n\n  Usage\n\n    npm uninstall|remove|rm|r|un|unlink \u003cpackages\u003e [options]                              \n\n  Arguments\n\n    packages                                                                      \n\n  Options\n\n    -S, --save             Package will be removed from your dependencies.        \n    -D, --save-dev         Package will be removed from your devDependencies.     \n    -O, --save-optional    Package will be removed from your optionalDependencies.\n    -h, --help             output the help information                            \n\n```\n\n### Custom help\n\nYou can use `.customHelp()` to make a custom help information. You should pass a callback to this function, and the auto generated help would be the first argument for this callback, you should return a new string as the custom help.\n\nYou can use the [cubb](https://github.com/Spikef/cubb) syntax to style the help information.\n\n```js\n#!/usr/bin/env node\n\nvar app = require('cmdu');\n\napp\n    .option('-f, --foo', 'enable some foo')\n    .option('-b, --bar', 'enable some bar')\n    .option('-B, --baz', 'enable some baz')\n    .customHelp(function(help) {\n        help = help + '\\n\\n' + [\n            '| [example] |',\n            '| $ help --help |',\n            '| $ help -h |'\n        ].join('\\n');\n\n        return help;\n    });\n\napp.listen();\n```\n\n### Show help manually\n\nYou can use `.showHelp()` to display help information manually.\n\n```javascript\nvar app = require('cmdu');\n\napp\n    .action(function() {\n        this.showHelp();    // Show help for current command\n    });\n\napp.listen();\n```\n\n## Examples\n\nMore examples can be found under the [examples](https://github.com/Spikef/cmdu/tree/master/examples) directory. \n\n## License\n\nMIT","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspikef%2Fcmdu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspikef%2Fcmdu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspikef%2Fcmdu/lists"}