Skip to content

Commit

Permalink
fix(cli): Ensure exit code is always numeric
Browse files Browse the repository at this point in the history
  • Loading branch information
evocateur committed Jan 22, 2019
1 parent d0ff473 commit a2362b8
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 1 deletion.
21 changes: 21 additions & 0 deletions core/cli/__tests__/core-cli.test.js
Expand Up @@ -159,6 +159,27 @@ describe("core-cli", () => {
);
});

it("coerces string exit codes to 1", async () => {
const cli = prepare(cwd);
const spy = jest.spyOn(cli, "exit");

cli.command("errname", "a string code", {}, async () => {
const err = new Error("npm-registry-fetch");
err.code = "E401";
throw err;
});

// paradoxically, this does NOT reject...
await parse(cli, ["errname"]);

expect(spy).toHaveBeenLastCalledWith(
1,
expect.objectContaining({
message: "npm-registry-fetch",
})
);
});

it("preserves exotic exit codes", async () => {
const cli = prepare(cwd);
const spy = jest.spyOn(cli, "exit");
Expand Down
2 changes: 1 addition & 1 deletion core/cli/index.js
Expand Up @@ -37,7 +37,7 @@ function lernaCLI(argv, cwd) {
}

// exit non-zero so the CLI can be usefully chained
cli.exit(actual.code || 1, actual);
cli.exit(actual.code > 0 ? actual.code : 1, actual);

This comment has been minimized.

Copy link
@andysmith415

andysmith415 Jan 29, 2019

@evocateur, if the exit code is "0", this will still return 1, this needs to be a >= comparison:

cli.exit(actual.code >= 0 ? actual.code : 1, actual);

This comment has been minimized.

Copy link
@evocateur

evocateur Jan 29, 2019

Author Member

This code is in the .fail() handler, so I'm pretty confident we don't want "0" to match. Thanks for reviewing it, though!

This comparison is mostly a "cheap" way to test, even if the value is a string, that it resolves to a number (1, by unix convention). Many libnpm utilities will throw errors that have a code property that could be "EOTP" or "ENOENT", etc, and execa uses the code property to actually pass the exit code (which in a failure case will always be greater than 0).

Whenever lerna exits successfully, it never mutates process.exitCode (or call process.exit(), for that matter), so the exit code is always 0. Unless it intentionally exits non-zero, like certain cases for lerna changed to better enable it to be used in a shell oneliner (e.g., lerna changed && lerna publish || echo "nothing to publish" in an npm script run during CI).

})
.alias("h", "help")
.alias("v", "version")
Expand Down

0 comments on commit a2362b8

Please sign in to comment.