|
|
- // based on https://github.com/webpack/webpack/blob/master/bin/webpack.js
-
- /**
- * @param {string} command process to run
- * @param {string[]} args commandline arguments
- * @returns {Promise<void>} promise
- */
- const runCommand = (command, args) => {
- const cp = require("child_process");
- return new Promise((resolve, reject) => {
- const executedCommand = cp.spawn(command, args, {
- stdio: "inherit",
- shell: true
- });
-
- executedCommand.on("error", error => {
- reject(error);
- });
-
- executedCommand.on("exit", code => {
- if (code === 0) {
- resolve();
- } else {
- reject();
- }
- });
- });
- };
-
- const npmGlobalRoot = () => {
- const cp = require("child_process");
- return new Promise((resolve, reject) => {
- const command = cp.spawn("npm", ["root", "-g"]);
- command.on("error", error => reject(error));
- command.stdout.on("data", data => resolve(data.toString()));
- command.stderr.on("data", data => reject(data));
- });
- };
-
- const runWhenInstalled = (packages, pathForCmd, ...args) => {
- const currentPackage = require(pathForCmd);
- const func = currentPackage.default;
- if (typeof func !== "function") {
- throw new Error(`@webpack-cli/${packages} failed to export a default function`);
- }
- return func(...args);
- };
-
- module.exports = function promptForInstallation(packages, ...args) {
- const nameOfPackage = "@webpack-cli/" + packages;
- let packageIsInstalled = false;
- let pathForCmd;
- try {
- const path = require("path");
- const fs = require("fs");
- pathForCmd = path.resolve(process.cwd(), "node_modules", "@webpack-cli", packages);
- if (!fs.existsSync(pathForCmd)) {
- const globalModules = require("global-modules");
- pathForCmd = globalModules + "/@webpack-cli/" + packages;
- require.resolve(pathForCmd);
- } else {
- require.resolve(pathForCmd);
- }
- packageIsInstalled = true;
- } catch (err) {
- packageIsInstalled = false;
- }
- if (!packageIsInstalled) {
- const path = require("path");
- const fs = require("fs");
- const readLine = require("readline");
- const isYarn = fs.existsSync(path.resolve(process.cwd(), "yarn.lock"));
-
- const packageManager = isYarn ? "yarn" : "npm";
- const options = ["install", "-D", nameOfPackage];
-
- if (isYarn) {
- options[0] = "add";
- }
-
- if (packages === "init") {
- if (isYarn) {
- options.splice(1, 1); // remove '-D'
- options.splice(0, 0, "global");
- } else {
- options[1] = "-g";
- }
- }
-
- const commandToBeRun = `${packageManager} ${options.join(" ")}`;
-
- const question = `Would you like to install ${packages}? (That will run ${commandToBeRun}) (yes/NO) : `;
-
- console.error(`The command moved into a separate package: ${nameOfPackage}`);
- const questionInterface = readLine.createInterface({
- input: process.stdin,
- output: process.stdout
- });
- questionInterface.question(question, answer => {
- questionInterface.close();
- switch (answer.toLowerCase()) {
- case "y":
- case "yes":
- case "1": {
- runCommand(packageManager, options)
- .then(_ => {
- if (packages === "init") {
- npmGlobalRoot()
- .then(root => {
- const pathtoInit = path.resolve(root.trim(), "@webpack-cli", "init");
- return pathtoInit;
- })
- .then(pathForInit => {
- return require(pathForInit).default(...args);
- })
- .catch(error => {
- console.error(error);
- process.exitCode = 1;
- });
- return;
- }
-
- pathForCmd = path.resolve(process.cwd(), "node_modules", "@webpack-cli", packages);
- return runWhenInstalled(packages, pathForCmd, ...args);
- })
- .catch(error => {
- console.error(error);
- process.exitCode = 1;
- });
- break;
- }
- default: {
- console.error(`${nameOfPackage} needs to be installed in order to run the command.`);
- process.exitCode = 1;
- break;
- }
- }
- });
- } else {
- return runWhenInstalled(packages, pathForCmd, ...args);
- }
- };
|