prompt-command.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. // based on https://github.com/webpack/webpack/blob/master/bin/webpack.js
  2. /**
  3. * @param {string} command process to run
  4. * @param {string[]} args commandline arguments
  5. * @returns {Promise<void>} promise
  6. */
  7. const runCommand = (command, args) => {
  8. const cp = require("child_process");
  9. return new Promise((resolve, reject) => {
  10. resolve();
  11. const executedCommand = cp.spawn(command, args, {
  12. stdio: "inherit",
  13. shell: true
  14. });
  15. executedCommand.on("error", error => {
  16. reject(error);
  17. });
  18. executedCommand.on("exit", code => {
  19. if (code === 0) {
  20. resolve();
  21. } else {
  22. reject();
  23. }
  24. });
  25. });
  26. };
  27. module.exports = function promptForInstallation(packages, ...args) {
  28. const nameOfPackage = "@webpack-cli/" + packages;
  29. let packageIsInstalled = false;
  30. let pathForCmd;
  31. try {
  32. const path = require("path");
  33. pathForCmd = path.resolve(
  34. process.cwd(),
  35. "node_modules",
  36. "@webpack-cli",
  37. packages
  38. );
  39. require.resolve(pathForCmd);
  40. packageIsInstalled = true;
  41. } catch (err) {
  42. packageIsInstalled = false;
  43. }
  44. if (!packageIsInstalled) {
  45. const path = require("path");
  46. const fs = require("fs");
  47. const readLine = require("readline");
  48. const isYarn = fs.existsSync(path.resolve(process.cwd(), "yarn.lock"));
  49. const packageManager = isYarn ? "yarn" : "npm";
  50. const options = ["install", "-D", nameOfPackage];
  51. if (isYarn) {
  52. options[0] = "add";
  53. }
  54. const commandToBeRun = `${packageManager} ${options.join(" ")}`;
  55. const question = `Would you like to install ${packages}? (That will run ${commandToBeRun}) (yes/NO)`;
  56. console.error(
  57. `The command moved into a separate package: ${nameOfPackage}`
  58. );
  59. const questionInterface = readLine.createInterface({
  60. input: process.stdin,
  61. output: process.stdout
  62. });
  63. questionInterface.question(question, answer => {
  64. questionInterface.close();
  65. switch (answer.toLowerCase()) {
  66. case "y":
  67. case "yes":
  68. case "1": {
  69. //eslint-disable-next-line
  70. runCommand(packageManager, options)
  71. .then(result => {
  72. pathForCmd = path.resolve(
  73. process.cwd(),
  74. "node_modules",
  75. "@webpack-cli",
  76. packages
  77. );
  78. if (packages === "serve") {
  79. return require(pathForCmd).default.serve();
  80. }
  81. return require(pathForCmd).default(...args); //eslint-disable-line
  82. })
  83. .catch(error => {
  84. console.error(error);
  85. process.exitCode = 1;
  86. });
  87. break;
  88. }
  89. default: {
  90. console.error(
  91. `${nameOfPackage} needs to be installed in order to run the command.`
  92. );
  93. process.exitCode = 1;
  94. break;
  95. }
  96. }
  97. });
  98. } else {
  99. require(pathForCmd).default(...args); // eslint-disable-line
  100. }
  101. };