Comparing version 1.2.0 to 1.3.0
@@ -21,4 +21,11 @@ const mri = require('mri'); | ||
command(str, desc, opts) { | ||
let [cmd, ...usage] = str.split(/\s+/); | ||
let cmd=[], usage=[], rgx=/(\[|<)/; | ||
// All non-([|<) are commands | ||
str.split(/\s+/).forEach(x => { | ||
(rgx.test(x.charAt(0)) ? usage : cmd).push(x); | ||
}); | ||
// Back to string~! | ||
cmd = cmd.join(' '); | ||
if (cmd in this.tree) { | ||
@@ -85,7 +92,17 @@ throw new Error(`Command already exists: ${cmd}`); | ||
parse(arr, opts={}) { | ||
let offset = 2; // argv slicer | ||
let alias = { h:'help', v:'version' }; | ||
let argv = mri(arr.slice(2), { alias }); | ||
let argv = mri(arr.slice(offset), { alias }); | ||
let bin = this.name; | ||
let name = argv._[0]; // may be undefined | ||
// Loop thru possible command(s) | ||
let tmp, name=''; | ||
let i=1, len=argv._.length + 1; | ||
for (; i < len; i++) { | ||
tmp = argv._.slice(0, i).join(' '); | ||
if (this.tree[tmp] !== void 0) { | ||
name=tmp; offset=(i + 2); // argv slicer | ||
} | ||
} | ||
let cmd = this.tree[name]; | ||
@@ -121,3 +138,3 @@ let isVoid = (cmd === void 0); | ||
let vals = mri(arr.slice(3), opts); | ||
let vals = mri(arr.slice(offset), opts); | ||
let segs = cmd.usage.split(/\s+/); | ||
@@ -124,0 +141,0 @@ let reqs = segs.filter(x => x.charAt(0)==='<'); |
{ | ||
"name": "sade", | ||
"version": "1.2.0", | ||
"version": "1.3.0", | ||
"description": "Smooth (CLI) operator 🎶", | ||
@@ -5,0 +5,0 @@ "repository": "lukeed/sade", |
@@ -7,3 +7,3 @@ # sade [![Build Status](https://travis-ci.org/lukeed/sade.svg?branch=master)](https://travis-ci.org/lukeed/sade) | ||
It enables default commands, option flags with aliases, default option values with type-casting, required-vs-optional argument handling, command validation, and automated help text generation! | ||
It enables default commands, git-like subcommands, option flags with aliases, default option values with type-casting, required-vs-optional argument handling, command validation, and automated help text generation! | ||
@@ -94,2 +94,5 @@ Your app's UX will be as smooth as butter... just like [Sade's voice](https://www.youtube.com/watch?v=4TYv2PhG89A). 😉 | ||
- **Define all commands & options in the order that you want them to appear.**<br> | ||
_Sade will not mutate or sort your CLI for you. Global options print before local options._ | ||
- **Required arguments without values will error & exit**<br> | ||
@@ -108,2 +111,35 @@ _An `Insufficient arguments!` error will be displayed along with a help prompt._ | ||
## Subcommands | ||
Subcommands are defined & parsed like any other command! When defining their [`usage`](#usage-1), everything up until the first argument (`[foo]` or `<foo>`) is interpreted as the command string. | ||
They should be defined in the order that you want them to appear in your general `--help` output. | ||
Lastly, it is _not_ necessary to define the subcommand's "base" as an additional command. However, if you choose to do so, it's recommended that you define it first for better visibility. | ||
```js | ||
const prog = sade('git'); | ||
// Not necessary for subcommands to work, but it's here anyway! | ||
prog | ||
.command('remote') | ||
.describe('Manage set of tracked repositories') | ||
.action(opts => { | ||
console.log('~> Print current remotes...'); | ||
}); | ||
prog | ||
.command('remote add <name> <url>', 'Demo...') | ||
.action((name, url, opts) => { | ||
console.log(`~> Adding a new remote (${name}) to ${url}`); | ||
}); | ||
prog | ||
.command('remote rename <old> <new>', 'Demo...') | ||
.action((old, nxt, opts) => { | ||
console.log(`~> Renaming from ${old} to ${nxt}~!`); | ||
}); | ||
``` | ||
## API | ||
@@ -110,0 +146,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
19250
201
424