/src/windows.js

https://github.com/dthree/cash · JavaScript · 145 lines · 109 code · 17 blank · 19 comment · 17 complexity · dc3d23bc99e3fb959145dfe11a46efde MD5 · raw file

  1. 'use strict';
  2. const os = require('os');
  3. const windows = (os.platform() === 'win32');
  4. const exclusions = require('./../commands.json').windowsExclusions;
  5. module.exports = {
  6. registerCommands(self) {
  7. self.vorpal
  8. .catch('[words...]', 'Catches content')
  9. .parse(function (input) {
  10. // Look for aliases and translate them.
  11. // Makes cash.alias and cash.unalias work.
  12. const parts = String(input).split(' ');
  13. const first = parts.shift();
  14. let out = input;
  15. const translation = self.vorpal._aliases[first];
  16. if (self.vorpal._aliases && translation) {
  17. /* istanbul ignore next */
  18. out = `${translation} ${parts.join(' ')}`;
  19. }
  20. return out;
  21. })
  22. .autocomplete(function () {
  23. /* istanbul ignore next */
  24. return self.vorpal.commands.map(c => c._name);
  25. })
  26. .action(function (args, cb) {
  27. cb = cb || function () {};
  28. const spawn = require('child_process').spawn;
  29. const slf = this;
  30. const words = args.words.join(' ');
  31. let argus;
  32. let cmd;
  33. // Only register commands if on Windows.
  34. /* istanbul ignore next */
  35. if (windows) {
  36. let excluded = false;
  37. for (let i = 0; i < exclusions.length; ++i) {
  38. if (String(words.slice(0, exclusions[i].length)).toLowerCase() === exclusions[i].toLowerCase()) {
  39. excluded = true;
  40. cmd = undefined;
  41. argus = undefined;
  42. }
  43. }
  44. if (!excluded) {
  45. const parts = words.split(' ');
  46. cmd = parts.shift();
  47. argus = parts;
  48. argus = (argus.length === 1 && argus[0] === '') ? [] : argus;
  49. }
  50. }
  51. // Accommodate tests for Linux.
  52. if (words === 'cash-test') {
  53. cmd = 'echo';
  54. argus = ['hi'];
  55. }
  56. if (cmd === undefined || argus === undefined) {
  57. slf.help();
  58. cb();
  59. return;
  60. }
  61. argus.unshift(cmd);
  62. argus.unshift('/C');
  63. let proc;
  64. let out = '';
  65. try {
  66. proc = spawn('cmd', argus);
  67. } catch (e) {
  68. /* istanbul ignore next */
  69. slf.log(e);
  70. }
  71. let closed = false;
  72. // Properly print stdout as it's fed,
  73. // waiting for line breaks before sending
  74. // it to Vorpal.
  75. function print() {
  76. const parts = String(out).split('\n');
  77. /* istanbul ignore next */
  78. if (parts.length > 1) {
  79. out = parts.pop();
  80. const logging = String(parts.join('\n')).replace(/\r\r/g, '\r');
  81. slf.log(logging);
  82. }
  83. /* istanbul ignore next */
  84. if (closed === false) {
  85. setTimeout(function () {
  86. print();
  87. }, 50);
  88. }
  89. }
  90. print();
  91. // See if we get a Windows help on an
  92. // invalid command and instead throw
  93. // Cash help.
  94. let windowsHelpFlag = false;
  95. const windowsCommandReject = 'is not recognized as an internal or external command';
  96. /* istanbul ignore next */
  97. proc.stdout.on('data', function (data) {
  98. out += data.toString('utf8');
  99. });
  100. /* istanbul ignore next */
  101. proc.stderr.on('data', function (data) {
  102. const str = data.toString('utf8');
  103. if (windows && str.indexOf(windowsCommandReject) > -1) {
  104. windowsHelpFlag = true;
  105. return;
  106. }
  107. out += str;
  108. });
  109. proc.on('close', function () {
  110. closed = true;
  111. if (String(out).trim() !== '') {
  112. slf.log(String(out).replace(/\r\r/g, '\r'));
  113. out = '';
  114. }
  115. if (windowsHelpFlag) {
  116. slf.help();
  117. }
  118. /* istanbul ignore next */
  119. setTimeout(function () {
  120. cb();
  121. }, 150);
  122. });
  123. proc.on('error', function (data) {
  124. out += data.toString('utf8');
  125. });
  126. });
  127. }
  128. };