diff --git a/.changeset/lucky-eyes-double.md b/.changeset/lucky-eyes-double.md new file mode 100644 index 00000000000..f4cd725d7a9 --- /dev/null +++ b/.changeset/lucky-eyes-double.md @@ -0,0 +1,6 @@ +--- +"@pnpm/default-reporter": patch +"pnpm": patch +--- + +The reporter should not crash when the CLI process is kill during lifecycle scripts execution [#5588](https://github.com/pnpm/pnpm/pull/5588). diff --git a/.changeset/moody-weeks-reply.md b/.changeset/moody-weeks-reply.md new file mode 100644 index 00000000000..aa14012811c --- /dev/null +++ b/.changeset/moody-weeks-reply.md @@ -0,0 +1,5 @@ +--- +"@pnpm/lifecycle": patch +--- + +Never log a lifecycle exit debug log without an exit code [#5588](https://github.com/pnpm/pnpm/pull/5588). diff --git a/packages/default-reporter/src/reporterForClient/reportLifecycleScripts.ts b/packages/default-reporter/src/reporterForClient/reportLifecycleScripts.ts index f7722e6d882..60396a39d04 100644 --- a/packages/default-reporter/src/reporterForClient/reportLifecycleScripts.ts +++ b/packages/default-reporter/src/reporterForClient/reportLifecycleScripts.ts @@ -266,6 +266,7 @@ function formatLine (maxWidth: number, logObj: LifecycleLog) { } function cutLine (line: string, maxLength: number) { + if (!line) return '' // This actually should never happen but it is better to be safe return stripAnsi(line).slice(0, maxLength) } diff --git a/packages/default-reporter/test/reportingLifecycleScripts.ts b/packages/default-reporter/test/reportingLifecycleScripts.ts index dbb9522a74d..92c9bc7ad8d 100644 --- a/packages/default-reporter/test/reportingLifecycleScripts.ts +++ b/packages/default-reporter/test/reportingLifecycleScripts.ts @@ -739,6 +739,52 @@ ${STATUS_INDENTATION} ${STATUS_FAILED}`) }) }) +test('do not fail if the debug log has no output', (done) => { + const output$ = toOutput$({ + context: { argv: ['install'] }, + reportingOptions: { outputMaxWidth: 79 }, + streamParser: createStreamParser(), + }) + + const wd = path.resolve(process.cwd(), 'node_modules', '.registry.npmjs.org', 'foo', '1.0.0', 'node_modules', 'foo') + + lifecycleLogger.debug({ + depPath: 'registry.npmjs.org/foo/1.0.0', + optional: false, + script: 'node foo', + stage: 'install', + wd, + }) + lifecycleLogger.debug({ + depPath: 'registry.npmjs.org/foo/1.0.0', + line: undefined as any, // eslint-disable-line @typescript-eslint/no-explicit-any + stage: 'install', + stdio: 'stdout', + wd, + }) + lifecycleLogger.debug({ + depPath: 'registry.npmjs.org/foo/1.0.0', + exitCode: 1, + optional: false, + stage: 'install', + wd, + }) + + expect.assertions(1) + + output$.pipe(skip(1), take(1), map(normalizeNewline)).subscribe({ + complete: () => done(), + error: done, + next: (output: string) => { + expect(replaceTimeWith1Sec(output)).toBe(`\ +${chalk.gray('node_modules/.registry.npmjs.org/foo/1.0.0/node_modules/')}foo: Running install script, failed in 1s +.../foo/1.0.0/node_modules/foo ${INSTALL}$ node foo +${OUTPUT_INDENTATION} +${STATUS_INDENTATION} ${STATUS_FAILED}`) + }, + }) +}) + // Many libs use stderr for logging, so showing all stderr adds not much value test['skip']('prints lifecycle progress', (done) => { const output$ = toOutput$({ diff --git a/packages/lifecycle/src/runLifecycleHook.ts b/packages/lifecycle/src/runLifecycleHook.ts index f44cfd64900..cde86cee426 100644 --- a/packages/lifecycle/src/runLifecycleHook.ts +++ b/packages/lifecycle/src/runLifecycleHook.ts @@ -100,7 +100,7 @@ export async function runLifecycleHook ( // Preventing the pnpm reporter from overriding the project's script output return } - const code = arguments[3] + const code = arguments[3] ?? 1 lifecycleLogger.debug({ depPath: opts.depPath, exitCode: code,