diff --git a/.changeset/green-olives-visit.md b/.changeset/green-olives-visit.md new file mode 100644 index 0000000000..c73f6edcce --- /dev/null +++ b/.changeset/green-olives-visit.md @@ -0,0 +1,5 @@ +--- +"@pnpm/default-reporter": minor +--- + +Color the different output prefixes differently. diff --git a/packages/default-reporter/src/reporterForClient/reportLifecycleScripts.ts b/packages/default-reporter/src/reporterForClient/reportLifecycleScripts.ts index 019eec67aa..db21f4dc64 100644 --- a/packages/default-reporter/src/reporterForClient/reportLifecycleScripts.ts +++ b/packages/default-reporter/src/reporterForClient/reportLifecycleScripts.ts @@ -13,6 +13,15 @@ import formatPrefix, { formatPrefixNoTrim } from './utils/formatPrefix' const NODE_MODULES = `${path.sep}node_modules${path.sep}` +// When streaming processes are spawned, use this color for prefix +const colorWheel = ['cyan', 'magenta', 'blue', 'yellow', 'green', 'red'] +const NUM_COLORS = colorWheel.length + +// Ever-increasing index ensures colors are always sequential +let currentColor = 0 + +type ColorByPkg = Map string> + export default ( log$: { lifecycle: most.Stream, @@ -26,8 +35,11 @@ export default ( // When the reporter is not append-only, the length of output is limited // in order to reduce flickering if (opts.appendOnly) { + const streamLifecycleOutput = createStreamLifecycleOutput(opts.cwd) return log$.lifecycle - .map((log: LifecycleLog) => most.of({ msg: formatLifecycleHideOverflowForAppendOnly(opts.cwd, log) })) + .map((log: LifecycleLog) => most.of({ + msg: streamLifecycleOutput(log), + })) } const lifecycleMessages: { [depPath: string]: { @@ -161,7 +173,7 @@ function updateMessageCache ( } ) { if (log['script']) { - const prefix = formatLifecycleScriptPrefix(opts.cwd, log.wd, log.stage) + const prefix = `${formatPrefix(opts.cwd, log.wd)} ${hlValue(log.stage)}` const maxLineWidth = opts.maxWidth - prefix.length - 2 + ANSI_ESCAPES_LENGTH_OF_PREFIX messageCache.script = `${prefix}$ ${cutLine(log['script'], maxLineWidth)}` } else if (opts.exit) { @@ -187,11 +199,18 @@ function highlightLastFolder (p: string) { const ANSI_ESCAPES_LENGTH_OF_PREFIX = hlValue(' ').length - 1 -function formatLifecycleHideOverflowForAppendOnly ( +function createStreamLifecycleOutput (cwd: string) { + currentColor = 0 + const colorByPrefix: ColorByPkg = new Map() + return streamLifecycleOutput.bind(null, colorByPrefix, cwd) +} + +function streamLifecycleOutput ( + colorByPkg: ColorByPkg, cwd: string, logObj: LifecycleLog ) { - const prefix = formatLifecycleScriptPrefix(cwd, logObj.wd, logObj.stage) + const prefix = formatLifecycleScriptPrefix(colorByPkg, cwd, logObj.wd, logObj.stage) if (typeof logObj['exitCode'] === 'number') { if (logObj['exitCode'] === 0) { return `${prefix}: Done` @@ -210,8 +229,20 @@ function formatIndentedOutput (maxWidth: number, logObj: LifecycleLog) { return `${chalk.magentaBright('│')} ${formatLine(maxWidth - 2, logObj)}` } -function formatLifecycleScriptPrefix (cwd: string, wd: string, stage: string) { - return `${formatPrefix(cwd, wd)} ${hlValue(stage)}` +function formatLifecycleScriptPrefix ( + colorByPkg: ColorByPkg, + cwd: string, + wd: string, + stage: string +) { + if (!colorByPkg.has(wd)) { + const colorName = colorWheel[currentColor % NUM_COLORS] + colorByPkg.set(wd, chalk[colorName]) + currentColor += 1 + } + + const color = colorByPkg.get(wd)! + return `${color(formatPrefix(cwd, wd))} ${hlValue(stage)}` } function formatLine (maxWidth: number, logObj: LifecycleLog) { diff --git a/packages/default-reporter/test/reportingLifecycleScripts.ts b/packages/default-reporter/test/reportingLifecycleScripts.ts index 2a46093ce6..6f03a75952 100644 --- a/packages/default-reporter/test/reportingLifecycleScripts.ts +++ b/packages/default-reporter/test/reportingLifecycleScripts.ts @@ -240,17 +240,17 @@ test('groups lifecycle output when append-only is used', t => { output$.take(11).map(normalizeNewline).subscribe({ complete: () => { t.equal(allOutputs.join(EOL), stripIndents` - packages/foo ${PREINSTALL}$ node foo - packages/foo ${PREINSTALL}: foo 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 - packages/foo ${PREINSTALL}: Failed - packages/foo ${POSTINSTALL}$ node foo - packages/foo ${POSTINSTALL}: foo I - packages/bar ${POSTINSTALL}$ node bar - packages/bar ${POSTINSTALL}: bar I - packages/foo ${POSTINSTALL}: foo II - packages/foo ${POSTINSTALL}: foo III - packages/qar ${INSTALL}$ node qar - packages/qar ${INSTALL}: Done + ${chalk.cyan('packages/foo')} ${PREINSTALL}$ node foo + ${chalk.cyan('packages/foo')} ${PREINSTALL}: foo 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 + ${chalk.cyan('packages/foo')} ${PREINSTALL}: Failed + ${chalk.cyan('packages/foo')} ${POSTINSTALL}$ node foo + ${chalk.cyan('packages/foo')} ${POSTINSTALL}: foo I + ${chalk.magenta('packages/bar')} ${POSTINSTALL}$ node bar + ${chalk.magenta('packages/bar')} ${POSTINSTALL}: bar I + ${chalk.cyan('packages/foo')} ${POSTINSTALL}: foo II + ${chalk.cyan('packages/foo')} ${POSTINSTALL}: foo III + ${chalk.blue('packages/qar')} ${INSTALL}$ node qar + ${chalk.blue('packages/qar')} ${INSTALL}: Done `) t.end() }, @@ -361,18 +361,18 @@ test('groups lifecycle output when streamLifecycleOutput is used', t => { error: t.end, next: (output: string) => { t.equal(output, stripIndents` - packages/foo ${PREINSTALL}$ node foo - packages/foo ${PREINSTALL}: foo 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 - packages/foo ${PREINSTALL}: Failed - packages/foo ${POSTINSTALL}$ node foo - packages/foo ${POSTINSTALL}: foo I - packages/bar ${POSTINSTALL}$ node bar - packages/bar ${POSTINSTALL}: bar I - packages/foo ${POSTINSTALL}: foo II - packages/foo ${POSTINSTALL}: foo III - packages/qar ${INSTALL}$ node qar - packages/qar ${INSTALL}: Done - packages/foo ${POSTINSTALL}: Done + ${chalk.cyan('packages/foo')} ${PREINSTALL}$ node foo + ${chalk.cyan('packages/foo')} ${PREINSTALL}: foo 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 + ${chalk.cyan('packages/foo')} ${PREINSTALL}: Failed + ${chalk.cyan('packages/foo')} ${POSTINSTALL}$ node foo + ${chalk.cyan('packages/foo')} ${POSTINSTALL}: foo I + ${chalk.magenta('packages/bar')} ${POSTINSTALL}$ node bar + ${chalk.magenta('packages/bar')} ${POSTINSTALL}: bar I + ${chalk.cyan('packages/foo')} ${POSTINSTALL}: foo II + ${chalk.cyan('packages/foo')} ${POSTINSTALL}: foo III + ${chalk.blue('packages/qar')} ${INSTALL}$ node qar + ${chalk.blue('packages/qar')} ${INSTALL}: Done + ${chalk.cyan('packages/foo')} ${POSTINSTALL}: Done `) }, })