Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Handle error when running init without npm #9169

Merged
merged 1 commit into from Aug 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion lib/config/config-initializer.js
Expand Up @@ -65,6 +65,7 @@ function writeFile(config, format) {
* @param {string} moduleName The module name to get.
* @returns {Object} The peer dependencies of the given module.
* This object is the object of `peerDependencies` field of `package.json`.
* Returns null if npm was not found.
*/
function getPeerDependencies(moduleName) {
let result = getPeerDependencies.cache.get(moduleName);
Expand Down Expand Up @@ -356,7 +357,8 @@ function hasESLintVersionConflict(answers) {
// Get the required range of ESLint version.
const configName = getStyleGuideName(answers);
const moduleName = `eslint-config-${configName}@latest`;
const requiredESLintVersionRange = getPeerDependencies(moduleName).eslint;
const peerDependencies = getPeerDependencies(moduleName) || {};
const requiredESLintVersionRange = peerDependencies.eslint;

if (!requiredESLintVersionRange) {
return false;
Expand Down
25 changes: 21 additions & 4 deletions lib/util/npm-util.js
Expand Up @@ -53,22 +53,39 @@ function installSyncSaveDev(packages) {
if (!Array.isArray(packages)) {
packages = [packages];
}
spawn.sync("npm", ["i", "--save-dev"].concat(packages), { stdio: "inherit" });
const npmProcess = spawn.sync("npm", ["i", "--save-dev"].concat(packages),
{ stdio: "inherit" });
const error = npmProcess.error;

if (error && error.code === "ENOENT") {
const pluralS = packages.length > 1 ? "s" : "";

log.error(`Could not execute npm. Please install the following package${pluralS} with your package manager of choice: ${packages.join(", ")}`);
}
}

/**
* Fetch `peerDependencies` of the given package by `npm show` command.
* @param {string} packageName The package name to fetch peerDependencies.
* @returns {Object} Gotten peerDependencies.
* @returns {Object} Gotten peerDependencies. Returns null if npm was not found.
*/
function fetchPeerDependencies(packageName) {
const fetchedText = spawn.sync(
const npmProcess = spawn.sync(
"npm",
["show", "--json", packageName, "peerDependencies"],
{ encoding: "utf8" }
).stdout.trim();
);

const error = npmProcess.error;

if (error && error.code === "ENOENT") {
return null;
}
const fetchedText = npmProcess.stdout.trim();

return JSON.parse(fetchedText || "{}");


}

/**
Expand Down
26 changes: 24 additions & 2 deletions tests/lib/util/npm-util.js
Expand Up @@ -170,7 +170,7 @@ describe("npmUtil", () => {

describe("installSyncSaveDev()", () => {
it("should invoke npm to install a single desired package", () => {
const stub = sandbox.stub(spawn, "sync");
const stub = sandbox.stub(spawn, "sync").returns({ stdout: "" });

npmUtil.installSyncSaveDev("desired-package");
assert(stub.calledOnce);
Expand All @@ -180,14 +180,26 @@ describe("npmUtil", () => {
});

it("should accept an array of packages to install", () => {
const stub = sandbox.stub(spawn, "sync");
const stub = sandbox.stub(spawn, "sync").returns({ stdout: "" });

npmUtil.installSyncSaveDev(["first-package", "second-package"]);
assert(stub.calledOnce);
assert.equal(stub.firstCall.args[0], "npm");
assert.deepEqual(stub.firstCall.args[1], ["i", "--save-dev", "first-package", "second-package"]);
stub.restore();
});

it("should log an error message if npm throws ENOENT error", () => {
const logErrorStub = sandbox.stub(log, "error");
const npmUtilStub = sandbox.stub(spawn, "sync").returns({ error: { code: "ENOENT" } });

npmUtil.installSyncSaveDev("some-package");

assert(logErrorStub.calledOnce);

logErrorStub.restore();
npmUtilStub.restore();
});
});

describe("fetchPeerDependencies()", () => {
Expand All @@ -200,5 +212,15 @@ describe("npmUtil", () => {
assert.deepEqual(stub.firstCall.args[1], ["show", "--json", "desired-package", "peerDependencies"]);
stub.restore();
});

it("should return null if npm throws ENOENT error", () => {
const stub = sandbox.stub(spawn, "sync").returns({ error: { code: "ENOENT" } });

const peerDependencies = npmUtil.fetchPeerDependencies("desired-package");

assert.isNull(peerDependencies);

stub.restore();
});
});
});