From e48395d446de9e6c346d4c20c33241b40eb59a70 Mon Sep 17 00:00:00 2001 From: Dave Eddy Date: Thu, 3 Sep 2015 18:09:21 -0400 Subject: [PATCH] add common.getCliTableOptions for tabula - common tabula options managed in "common" - "datacenters" and "services" pass raw data with -j --- lib/common.js | 106 ++++++++++++++++++++++++++++++------------ lib/do_datacenters.js | 44 +++++++++++------- lib/do_images.js | 70 ++++++++++++---------------- lib/do_instances.js | 26 ++++++++--- lib/do_networks.js | 54 ++++++++------------- lib/do_packages.js | 76 ++++++++++++++---------------- lib/do_services.js | 45 ++++++++++-------- 7 files changed, 231 insertions(+), 190 deletions(-) diff --git a/lib/common.js b/lib/common.js index cda485c..3da99b3 100644 --- a/lib/common.js +++ b/lib/common.js @@ -16,34 +16,6 @@ var p = console.log; var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/; -var TABULA_OPTIONS = [ - { - group: 'Output options' - }, - { - names: ['H'], - type: 'bool', - help: 'Omit table header row.' - }, - { - names: ['o'], - type: 'string', - help: 'Specify fields (columns) to output.', - helpArg: 'field1,...' - }, - { - names: ['s'], - type: 'string', - help: 'Sort on the given fields.', - helpArg: 'field1,...' - }, - { - names: ['json', 'j'], - type: 'bool', - help: 'JSON output.' - } -]; - // ---- support stuff function objCopy(obj, target) { @@ -349,6 +321,82 @@ function slug(o) { return s; } +/* + * take some basic information and return node-cmdln options suitable for + * tabula + * + * @param {String} (optional) opts.columnDefault Default value for `-o` + * @param {String} (optional) opts.sortDefault Default value for `-s` + * @param {String} (optional) opts.includeLong Include `-l` option + * @return {Array} Array of cmdln options objects + */ +function getCliTableOptions(opts) { + opts = opts || {}; + assert.object(opts, 'opts'); + assert.optionalString(opts.columnsDefault, 'opts.columnsDefault'); + assert.optionalString(opts.sortDefault, 'opts.sortDefault'); + assert.optionalBool(opts.includeLong, 'opts.includeLong'); + + var o; + + // construct the options object + var tOpts = []; + + // header + tOpts.push({ + group: 'Output options' + }); + + // -H + tOpts.push({ + names: ['H'], + type: 'bool', + help: 'Omit table header row.' + }); + + // -o field1,field2,... + o = { + names: ['o'], + type: 'string', + help: 'Specify fields (columns) to output.', + helpArg: 'field1,...' + }; + if (opts.columnsDefault) + o.default = opts.columnsDefault; + tOpts.push(o); + + // -l, --long + if (opts.includeLong) { + tOpts.push({ + names: ['long', 'l'], + type: 'bool', + help: 'Long/wider output. Ignored if "-o ..." is used.' + }); + } + + // -s field1,field2,... + o = { + names: ['s'], + type: 'string', + help: 'Sort on the given fields.', + helpArg: 'field1,...' + }; + if (opts.sortDefault) { + o.default = opts.sortDefault; + o.help = format('%s Default is "%s"."', o.help, opts.sortDefault); + } + tOpts.push(o); + + // -j, --json + tOpts.push({ + names: ['json', 'j'], + type: 'bool', + help: 'JSON output.' + }); + + return tOpts; +} + //---- exports @@ -367,6 +415,6 @@ module.exports = { capitalize: capitalize, normShortId: normShortId, slug: slug, - TABULA_OPTIONS: TABULA_OPTIONS + getCliTableOptions: getCliTableOptions }; // vim: set softtabstop=4 shiftwidth=4: diff --git a/lib/do_datacenters.js b/lib/do_datacenters.js index aa57d47..20c6aab 100644 --- a/lib/do_datacenters.js +++ b/lib/do_datacenters.js @@ -8,6 +8,12 @@ var tabula = require('tabula'); var common = require('./common'); +// columns default without -o +var columnsDefault = 'name,url'; + +// sort default with -s +var sortDefault = 'name'; + function do_datacenters(subcmd, opts, args, callback) { if (opts.help) { this.do_help('help', {}, [subcmd], callback); @@ -17,8 +23,8 @@ function do_datacenters(subcmd, opts, args, callback) { return; } - var columns = (opts.o || 'name,url').split(','); - var sort = (opts.s || 'name').split(','); + var columns = opts.o.split(','); + var sort = opts.s.split(','); this.triton.cloudapi.listDatacenters(function (err, datacenters) { if (err) { @@ -26,23 +32,21 @@ function do_datacenters(subcmd, opts, args, callback) { return; } - /* - * datacenters are returned in the form of: - * {name: 'url', name2: 'url2', ...} - * we "normalize" them for use by tabula and JSON stream - * by making them an array - */ - var dcs = []; - Object.keys(datacenters).forEach(function (key) { - dcs.push({ - name: key, - url: datacenters[key] - }); - }); - if (opts.json) { - common.jsonStream(dcs); + console.log(JSON.stringify(datacenters)); } else { + /* + * datacenters are returned in the form of: + * {name: 'url', name2: 'url2', ...} + * we "normalize" them for use by tabula by making them an array + */ + var dcs = []; + Object.keys(datacenters).forEach(function (key) { + dcs.push({ + name: key, + url: datacenters[key] + }); + }); tabula(dcs, { skipHeader: opts.H, columns: columns, @@ -60,7 +64,11 @@ do_datacenters.options = [ type: 'bool', help: 'Show this help.' } -].concat(common.TABULA_OPTIONS); +].concat(common.getCliTableOptions({ + columnsDefault: columnsDefault, + sortDefault: sortDefault +})); + do_datacenters.help = ( 'Show datacenters information\n' + '\n' diff --git a/lib/do_images.js b/lib/do_images.js index 76afe18..a530be2 100644 --- a/lib/do_images.js +++ b/lib/do_images.js @@ -10,6 +10,25 @@ var tabula = require('tabula'); var common = require('./common'); var errors = require('./errors'); +// filters to pass triton.listImages +var validFilters = [ + 'name', + 'os', + 'version', + 'public', + 'state', + 'owner', + 'type' +]; + +// columns default without -o +var columnsDefault = 'shortid,name,version,state,flags,os,pubdate'; + +// columns default with -l +var columnsDefaultLong = 'id,name,version,state,flags,os,pubdate'; + +// sort default with -s +var sortDefault = 'published_at'; function do_images(subcmd, opts, args, callback) { if (opts.help) { @@ -17,19 +36,16 @@ function do_images(subcmd, opts, args, callback) { return; } - var columns = 'shortid,name,version,state,flags,os,pubdate'.split(','); + var columns = columnsDefault; if (opts.o) { - /* JSSTYLED */ - columns = opts.o.trim().split(/\s*,\s*/g); + columns = opts.o; } else if (opts.long) { - columns[0] = 'id'; + columns = columnsDefaultLong; } - /* JSSTYLED */ - var sort = opts.s.trim().split(/\s*,\s*/g); + columns = columns.split(','); + + var sort = opts.s.split(','); - var validFilters = [ - 'name', 'os', 'version', 'public', 'state', 'owner', 'type' - ]; var listOpts; try { listOpts = common.kvToObj(args, validFilters); @@ -97,39 +113,11 @@ do_images.options = [ type: 'bool', help: 'List all images, not just "active" ones. This ' + 'is a shortcut for the "state=all" filter.' - }, - { - group: 'Output options' - }, - { - names: ['H'], - type: 'bool', - help: 'Omit table header row.' - }, - { - names: ['o'], - type: 'string', - help: 'Specify fields (columns) to output.', - helpArg: 'field1,...' - }, - { - names: ['long', 'l'], - type: 'bool', - help: 'Long/wider output. Ignored if "-o ..." is used.' - }, - { - names: ['s'], - type: 'string', - default: 'published_at', - help: 'Sort on the given fields. Default is "published_at".', - helpArg: 'field1,...' - }, - { - names: ['json', 'j'], - type: 'bool', - help: 'JSON stream output.' } -]; +].concat(common.getCliTableOptions({ + includeLong: true, + sortDefault: sortDefault +})); do_images.help = ( /* BEGIN JSSTYLED */ diff --git a/lib/do_instances.js b/lib/do_instances.js index 44523d9..57b07b0 100644 --- a/lib/do_instances.js +++ b/lib/do_instances.js @@ -20,21 +20,30 @@ var validFilters = [ 'credentials' ]; +// columns default without -o +var columnsDefault = 'shortid,name,img,state,primaryIp,ago'; + +// columns default with -l +var columnsDefaultLong = 'id,name,img,package,state,primaryIp,created'; + +// sort default with -s +var sortDefault = 'created'; + function do_instances(subcmd, opts, args, callback) { if (opts.help) { this.do_help('help', {}, [subcmd], callback); return; } - var columns = 'shortid,name,img,state,primaryIp,ago'.split(','); + var columns = columnsDefault; if (opts.o) { - /* JSSTYLED */ - columns = opts.o.trim().split(/\s*,\s*/g); + columns = opts.o; } else if (opts.long) { - columns = 'id,name,img,package,state,primaryIp,created'.split(','); + columns = columnsDefaultLong; } - /* JSSTYLED */ - var sort = (opts.s || 'created').trim().split(/\s*,\s*/g); + columns = columns.split(','); + + var sort = opts.s.split(','); var listOpts; try { @@ -109,7 +118,10 @@ do_instances.options = [ type: 'bool', help: 'Show this help.' } -].concat(common.TABULA_OPTIONS); +].concat(common.getCliTableOptions({ + includeLong: true, + sortDefault: sortDefault +})); do_instances.help = ( 'List instances.\n' diff --git a/lib/do_networks.js b/lib/do_networks.js index 0ed8de8..2ede34a 100644 --- a/lib/do_networks.js +++ b/lib/do_networks.js @@ -16,6 +16,15 @@ var validFilters = [ 'description' ]; +// columns default without -o +var columnsDefault = 'shortid,name,subnet,gateway,fabric,vlan,public'; + +// columns default with -l +var columnsDefaultLong = 'id,name,subnet,gateway,fabric,vlan,public'; + +// sort default with -s +var sortDefault = 'name'; + function do_networks(subcmd, opts, args, callback) { if (opts.help) { this.do_help('help', {}, [subcmd], callback); @@ -25,14 +34,15 @@ function do_networks(subcmd, opts, args, callback) { return; } - var columns = 'shortid,name,subnet,gateway,fabric,vlan,public'.split(','); + var columns = columnsDefault; if (opts.o) { - /* JSSTYLED */ - columns = opts.o.trim().split(/\s*,\s*/g); + columns = opts.o; } else if (opts.long) { - columns[0] = 'id'; + columns = columnsDefaultLong; } - var sort = opts.s.trim().split(','); + columns = columns.split(','); + + var sort = opts.s.split(','); this.triton.cloudapi.listNetworks(function (err, networks) { if (err) { @@ -63,36 +73,12 @@ do_networks.options = [ names: ['help', 'h'], type: 'bool', help: 'Show this help.' - }, - { - names: ['H'], - type: 'bool', - help: 'Omit table header row.' - }, - { - names: ['o'], - type: 'string', - help: 'Specify fields (columns) to output.', - helpArg: 'field1,...' - }, - { - names: ['long', 'l'], - type: 'bool', - help: 'Long/wider output. Ignored if "-o ..." is used.' - }, - { - names: ['s'], - type: 'string', - default: 'name', - help: 'Sort on the given fields. Default is "name".', - helpArg: 'field1,...' - }, - { - names: ['json', 'j'], - type: 'bool', - help: 'JSON output.' } -]; +].concat(common.getCliTableOptions({ + includeLong: true, + sortDefault: sortDefault +})); + do_networks.help = [ 'List available networks.', '', diff --git a/lib/do_packages.js b/lib/do_packages.js index 9c45bb0..f423e35 100644 --- a/lib/do_packages.js +++ b/lib/do_packages.js @@ -8,25 +8,43 @@ var tabula = require('tabula'); var common = require('./common'); +// valid filters to pass to cloudapi.listPackages +var validFilters = [ + 'name', + 'memory', + 'disk', + 'swap', + 'lwps', + 'version', + 'vcpus', + 'group' +]; + +// columns default without -o +var columnsDefault = 'shortid,name,default,memory,swap,disk'; + +// columns default with -l +var columnsDefaultLong = 'id,name,default,memory,swap,disk'; + +// sort default with -s +var sortDefault = '_groupPlus,memory'; + function do_packages(subcmd, opts, args, callback) { if (opts.help) { this.do_help('help', {}, [subcmd], callback); return; } - var columns = 'shortid,name,default,memory,swap,disk'.split(','); + var columns = columnsDefault; if (opts.o) { - /* JSSTYLED */ - columns = opts.o.trim().split(/\s*,\s*/g); + columns = opts.o; } else if (opts.long) { - columns[0] = 'id'; + columns = columnsDefaultLong; } - /* JSSTYLED */ - var sort = opts.s.trim().split(/\s*,\s*/g); + columns = columns.split(','); + + var sort = opts.s.split(','); - var validFilters = [ - 'name', 'memory', 'disk', 'swap', 'lwps', 'version', 'vcpus', 'group' - ]; var listOpts; try { listOpts = common.kvToObj(args, validFilters); @@ -102,44 +120,18 @@ do_packages.options = [ names: ['help', 'h'], type: 'bool', help: 'Show this help.' - }, - { - group: 'Output options' - }, - { - names: ['H'], - type: 'bool', - help: 'Omit table header row.' - }, - { - names: ['o'], - type: 'string', - help: 'Specify fields (columns) to output.', - helpArg: 'field1,...' - }, - { - names: ['long', 'l'], - type: 'bool', - help: 'Long/wider output. Ignored if "-o ..." is used.' - }, - { - names: ['s'], - type: 'string', - default: '_groupPlus,memory', - help: 'Sort on the given fields. Default is "group,memory".', - helpArg: 'field1,...' - }, + } +].concat(common.getCliTableOptions({ + includeLong: true, + sortDefault: sortDefault +})).concat([ { names: ['p'], type: 'bool', help: 'Display numbers in parsable (exact) values.' - }, - { - names: ['json', 'j'], - type: 'bool', - help: 'JSON output.' } -]; +]); + do_packages.help = ( 'List packgaes.\n' + '\n' diff --git a/lib/do_services.js b/lib/do_services.js index a413012..6d355e9 100644 --- a/lib/do_services.js +++ b/lib/do_services.js @@ -8,6 +8,12 @@ var tabula = require('tabula'); var common = require('./common'); +// columns default without -o +var columnsDefault = 'name,endpoint'; + +// sort default with -s +var sortDefault = 'name'; + function do_services(subcmd, opts, args, callback) { if (opts.help) { this.do_help('help', {}, [subcmd], callback); @@ -17,8 +23,8 @@ function do_services(subcmd, opts, args, callback) { return; } - var columns = (opts.o || 'name,endpoint').split(','); - var sort = (opts.s || 'name').split(','); + var columns = opts.o.split(','); + var sort = opts.s.split(','); this.triton.cloudapi.listServices(function (err, services) { if (err) { @@ -26,24 +32,22 @@ function do_services(subcmd, opts, args, callback) { return; } - /* - * services are returned in the form of: - * {name: 'endpoint', name2: 'endpoint2', ...} - * we "normalize" them for use by tabula and JSON stream - * by making them an array - */ - - var svcs = []; - Object.keys(services).forEach(function (key) { - svcs.push({ - name: key, - endpoint: services[key] - }); - }); - if (opts.json) { - common.jsonStream(svcs); + console.log(JSON.stringify(services)); } else { + /* + * services are returned in the form of: + * {name: 'endpoint', name2: 'endpoint2', ...} + * we "normalize" them for use by tabula and JSON stream + * by making them an array + */ + var svcs = []; + Object.keys(services).forEach(function (key) { + svcs.push({ + name: key, + endpoint: services[key] + }); + }); tabula(svcs, { skipHeader: opts.H, columns: columns, @@ -62,7 +66,10 @@ do_services.options = [ type: 'bool', help: 'Show this help.' } -].concat(common.TABULA_OPTIONS); +].concat(common.getCliTableOptions({ + columnsDefault: columnsDefault, + sortDefault: sortDefault +})); do_services.help = ( 'Show services information\n'