clistyle: updated bash completion (much improved, fixes limitation that subsubcmds weren't supported)

This commit is contained in:
Trent Mick 2016-01-09 16:55:12 -08:00
parent 922ca13816
commit 3f427adff1
31 changed files with 219 additions and 161 deletions

View File

@ -2,28 +2,46 @@
## 4.0.0 (not yet released) ## 4.0.0 (not yet released)
- Much improved Bash completion. - [backwards incompat] #66 New consistent `triton` CLI style. See [the
issue](https://github.com/joyent/node-triton/issues/66) for discussion.
- XXX changes in `triton instance,key,network,account`. The major changes is that where some sub-commands used to be some
Drops `triton whoami`. Want to keep that? flavour of:
triton things # list all the things
triton thing ID # get a thing
triton thing -a ID # create a new thing
Now commands are consistently:
triton thing list # list all the things
triton thing get ID # get a thing
triton thing create ... # create a new thing
...
The most annoying incompatility is the need for "get" to
get a thing. E.g.:
BEFORE AFTER
triton img blah triton img get blah
triton inst web0 triton inst get web0
For *listing* things, there is typically a shortcut with
the old form, e.g. `triton images` is a shortcut for
`triton image list`.
Currently all of the CLI *except* the experimental `triton rbac ...`
is converted to the new consistent style.
- [backwards incompat] `triton whoami` was dropped. This used to be a shortcut
for `triton account get`. It could possibly come back.
- *Much* improved Bash completion.
- Add the ability to create a profile copying from an existing profile, - Add the ability to create a profile copying from an existing profile,
via `triton profile create --copy NAME`. via `triton profile create --copy NAME`.
- [backwards incompat] #66 `triton profile` now has list, get, etc. sub-commands. - `triton key add` was added (<https://apidocs.joyent.com/cloudapi/#CreateKey>).
One backwards incompatible change here is that `triton profile NAME` is
now `triton profile get NAME`. Note that for bwcompat `triton profiles` is
a shortcut for `triton profile list`.
- [backwards incompat] #66 `triton image` now has list, get sub-commands.
One backwards incompatible change here is that `triton image ID|NAME` is
now `triton image get ID|NAME`. Note that for bwcompat `triton images` is
a shortcut for `triton image list`.
- [backwards incompat] #66 `triton package` now has list, get sub-commands.
One backwards incompatible change here is that `triton package ID|NAME` is
now `triton package get ID|NAME`. Note that for bwcompat `triton packages` is
a shortcut for `triton package list`.
## 3.6.1 (not yet released) ## 3.6.1 (not yet released)

View File

@ -5,21 +5,20 @@
*/ */
/* /*
* Copyright 2015 Joyent, Inc. * Copyright 2016 Joyent, Inc.
* *
* `triton create ...` bwcompat shortcut for `triton instance create ...`. * `triton create ...` bwcompat shortcut for `triton instance create ...`.
*/ */
function do_create(subcmd, opts, args, callback) { function do_create(subcmd, opts, args, callback) {
var subcmdArgv = ['node', 'triton', 'instance', 'create'].concat(args); this.handlerFromSubcmd('instance').dispatch({
this.dispatch('instance', subcmdArgv, callback); subcmd: 'create',
opts: opts,
args: args
}, callback);
} }
do_create.help = [ do_create.help = 'A shortcut for "triton instance create".';
'A shortcut for "triton instance create".', do_create.options = require('./do_instance/do_create').options;
'',
'Usage:',
' {{name}} create ...'
].join('\n');
module.exports = do_create; module.exports = do_create;

View File

@ -5,23 +5,21 @@
*/ */
/* /*
* Copyright 2015 Joyent, Inc. * Copyright 2016 Joyent, Inc.
* *
* `triton delete ...` bwcompat shortcut for `triton instance delete ...`. * `triton delete ...` bwcompat shortcut for `triton instance delete ...`.
*/ */
function do_delete(subcmd, opts, args, callback) { function do_delete(subcmd, opts, args, callback) {
var subcmdArgv = ['node', 'triton', 'instance', 'delete'].concat(args); this.handlerFromSubcmd('instance').dispatch({
this.dispatch('instance', subcmdArgv, callback); subcmd: 'delete',
opts: opts,
args: args
}, callback);
} }
do_delete.help = [ do_delete.help = 'A shortcut for "triton instance delete".';
'A shortcut for "triton instance delete".',
'',
'Usage:',
' {{name}} delete ...'
].join('\n');
do_delete.aliases = ['rm']; do_delete.aliases = ['rm'];
do_delete.options = require('./do_instance/do_delete').options;
module.exports = do_delete; module.exports = do_delete;

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright 2015 Joyent, Inc. * Copyright 2016 Joyent, Inc.
* *
* `triton image get ...` * `triton image get ...`
*/ */
@ -55,7 +55,7 @@ do_get.help = (
'Get an image.\n' + 'Get an image.\n' +
'\n' + '\n' +
'Usage:\n' + 'Usage:\n' +
' {{name}} image get [<options>] ID|NAME\n' + ' {{name}} get [<options>] ID|NAME\n' +
'\n' + '\n' +
'{{options}}' + '{{options}}' +
'\n' + '\n' +

View File

@ -130,7 +130,7 @@ do_list.help = (
'List images.\n' + 'List images.\n' +
'\n' + '\n' +
'Usage:\n' + 'Usage:\n' +
' {{name}} image list [<options>] [<filters>]\n' + ' {{name}} list [<options>] [<filters>]\n' +
'\n' + '\n' +
'{{options}}' + '{{options}}' +
'\n' + '\n' +

View File

@ -5,25 +5,22 @@
*/ */
/* /*
* Copyright 2015 Joyent, Inc. * Copyright 2016 Joyent, Inc.
* *
* `triton images ...` bwcompat shortcut for `triton image list ...`. * `triton images ...` bwcompat shortcut for `triton image list ...`.
*/ */
function do_images(subcmd, opts, args, callback) { function do_images(subcmd, opts, args, callback) {
var subcmdArgv = ['node', 'triton', 'image', 'list'].concat(args); this.handlerFromSubcmd('image').dispatch({
this.dispatch('image', subcmdArgv, callback); subcmd: 'list',
opts: opts,
args: args
}, callback);
} }
do_images.help = [ do_images.help = 'A shortcut for "triton image list".';
'A shortcut for "triton image list".',
'',
'Usage:',
' {{name}} images ...'
].join('\n');
do_images.aliases = ['imgs']; do_images.aliases = ['imgs'];
do_images.hidden = true; do_images.hidden = true;
do_images.options = require('./do_image/do_list').options;
module.exports = do_images; module.exports = do_images;

View File

@ -307,7 +307,7 @@ function do_create(subcmd, opts, args, cb) {
vasync.pipeline({arg: {}, funcs: [ vasync.pipeline({arg: {}, funcs: [
function loadMetadata(ctx, next) { function loadMetadata(ctx, next) {
metadataFromOpts(opts, self.log, function (err, metadata) { metadataFromOpts(opts, log, function (err, metadata) {
if (err) { if (err) {
next(err); next(err);
return; return;
@ -321,7 +321,7 @@ function do_create(subcmd, opts, args, cb) {
}); });
}, },
function loadTags(ctx, next) { function loadTags(ctx, next) {
tagsFromOpts(opts, self.log, function (err, tags) { tagsFromOpts(opts, log, function (err, tags) {
if (err) { if (err) {
next(err); next(err);
return; return;

View File

@ -0,0 +1,17 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/*
* Copyright 2016 Joyent, Inc.
*
* `triton instance delete ...`
*/
var gen_do_ACTION = require('./gen_do_ACTION');
var do_delete = gen_do_ACTION({action: 'delete', aliases: ['rm']});
module.exports = do_delete;

View File

@ -50,7 +50,7 @@ do_get.help = (
'Get an instance.\n' 'Get an instance.\n'
+ '\n' + '\n'
+ 'Usage:\n' + 'Usage:\n'
+ ' {{name}} instance <alias|id>\n' + ' {{name}} get <alias|id>\n'
+ '\n' + '\n'
+ '{{options}}' + '{{options}}'
+ '\n' + '\n'

View File

@ -146,7 +146,7 @@ do_list.help = (
'List instances.\n' 'List instances.\n'
+ '\n' + '\n'
+ 'Usage:\n' + 'Usage:\n'
+ ' {{name}} instance list [<filters>...]\n' + ' {{name}} list [<filters>...]\n'
+ '\n' + '\n'
+ '{{options}}' + '{{options}}'
); );

View File

@ -0,0 +1,17 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/*
* Copyright 2016 Joyent, Inc.
*
* `triton instance reboot ...`
*/
var gen_do_ACTION = require('./gen_do_ACTION');
var do_reboot = gen_do_ACTION({action: 'reboot'});
module.exports = do_reboot;

View File

@ -0,0 +1,17 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/*
* Copyright 2016 Joyent, Inc.
*
* `triton instance start ...`
*/
var gen_do_ACTION = require('./gen_do_ACTION');
var do_start = gen_do_ACTION({action: 'start'});
module.exports = do_start;

View File

@ -0,0 +1,17 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/*
* Copyright 2016 Joyent, Inc.
*
* `triton instance stop ...`
*/
var gen_do_ACTION = require('./gen_do_ACTION');
var do_stop = gen_do_ACTION({action: 'stop'});
module.exports = do_stop;

View File

@ -7,6 +7,7 @@
/* /*
* Copyright 2015 Joyent, Inc. * Copyright 2015 Joyent, Inc.
* *
* Shared support for:
* `triton instance start ...` * `triton instance start ...`
* `triton instance stop ...` * `triton instance stop ...`
* `triton instance reboot ...` * `triton instance reboot ...`

View File

@ -13,8 +13,6 @@
var Cmdln = require('cmdln').Cmdln; var Cmdln = require('cmdln').Cmdln;
var util = require('util'); var util = require('util');
var gen_do_ACTION = require('./gen_do_ACTION');
// ---- CLI class // ---- CLI class
@ -57,12 +55,11 @@ InstanceCLI.prototype.init = function init(opts, args, cb) {
InstanceCLI.prototype.do_list = require('./do_list'); InstanceCLI.prototype.do_list = require('./do_list');
InstanceCLI.prototype.do_get = require('./do_get'); InstanceCLI.prototype.do_get = require('./do_get');
InstanceCLI.prototype.do_create = require('./do_create'); InstanceCLI.prototype.do_create = require('./do_create');
InstanceCLI.prototype.do_delete = gen_do_ACTION( InstanceCLI.prototype.do_delete = require('./do_delete');
{action: 'delete', aliases: ['rm']});
InstanceCLI.prototype.do_start = gen_do_ACTION({action: 'start'}); InstanceCLI.prototype.do_start = require('./do_start');
InstanceCLI.prototype.do_stop = gen_do_ACTION({action: 'stop'}); InstanceCLI.prototype.do_stop = require('./do_stop');
InstanceCLI.prototype.do_reboot = gen_do_ACTION({action: 'reboot'}); InstanceCLI.prototype.do_reboot = require('./do_reboot');
InstanceCLI.prototype.do_ssh = require('./do_ssh'); InstanceCLI.prototype.do_ssh = require('./do_ssh');
InstanceCLI.prototype.do_wait = require('./do_wait'); InstanceCLI.prototype.do_wait = require('./do_wait');

View File

@ -5,23 +5,21 @@
*/ */
/* /*
* Copyright 2015 Joyent, Inc. * Copyright 2016 Joyent, Inc.
* *
* `triton instances ...` bwcompat shortcut for `triton instance list ...`. * `triton instances ...` bwcompat shortcut for `triton instance list ...`.
*/ */
function do_instances(subcmd, opts, args, callback) { function do_instances(subcmd, opts, args, callback) {
var subcmdArgv = ['node', 'triton', 'instance', 'list'].concat(args); this.handlerFromSubcmd('instance').dispatch({
this.dispatch('instance', subcmdArgv, callback); subcmd: 'list',
opts: opts,
args: args
}, callback);
} }
do_instances.help = [ do_instances.help = 'A shortcut for "triton instance list".';
'A shortcut for "triton instance list".',
'',
'Usage:',
' {{name}} instances ...'
].join('\n');
do_instances.aliases = ['insts', 'ls']; do_instances.aliases = ['insts', 'ls'];
do_instances.options = require('./do_instance/do_list').options;
module.exports = do_instances; module.exports = do_instances;

View File

@ -132,7 +132,6 @@ do_add.help = [
' {{name}} add [<options>] FILE', ' {{name}} add [<options>] FILE',
'', '',
'{{options}}', '{{options}}',
'',
'Where "FILE" must be a file path to an SSH public key, ', 'Where "FILE" must be a file path to an SSH public key, ',
'or "-" to pass the public key in on stdin.' 'or "-" to pass the public key in on stdin.'
].join('\n'); ].join('\n');

View File

@ -108,10 +108,9 @@ do_delete.help = [
'Remove an SSH key from an account.', 'Remove an SSH key from an account.',
'', '',
'Usage:', 'Usage:',
' {{name}} delete [<options>] FILE', ' {{name}} delete [<options>] KEY [KEY...]',
'', '',
'{{options}}', '{{options}}',
'',
'Where "KEY" is an SSH key "name" or "fingerprint".' 'Where "KEY" is an SSH key "name" or "fingerprint".'
].join('\n'); ].join('\n');

View File

@ -85,8 +85,8 @@ do_list.options = [
{ {
names: ['authorized-keys', 'A'], names: ['authorized-keys', 'A'],
type: 'bool', type: 'bool',
help: 'Just output public key data -- i.e. output appropriate for a ' + help: 'Just output public key data, one per line -- i.e. output ' +
'"~/.ssh/authorized_keys" file.' 'appropriate for a "~/.ssh/authorized_keys" file.'
} }
]); ]);
@ -96,11 +96,7 @@ do_list.help = [
'Usage:', 'Usage:',
' {{name}} list [<options>]', ' {{name}} list [<options>]',
'', '',
'{{options}}', '{{options}}'
'',
'By default this lists just the key content for each key -- in other',
'words, content appropriate for a "~/.ssh/authorized_keys" file.',
'Use `triton keys -j` to see all fields.'
].join('\n'); ].join('\n');
do_list.aliases = ['ls']; do_list.aliases = ['ls'];

View File

@ -5,23 +5,21 @@
*/ */
/* /*
* Copyright 2015 Joyent, Inc. * Copyright 2016 Joyent, Inc.
* *
* `triton keys ...` bwcompat shortcut for `triton keys list ...`. * `triton keys ...` bwcompat shortcut for `triton key list ...`.
*/ */
function do_keys(subcmd, opts, args, callback) { function do_keys(subcmd, opts, args, callback) {
var subcmdArgv = ['node', 'triton', 'key', 'list'].concat(args); this.handlerFromSubcmd('key').dispatch({
this.dispatch('key', subcmdArgv, callback); subcmd: 'list',
opts: opts,
args: args
}, callback);
} }
do_keys.help = [ do_keys.help = 'A shortcut for "triton key list".';
'A shortcut for "triton key list".',
'',
'Usage:',
' {{name}} key ...'
].join('\n');
do_keys.hidden = true; do_keys.hidden = true;
do_keys.options = require('./do_key/do_list').options;
module.exports = do_keys; module.exports = do_keys;

View File

@ -11,17 +11,15 @@
*/ */
function do_networks(subcmd, opts, args, callback) { function do_networks(subcmd, opts, args, callback) {
var subcmdArgv = ['node', 'triton', 'network', 'list'].concat(args); this.handlerFromSubcmd('network').dispatch({
this.dispatch('network', subcmdArgv, callback); subcmd: 'list',
opts: opts,
args: args
}, callback);
} }
do_networks.help = [ do_networks.help = 'A shortcut for "triton network list".';
'A shortcut for "triton network list".',
'',
'Usage:',
' {{name}} networks ...'
].join('\n');
do_networks.hidden = true; do_networks.hidden = true;
do_networks.options = require('./do_network/do_list').options;
module.exports = do_networks; module.exports = do_networks;

View File

@ -55,7 +55,7 @@ do_get.help = (
'Get a package.\n' + 'Get a package.\n' +
'\n' + '\n' +
'Usage:\n' + 'Usage:\n' +
' {{name}} package get [<options>] ID|NAME\n' + ' {{name}} get [<options>] ID|NAME\n' +
'\n' + '\n' +
'{{options}}' + '{{options}}' +
'\n' + '\n' +

View File

@ -159,7 +159,7 @@ do_list.help = [
'List packages.', 'List packages.',
'', '',
'Usage:', 'Usage:',
' {{name}} package list [<filters>]', ' {{name}} list [<filters>]',
'', '',
'{{options}}', '{{options}}',
'Filters:', 'Filters:',

View File

@ -5,25 +5,22 @@
*/ */
/* /*
* Copyright 2015 Joyent, Inc. * Copyright 2016 Joyent, Inc.
* *
* `triton packages ...` bwcompat shortcut for `triton package list ...`. * `triton packages ...` bwcompat shortcut for `triton package list ...`.
*/ */
function do_packages(subcmd, opts, args, callback) { function do_packages(subcmd, opts, args, callback) {
var subcmdArgv = ['node', 'triton', 'package', 'list'].concat(args); this.handlerFromSubcmd('package').dispatch({
this.dispatch('package', subcmdArgv, callback); subcmd: 'list',
opts: opts,
args: args
}, callback);
} }
do_packages.help = [ do_packages.help = 'A shortcut for "triton package list".';
'A shortcut for "triton package list".',
'',
'Usage:',
' {{name}} packages ...'
].join('\n');
do_packages.aliases = ['pkgs']; do_packages.aliases = ['pkgs'];
do_packages.hidden = true; do_packages.hidden = true;
do_packages.options = require('./do_package/do_list').options;
module.exports = do_packages; module.exports = do_packages;

View File

@ -5,23 +5,21 @@
*/ */
/* /*
* Copyright 2015 Joyent, Inc. * Copyright 2016 Joyent, Inc.
* *
* `triton profiles ...` bwcompat shortcut for `triton profile list ...`. * `triton profiles ...` bwcompat shortcut for `triton profile list ...`.
*/ */
function do_profiles(subcmd, opts, args, callback) { function do_profiles(subcmd, opts, args, callback) {
var subcmdArgv = ['node', 'triton', 'profile', 'list'].concat(args); this.handlerFromSubcmd('profile').dispatch({
this.dispatch('profile', subcmdArgv, callback); subcmd: 'list',
opts: opts,
args: args
}, callback);
} }
do_profiles.help = [ do_profiles.help = 'A shortcut for "triton profile list".';
'A shortcut for "triton profile list".', do_profiles.options = require('./do_profile/do_list').options;
'',
'Usage:',
' {{name}} profiles ...'
].join('\n');
do_profiles.hidden = true; do_profiles.hidden = true;
module.exports = do_profiles; module.exports = do_profiles;

View File

@ -5,21 +5,20 @@
*/ */
/* /*
* Copyright 2015 Joyent, Inc. * Copyright 2016 Joyent, Inc.
* *
* `triton reboot ...` bwcompat shortcut for `triton instance reboot ...`. * `triton reboot ...` bwcompat shortcut for `triton instance reboot ...`.
*/ */
function do_reboot(subcmd, opts, args, callback) { function do_reboot(subcmd, opts, args, callback) {
var subcmdArgv = ['node', 'triton', 'instance', 'reboot'].concat(args); this.handlerFromSubcmd('instance').dispatch({
this.dispatch('instance', subcmdArgv, callback); subcmd: 'reboot',
opts: opts,
args: args
}, callback);
} }
do_reboot.help = [ do_reboot.help = 'A shortcut for "triton instance reboot".';
'A shortcut for "triton instance reboot".', do_reboot.options = require('./do_instance/do_reboot').options;
'',
'Usage:',
' {{name}} reboot ...'
].join('\n');
module.exports = do_reboot; module.exports = do_reboot;

View File

@ -11,15 +11,14 @@
*/ */
function do_ssh(subcmd, opts, args, callback) { function do_ssh(subcmd, opts, args, callback) {
var subcmdArgv = ['node', 'triton', 'instance', 'ssh'].concat(args); this.handlerFromSubcmd('instance').dispatch({
this.dispatch('instance', subcmdArgv, callback); subcmd: 'ssh',
opts: opts,
args: args
}, callback);
} }
do_ssh.help = [ do_ssh.help = 'A shortcut for "triton instance ssh".';
'A shortcut for "triton instance ssh".', do_ssh.options = require('./do_instance/do_ssh').options;
'',
'Usage:',
' {{name}} ssh ...'
].join('\n');
module.exports = do_ssh; module.exports = do_ssh;

View File

@ -5,21 +5,20 @@
*/ */
/* /*
* Copyright 2015 Joyent, Inc. * Copyright 2016 Joyent, Inc.
* *
* `triton start ...` bwcompat shortcut for `triton instance start ...`. * `triton start ...` bwcompat shortcut for `triton instance start ...`.
*/ */
function do_start(subcmd, opts, args, callback) { function do_start(subcmd, opts, args, callback) {
var subcmdArgv = ['node', 'triton', 'instance', 'start'].concat(args); this.handlerFromSubcmd('instance').dispatch({
this.dispatch('instance', subcmdArgv, callback); subcmd: 'start',
opts: opts,
args: args
}, callback);
} }
do_start.help = [ do_start.help = 'A shortcut for "triton instance start".';
'A shortcut for "triton instance start".', do_start.options = require('./do_instance/do_start').options;
'',
'Usage:',
' {{name}} start ...'
].join('\n');
module.exports = do_start; module.exports = do_start;

View File

@ -5,21 +5,20 @@
*/ */
/* /*
* Copyright 2015 Joyent, Inc. * Copyright 2016 Joyent, Inc.
* *
* `triton stop ...` bwcompat shortcut for `triton instance stop ...`. * `triton stop ...` bwcompat shortcut for `triton instance stop ...`.
*/ */
function do_stop(subcmd, opts, args, callback) { function do_stop(subcmd, opts, args, callback) {
var subcmdArgv = ['node', 'triton', 'instance', 'stop'].concat(args); this.handlerFromSubcmd('instance').dispatch({
this.dispatch('instance', subcmdArgv, callback); subcmd: 'stop',
opts: opts,
args: args
}, callback);
} }
do_stop.help = [ do_stop.help = 'A shortcut for "triton instance stop".';
'A shortcut for "triton instance stop".', do_stop.options = require('./do_instance/do_stop').options;
'',
'Usage:',
' {{name}} stop ...'
].join('\n');
module.exports = do_stop; module.exports = do_stop;

View File

@ -8,7 +8,7 @@
"backoff": "2.4.1", "backoff": "2.4.1",
"bigspinner": "3.1.0", "bigspinner": "3.1.0",
"bunyan": "1.5.1", "bunyan": "1.5.1",
"cmdln": "3.5.0", "cmdln": "3.5.2",
"extsprintf": "1.0.2", "extsprintf": "1.0.2",
"lomstream": "1.1.0", "lomstream": "1.1.0",
"mkdirp": "0.5.1", "mkdirp": "0.5.1",

View File

@ -40,7 +40,8 @@ test('triton networks', function (tt) {
h.triton('help networks', function (err, stdout, stderr) { h.triton('help networks', function (err, stdout, stderr) {
if (h.ifErr(t, err)) if (h.ifErr(t, err))
return t.end(); return t.end();
t.ok(/Usage:\s+triton networks/.test(stdout)); // JSSTYLED
t.ok(/shortcut for "triton network list"/.test(stdout));
t.end(); t.end();
}); });
}); });