From 5e3efa02a67755231a1463aaf3068f2ac3189ce5 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Mon, 31 Aug 2015 12:13:17 -0700 Subject: [PATCH] 'triton packages --human' for M/G/T units on sizes --- lib/common.js | 55 +++++++++++++++++++++++++++++++++++++++++----- lib/do_packages.js | 35 ++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 6 deletions(-) diff --git a/lib/common.js b/lib/common.js index ad0af41..ca5065f 100755 --- a/lib/common.js +++ b/lib/common.js @@ -179,20 +179,65 @@ function humanDurationFromMs(ms) { /** * Adapted from + * + * @param {Number} opts.precision The number of decimal places of precision to + * include. Note: This is just clipping (i.e. floor) instead of rounding. + * TODO: round + * @param {Boolean} opts.narrow Make it as narrow as possible: short units, + * no space between value and unit, drop precision if it is all zeros. */ -function humanSizeFromBytes(bytes) { +function humanSizeFromBytes(opts, bytes) { + if (bytes === undefined) { + opts = {}; + bytes = opts; + } assert.number(bytes, 'bytes'); - var sizes = ['B', 'KiB', 'MiB', 'GiB', 'TiB']; + // The number of decimal places, default 1. + assert.optionalNumber(opts.precision, 'opts.precision'); + var precision = opts.precision === undefined ? 1 : opts.precision; + assert.ok(precision >= 0); + assert.optionalBool(opts.narrow, 'opts.narrow'); + + var sizes = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB']; + if (opts.narrow) { + sizes = ['B', 'K', 'M', 'G', 'T', 'P']; + } + var template = opts.narrow ? '%s%s' : '%s %s'; + if (bytes === 0) { return '0 B'; } + var i = Number(Math.floor(Math.log(bytes) / Math.log(1024))); var s = String(bytes / Math.pow(1024, i)); - var precision1 = (s.indexOf('.') === -1 - ? s + '.0' : s.slice(0, s.indexOf('.') + 2)); - return format('%s %s', precision1, sizes[i]); + var hasDecimal = s.indexOf('.') !== -1; + if (precision === 0) { + if (hasDecimal) { + s = s.slice(0, s.indexOf('.')); + } + } else if (opts.narrow && !hasDecimal) { + /* skip all-zero precision */ + } else { + if (!hasDecimal) { + s += '.'; + } + var places = s.length - s.indexOf('.') - 1; + while (places < precision) { + s += '0'; + places++; + } + if (places > precision) { + s = s.slice(0, s.length - places + precision); + } + } + //var precision1 = (s.indexOf('.') === -1 + // ? s + '.0' : s.slice(0, s.indexOf('.') + 2)); + + return format(template, s, sizes[i]); } +humanSizeFromBytes({precision:1}, 1638400); + function capitalize(s) { return s[0].toUpperCase() + s.substr(1); } diff --git a/lib/do_packages.js b/lib/do_packages.js index 30c355e..42065a7 100644 --- a/lib/do_packages.js +++ b/lib/do_packages.js @@ -14,7 +14,7 @@ function do_packages (subcmd, opts, args, callback) { return; } - var columns = 'shortid,name,default,memory,disk'.split(','); + var columns = 'shortid,name,default,memory,swap,disk'.split(','); if (opts.o) { /* JSSTYLED */ columns = opts.o.trim().split(/\s*,\s*/g); @@ -46,6 +46,34 @@ function do_packages (subcmd, opts, args, callback) { for (var i = 0; i < pkgs.length; i++) { var pkg = pkgs[i]; pkg.shortid = pkg.id.split('-', 1)[0]; + if (opts.human) { + pkg.memoryHuman = common.humanSizeFromBytes({ + precision: 1, + narrow: true + }, pkg.memory * 1024 * 1024); + pkg.swapHuman = common.humanSizeFromBytes({ + precision: 1, + narrow: true + }, pkg.swap * 1024 * 1024); + pkg.diskHuman = common.humanSizeFromBytes({ + precision: 1, + narrow: true + }, pkg.disk * 1024 * 1024); + } + } + if (opts.human) { + columns = columns.map(function (c) { + switch (c) { + case 'memory': + return {lookup: 'memoryHuman', name: 'MEMORY'}; + case 'swap': + return {lookup: 'swapHuman', name: 'SWAP'}; + case 'disk': + return {lookup: 'diskHuman', name: 'DISK'}; + default: + return c; + } + }); } tabula(pkgs, { skipHeader: opts.H, @@ -89,6 +117,11 @@ do_packages.options = [ help: 'Sort on the given fields. Default is "name".', helpArg: 'field1,...' }, + { + names: ['human'], + type: 'bool', + help: '"Human-readable" output. Show MiB, GiB, etc units for sizes.' + }, { names: ['json', 'j'], type: 'bool',