From 17d1f3dd41ef6127228d427fd5cca373d6c97f0f Mon Sep 17 00:00:00 2001 From: Kristoffer K Date: Wed, 24 May 2023 00:31:58 +0200 Subject: [PATCH] fix: don't override `process.exitCode` (#268) * fix: don't override exit codes * chore: update nock files --- sources/main.ts | 22 +++----- tests/main.test.ts | 68 ++++++++++++++++++++++++ tests/nock/4ppY93mauKPrkN4oe1GUkA-1.dat | Bin 0 -> 7 bytes tests/nock/WaR3LFsnTKCCsgSkSI54NA-1.dat | Bin 0 -> 7 bytes tests/nock/bc9X9LCamX_BSH1eZYT1Zg-1.dat | Bin 0 -> 7 bytes 5 files changed, 75 insertions(+), 15 deletions(-) create mode 100644 tests/nock/4ppY93mauKPrkN4oe1GUkA-1.dat create mode 100644 tests/nock/WaR3LFsnTKCCsgSkSI54NA-1.dat create mode 100644 tests/nock/bc9X9LCamX_BSH1eZYT1Zg-1.dat diff --git a/sources/main.ts b/sources/main.ts index e1262682f..21f0804ad 100644 --- a/sources/main.ts +++ b/sources/main.ts @@ -88,7 +88,7 @@ async function executePackageManagerRequest({packageManager, binaryName, binaryV return await corepackUtils.runVersion(installSpec, binaryName, args); } -async function main(argv: Array) { +export async function runMain(argv: Array) { // Because we load the binaries in the same process, we don't support custom contexts. const context = { ...Cli.defaultContext, @@ -99,10 +99,9 @@ async function main(argv: Array) { const [firstArg, ...restArgs] = argv; const request = getPackageManagerRequestFromCli(firstArg, context); - let cli: Cli; if (!request) { // If the first argument doesn't match any supported package manager, we fallback to the standard Corepack CLI - cli = new Cli({ + const cli = new Cli({ binaryLabel: `Corepack`, binaryName: `corepack`, binaryVersion: corepackVersion, @@ -116,7 +115,7 @@ async function main(argv: Array) { cli.register(HydrateCommand); cli.register(PrepareCommand); - return await cli.run(argv, context); + await cli.runExit(argv, context); } else { // Otherwise, we create a single-command CLI to run the specified package manager (we still use Clipanion in order to pretty-print usage errors). const cli = new Cli({ @@ -132,16 +131,9 @@ async function main(argv: Array) { } }); - return await cli.run(restArgs, context); + const code = await cli.run(restArgs, context); + if (code !== 0) { + process.exitCode ??= code; + } } } - -// Important: this is the only function that the corepack binary exports. -export function runMain(argv: Array) { - main(argv).then(exitCode => { - process.exitCode = exitCode; - }, err => { - console.error(err.stack); - process.exitCode = 1; - }); -} diff --git a/tests/main.test.ts b/tests/main.test.ts index bc8eff767..94a5c39c4 100644 --- a/tests/main.test.ts +++ b/tests/main.test.ts @@ -538,3 +538,71 @@ it(`should handle parallel installs`, async () => { ]); }); }); + +it(`should not override the package manager exit code`, async () => { + await xfs.mktempPromise(async cwd => { + await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), { + packageManager: `yarn@2.2.2`, + }); + + const yarnPath = ppath.join(npath.toPortablePath(process.env.COREPACK_HOME!), `yarn/2.2.2/yarn.js` as PortablePath); + + await xfs.mkdirPromise(ppath.dirname(yarnPath), {recursive: true}); + await xfs.writeFilePromise(yarnPath, ` + process.exitCode = 42; + `); + + await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({ + exitCode: 42, + stdout: ``, + stderr: ``, + }); + }); +}); + +it(`should not override the package manager exit code when it throws`, async () => { + await xfs.mktempPromise(async cwd => { + await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), { + packageManager: `yarn@2.2.2`, + }); + + const yarnPath = ppath.join(npath.toPortablePath(process.env.COREPACK_HOME!), `yarn/2.2.2/yarn.js` as PortablePath); + + await xfs.mkdirPromise(ppath.dirname(yarnPath), {recursive: true}); + await xfs.writeFilePromise(yarnPath, ` + process.exitCode = 42; + throw new Error('foo'); + `); + + await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({ + exitCode: 42, + stdout: expect.stringContaining(`foo`), + stderr: ``, + }); + }); +}); + +it(`should not set the exit code after successfully launching the package manager`, async () => { + await xfs.mktempPromise(async cwd => { + await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), { + packageManager: `yarn@2.2.2`, + }); + + const yarnPath = ppath.join(npath.toPortablePath(process.env.COREPACK_HOME!), `yarn/2.2.2/yarn.js` as PortablePath); + + await xfs.mkdirPromise(ppath.dirname(yarnPath), {recursive: true}); + await xfs.writeFilePromise(yarnPath, ` + process.once('beforeExit', () => { + if (process.exitCode === undefined) { + process.exitCode = 42; + } + }); + `); + + await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({ + exitCode: 42, + stdout: ``, + stderr: ``, + }); + }); +}); diff --git a/tests/nock/4ppY93mauKPrkN4oe1GUkA-1.dat b/tests/nock/4ppY93mauKPrkN4oe1GUkA-1.dat new file mode 100644 index 0000000000000000000000000000000000000000..5403d9e583dc034b149e979da4843ed8d221269f GIT binary patch literal 7 Ocmey*>&T$OzyJUU{{eCU literal 0 HcmV?d00001 diff --git a/tests/nock/WaR3LFsnTKCCsgSkSI54NA-1.dat b/tests/nock/WaR3LFsnTKCCsgSkSI54NA-1.dat new file mode 100644 index 0000000000000000000000000000000000000000..5403d9e583dc034b149e979da4843ed8d221269f GIT binary patch literal 7 Ocmey*>&T$OzyJUU{{eCU literal 0 HcmV?d00001 diff --git a/tests/nock/bc9X9LCamX_BSH1eZYT1Zg-1.dat b/tests/nock/bc9X9LCamX_BSH1eZYT1Zg-1.dat new file mode 100644 index 0000000000000000000000000000000000000000..5403d9e583dc034b149e979da4843ed8d221269f GIT binary patch literal 7 Ocmey*>&T$OzyJUU{{eCU literal 0 HcmV?d00001