From 146d302915ecf7bfcd15646b6157ad5d37e8584b Mon Sep 17 00:00:00 2001 From: Nate Fischer Date: Tue, 14 Jan 2020 00:46:16 -0800 Subject: [PATCH] feat: allow external commands on unix External commands were previously limited to Windows. There's no good reason for this, so this adds support for Linux as well. Fixes #122 Test: manually tried `whoami` and `git status` Test: manually tried a not-found command, verified output looks good --- dist/commands/clear.js | 2 +- dist/commands/cp.js | 8 ++-- dist/commands/head.js | 2 +- dist/commands/ls.js | 2 +- dist/commands/rm.js | 12 +++--- dist/commands/unalias.js | 6 +-- dist/delimiter.js | 2 +- dist/index.js | 65 +++++++++++++---------------- dist/lib/sugar.js | 10 ++--- dist/util/colorFile.js | 2 +- dist/windows.js | 43 +++++++++---------- package.json | 1 + packages/cp/dist/commands/cp.js | 8 ++-- packages/head/dist/commands/head.js | 2 +- packages/ls/dist/commands/ls.js | 2 +- packages/ls/dist/util/colorFile.js | 2 +- packages/rm/dist/commands/rm.js | 12 +++--- packages/touch/dist/lib/sugar.js | 10 ++--- src/windows.js | 43 +++++++++---------- 19 files changed, 116 insertions(+), 118 deletions(-) diff --git a/dist/commands/clear.js b/dist/commands/clear.js index 02ee3a9..e9c1c9f 100644 --- a/dist/commands/clear.js +++ b/dist/commands/clear.js @@ -4,7 +4,7 @@ var interfacer = require('./../util/interfacer'); var clear = { exec: function exec() { - this.log('\u001b[2J\u001b[0;0H'); + this.log('\x1B[2J\x1B[0;0H'); return 0; } }; diff --git a/dist/commands/cp.js b/dist/commands/cp.js index 1a52005..2a23e54 100755 --- a/dist/commands/cp.js +++ b/dist/commands/cp.js @@ -140,10 +140,10 @@ function cpdirSyncRecursive(sourceDir, destDir, options) { fs.symlinkSync(symlinkFull, destFile, os.platform() === 'win32' ? 'junction' : null); // At this point, we've hit a file actually worth copying... so copy it on over. } else if (fs.existsSync(destFile) && options.noclobber) { - // be silent - } else { - copyFileSync.call(self, srcFile, destFile); - } + // be silent + } else { + copyFileSync.call(self, srcFile, destFile); + } } } diff --git a/dist/commands/head.js b/dist/commands/head.js index 1443c73..aeebe20 100755 --- a/dist/commands/head.js +++ b/dist/commands/head.js @@ -1,6 +1,6 @@ 'use strict'; -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var interfacer = require('./../util/interfacer'); var fs = require('fs'); diff --git a/dist/commands/ls.js b/dist/commands/ls.js index 544e03f..ffa7f55 100755 --- a/dist/commands/ls.js +++ b/dist/commands/ls.js @@ -1,6 +1,6 @@ 'use strict'; -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var chalk = require('chalk'); var filesize = require('filesize'); diff --git a/dist/commands/rm.js b/dist/commands/rm.js index 602b134..68d21eb 100755 --- a/dist/commands/rm.js +++ b/dist/commands/rm.js @@ -123,12 +123,12 @@ function rmdirSyncRecursive(dir, force, removeEmptyDir) { } /* istanbul ignore next */ } else if (er.code === 'ENOENT') { - // Directory did not exist, deletion was successful - break; - /* istanbul ignore next */ - } else { - throw er; - } + // Directory did not exist, deletion was successful + break; + /* istanbul ignore next */ + } else { + throw er; + } } } } catch (e) { diff --git a/dist/commands/unalias.js b/dist/commands/unalias.js index 971265a..6a5fb1b 100755 --- a/dist/commands/unalias.js +++ b/dist/commands/unalias.js @@ -68,10 +68,10 @@ var unalias = { // Rebuild alias lists. var aliases = {}; /* istanbul ignore next */ - for (var _i = 0; _i < all.length; ++_i) { - var item = vorpal.localStorage.getItem('alias|' + all[_i]); + for (var i = 0; i < all.length; ++i) { + var item = vorpal.localStorage.getItem('alias|' + all[i]); if (item !== undefined && item !== null) { - aliases[all[_i]] = item; + aliases[all[i]] = item; } } vorpal._aliases = aliases; diff --git a/dist/delimiter.js b/dist/delimiter.js index 30eddc1..a099950 100755 --- a/dist/delimiter.js +++ b/dist/delimiter.js @@ -20,7 +20,7 @@ module.exports = { // If we're on linux-based systems, color // the prompt so we don't get confused. if (!isWindows) { - delimiter = '\u001b[32m' + delimiter + '\u001b[39m'; + delimiter = '\x1B[32m' + delimiter + '\x1B[39m'; } vorpal.delimiter(delimiter); cb(null); diff --git a/dist/index.js b/dist/index.js index 5aee34a..9d77e8c 100755 --- a/dist/index.js +++ b/dist/index.js @@ -70,26 +70,24 @@ var app = { return; } try { - (function () { - var mod = require('./commands/' + cmd + '.js'); - var help = void 0; - try { - help = require('./help/' + cmd + '.js'); - help = String(help).replace(/^\n|\n$/g, ''); - } catch (e) { - // .. whatever - } - self.vorpal.use(mod, { - parent: self + var mod = require('./commands/' + cmd + '.js'); + var _help = void 0; + try { + _help = require('./help/' + cmd + '.js'); + _help = String(_help).replace(/^\n|\n$/g, ''); + } catch (e) { + // .. whatever + } + self.vorpal.use(mod, { + parent: self + }); + var cmdObj = self.vorpal.find(cmd); + if (cmdObj && _help) { + /* istanbul ignore next */ + cmdObj.help(function (args, cb) { + cb(_help); }); - var cmdObj = self.vorpal.find(cmd); - if (cmdObj && help) { - /* istanbul ignore next */ - cmdObj.help(function (args, cb) { - cb(help); - }); - } - })(); + } } catch (e) { /* istanbul ignore next */ self.vorpal.log('Error loading command ' + cmd + ': ', e); @@ -191,21 +189,19 @@ var app = { // for dev testing. /* istanbul ignore next */ if (os.platform().indexOf('win') > -1) { - (function () { - var counter = 0; - setInterval(function () { - counter = counter > 0 ? 0 : counter; - }, 3000); - app.vorpal.sigint(function () { - counter++; - app.vorpal.ui.submit(''); - if (counter > 5) { - app.vorpal.log('(to quit Cash, use the "exit" command)'); - counter -= 10000; - } - return; - }); - })(); + var counter = 0; + setInterval(function () { + counter = counter > 0 ? 0 : counter; + }, 3000); + app.vorpal.sigint(function () { + counter++; + app.vorpal.ui.submit(''); + if (counter > 5) { + app.vorpal.log('(to quit Cash, use the "exit" command)'); + counter -= 10000; + } + return; + }); } // Load .cashrc upon startup @@ -238,7 +234,6 @@ var app = { cmds = { /* istanbul ignore next */ - show: function show() { /* istanbul ignore next */ app.vorpal.show(); diff --git a/dist/lib/sugar.js b/dist/lib/sugar.js index ffee6c5..620d9e0 100755 --- a/dist/lib/sugar.js +++ b/dist/lib/sugar.js @@ -1,6 +1,6 @@ "use strict"; -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /* * Sugar Library v1.4.1 @@ -146,7 +146,7 @@ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol Ja = "", Ka = {}, La;function Ma() { - return "\t\n\u000b\f\r   ᠎             \u2028\u2029 "; + return "\t\n\x0B\f\r \xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u2028\u2029\u3000\uFEFF"; }function Na(a, b) { var c = "";for (a = a.toString(); 0 < b;) { if (b & 1 && (c += a), b >>= 1) a += a; @@ -216,7 +216,7 @@ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol });var Za, $a; for ($a = 0; 9 >= $a; $a++) { Za = s.fromCharCode($a + Ga), Ja += Za, Ka[Za] = s.fromCharCode($a + Ea); - }Ka[","] = "";Ka["."] = Ia;Ka[Ia] = Ia;La = q("[" + Ja + ".," + Ia + "]", "g"); + }Ka[","] = "";Ka["\uFF0E"] = Ia;Ka[Ia] = Ia;La = q("[" + Ja + "\uFF0E," + Ia + "]", "g"); "use strict";H(m, !1, !1, { keys: function keys(a) { var b = [];if (!G(a) && !D(a) && !F(a)) throw new TypeError("Object required");I(a, function (a) { b.push(a); @@ -725,9 +725,9 @@ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol return qc(this, b, !1, a); }; }); - "〇一二三四五六七八九十百千万".split("").forEach(function (a, b) { + "\u3007\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D\u5341\u767E\u5343\u4E07".split("").forEach(function (a, b) { 9 < b && (b = za(10, b - 9));Lb[a] = b; - });xa(Lb, Ka);Mb = q("([期週周])?([〇一二三四五六七八九十百千万" + Ja + "]+)(?!昨)", "g"); + });xa(Lb, Ka);Mb = q("([\u671F\u9031\u5468])?([\u3007\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D\u5341\u767E\u5343\u4E07" + Ja + "]+)(?!\u6628)", "g"); /* istanbul ignore next */ (function () { var a = W.weekdays.slice(0, 7), diff --git a/dist/util/colorFile.js b/dist/util/colorFile.js index 2368f96..cb820bd 100755 --- a/dist/util/colorFile.js +++ b/dist/util/colorFile.js @@ -6,7 +6,7 @@ var chalk = {}; var map = { cyan: 36, red: 31, magenta: 35 }; Object.keys(map).forEach(function (key, value) { chalk[key] = function (str) { - return '\u001b[' + value + 'm' + str + '\u001b[39m'; + return '\x1B[' + value + 'm' + str + '\x1B[39m'; }; }); diff --git a/dist/windows.js b/dist/windows.js index a038a11..571bb34 100755 --- a/dist/windows.js +++ b/dist/windows.js @@ -1,6 +1,7 @@ 'use strict'; var os = require('os'); +var execa = require('execa'); var windows = os.platform() === 'win32'; var exclusions = require('./../commands.json').windowsExclusions; @@ -26,31 +27,26 @@ module.exports = { }); }).action(function (args, cb) { cb = cb || function () {}; - var spawn = require('child_process').spawn; var slf = this; var words = args.words.join(' '); var argus = void 0; var cmd = void 0; - // Only register commands if on Windows. - /* istanbul ignore next */ - if (windows) { - var excluded = false; - for (var i = 0; i < exclusions.length; ++i) { - if (String(words.slice(0, exclusions[i].length)).toLowerCase() === exclusions[i].toLowerCase()) { - excluded = true; - cmd = undefined; - argus = undefined; - } + var excluded = false; + for (var i = 0; i < exclusions.length; ++i) { + if (String(words.slice(0, exclusions[i].length)).toLowerCase() === exclusions[i].toLowerCase()) { + excluded = true; + cmd = undefined; + argus = undefined; } + } - if (!excluded) { - var parts = words.split(' '); - cmd = parts.shift(); - argus = parts; - argus = argus.length === 1 && argus[0] === '' ? [] : argus; - } + if (!excluded) { + var parts = words.split(' '); + cmd = parts.shift(); + argus = parts; + argus = argus.length === 1 && argus[0] === '' ? [] : argus; } // Accommodate tests for Linux. @@ -65,12 +61,10 @@ module.exports = { return; } - argus.unshift(cmd); - argus.unshift('/C'); var proc = void 0; var out = ''; try { - proc = spawn('cmd', argus); + proc = execa(cmd, argus); } catch (e) { /* istanbul ignore next */ slf.log(e); @@ -122,7 +116,10 @@ module.exports = { proc.on('close', function () { closed = true; if (String(out).trim() !== '') { - slf.log(String(out).replace(/\r\r/g, '\r')); + // Remove a trailing newline, because log() will add it back: + out = String(out).replace(/\n$/g, ''); + out = String(out).replace(/\r\r/g, '\r'); + slf.log(out); out = ''; } if (windowsHelpFlag) { @@ -135,6 +132,10 @@ module.exports = { }); proc.on('error', function (data) { + if (data.code === 'ENOENT') { + windowsHelpFlag = true; + return; + } out += data.toString('utf8'); }); }); diff --git a/package.json b/package.json index 13209eb..8cc997d 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "dependencies": { "array-shuffle": "^1.0.0", "chalk": "^1.1.0", + "execa": "^1.0.0", "filesize": "^3.1.3", "fkill": "^4.0.0", "fs-extra": "^0.26.7", diff --git a/packages/cp/dist/commands/cp.js b/packages/cp/dist/commands/cp.js index 1a52005..2a23e54 100755 --- a/packages/cp/dist/commands/cp.js +++ b/packages/cp/dist/commands/cp.js @@ -140,10 +140,10 @@ function cpdirSyncRecursive(sourceDir, destDir, options) { fs.symlinkSync(symlinkFull, destFile, os.platform() === 'win32' ? 'junction' : null); // At this point, we've hit a file actually worth copying... so copy it on over. } else if (fs.existsSync(destFile) && options.noclobber) { - // be silent - } else { - copyFileSync.call(self, srcFile, destFile); - } + // be silent + } else { + copyFileSync.call(self, srcFile, destFile); + } } } diff --git a/packages/head/dist/commands/head.js b/packages/head/dist/commands/head.js index 1443c73..aeebe20 100755 --- a/packages/head/dist/commands/head.js +++ b/packages/head/dist/commands/head.js @@ -1,6 +1,6 @@ 'use strict'; -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var interfacer = require('./../util/interfacer'); var fs = require('fs'); diff --git a/packages/ls/dist/commands/ls.js b/packages/ls/dist/commands/ls.js index 544e03f..ffa7f55 100755 --- a/packages/ls/dist/commands/ls.js +++ b/packages/ls/dist/commands/ls.js @@ -1,6 +1,6 @@ 'use strict'; -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var chalk = require('chalk'); var filesize = require('filesize'); diff --git a/packages/ls/dist/util/colorFile.js b/packages/ls/dist/util/colorFile.js index 2368f96..cb820bd 100755 --- a/packages/ls/dist/util/colorFile.js +++ b/packages/ls/dist/util/colorFile.js @@ -6,7 +6,7 @@ var chalk = {}; var map = { cyan: 36, red: 31, magenta: 35 }; Object.keys(map).forEach(function (key, value) { chalk[key] = function (str) { - return '\u001b[' + value + 'm' + str + '\u001b[39m'; + return '\x1B[' + value + 'm' + str + '\x1B[39m'; }; }); diff --git a/packages/rm/dist/commands/rm.js b/packages/rm/dist/commands/rm.js index 602b134..68d21eb 100755 --- a/packages/rm/dist/commands/rm.js +++ b/packages/rm/dist/commands/rm.js @@ -123,12 +123,12 @@ function rmdirSyncRecursive(dir, force, removeEmptyDir) { } /* istanbul ignore next */ } else if (er.code === 'ENOENT') { - // Directory did not exist, deletion was successful - break; - /* istanbul ignore next */ - } else { - throw er; - } + // Directory did not exist, deletion was successful + break; + /* istanbul ignore next */ + } else { + throw er; + } } } } catch (e) { diff --git a/packages/touch/dist/lib/sugar.js b/packages/touch/dist/lib/sugar.js index ffee6c5..620d9e0 100755 --- a/packages/touch/dist/lib/sugar.js +++ b/packages/touch/dist/lib/sugar.js @@ -1,6 +1,6 @@ "use strict"; -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /* * Sugar Library v1.4.1 @@ -146,7 +146,7 @@ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol Ja = "", Ka = {}, La;function Ma() { - return "\t\n\u000b\f\r   ᠎             \u2028\u2029 "; + return "\t\n\x0B\f\r \xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u2028\u2029\u3000\uFEFF"; }function Na(a, b) { var c = "";for (a = a.toString(); 0 < b;) { if (b & 1 && (c += a), b >>= 1) a += a; @@ -216,7 +216,7 @@ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol });var Za, $a; for ($a = 0; 9 >= $a; $a++) { Za = s.fromCharCode($a + Ga), Ja += Za, Ka[Za] = s.fromCharCode($a + Ea); - }Ka[","] = "";Ka["."] = Ia;Ka[Ia] = Ia;La = q("[" + Ja + ".," + Ia + "]", "g"); + }Ka[","] = "";Ka["\uFF0E"] = Ia;Ka[Ia] = Ia;La = q("[" + Ja + "\uFF0E," + Ia + "]", "g"); "use strict";H(m, !1, !1, { keys: function keys(a) { var b = [];if (!G(a) && !D(a) && !F(a)) throw new TypeError("Object required");I(a, function (a) { b.push(a); @@ -725,9 +725,9 @@ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol return qc(this, b, !1, a); }; }); - "〇一二三四五六七八九十百千万".split("").forEach(function (a, b) { + "\u3007\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D\u5341\u767E\u5343\u4E07".split("").forEach(function (a, b) { 9 < b && (b = za(10, b - 9));Lb[a] = b; - });xa(Lb, Ka);Mb = q("([期週周])?([〇一二三四五六七八九十百千万" + Ja + "]+)(?!昨)", "g"); + });xa(Lb, Ka);Mb = q("([\u671F\u9031\u5468])?([\u3007\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D\u5341\u767E\u5343\u4E07" + Ja + "]+)(?!\u6628)", "g"); /* istanbul ignore next */ (function () { var a = W.weekdays.slice(0, 7), diff --git a/src/windows.js b/src/windows.js index 3f36699..50a90c7 100755 --- a/src/windows.js +++ b/src/windows.js @@ -1,6 +1,7 @@ 'use strict'; const os = require('os'); +const execa = require('execa'); const windows = (os.platform() === 'win32'); const exclusions = require('./../commands.json').windowsExclusions; @@ -29,31 +30,26 @@ module.exports = { }) .action(function (args, cb) { cb = cb || function () {}; - const spawn = require('child_process').spawn; const slf = this; const words = args.words.join(' '); let argus; let cmd; - // Only register commands if on Windows. - /* istanbul ignore next */ - if (windows) { - let excluded = false; - for (let i = 0; i < exclusions.length; ++i) { - if (String(words.slice(0, exclusions[i].length)).toLowerCase() === exclusions[i].toLowerCase()) { - excluded = true; - cmd = undefined; - argus = undefined; - } + let excluded = false; + for (let i = 0; i < exclusions.length; ++i) { + if (String(words.slice(0, exclusions[i].length)).toLowerCase() === exclusions[i].toLowerCase()) { + excluded = true; + cmd = undefined; + argus = undefined; } + } - if (!excluded) { - const parts = words.split(' '); - cmd = parts.shift(); - argus = parts; - argus = (argus.length === 1 && argus[0] === '') ? [] : argus; - } + if (!excluded) { + const parts = words.split(' '); + cmd = parts.shift(); + argus = parts; + argus = (argus.length === 1 && argus[0] === '') ? [] : argus; } // Accommodate tests for Linux. @@ -68,12 +64,10 @@ module.exports = { return; } - argus.unshift(cmd); - argus.unshift('/C'); let proc; let out = ''; try { - proc = spawn('cmd', argus); + proc = execa(cmd, argus); } catch (e) { /* istanbul ignore next */ slf.log(e); @@ -125,7 +119,10 @@ module.exports = { proc.on('close', function () { closed = true; if (String(out).trim() !== '') { - slf.log(String(out).replace(/\r\r/g, '\r')); + // Remove a trailing newline, because log() will add it back: + out = String(out).replace(/\n$/g, ''); + out = String(out).replace(/\r\r/g, '\r'); + slf.log(out); out = ''; } if (windowsHelpFlag) { @@ -138,6 +135,10 @@ module.exports = { }); proc.on('error', function (data) { + if (data.code === 'ENOENT') { + windowsHelpFlag = true; + return; + } out += data.toString('utf8'); }); });