mirror of
https://github.com/pnpm/pnpm.git
synced 2025-12-24 07:38:12 -05:00
feat(reporter): add --hide-reporter-prefix option (#7086)
close #7061 --------- Co-authored-by: Zoltan Kochan <z@kochan.io>
This commit is contained in:
8
.changeset/proud-lions-nail.md
Normal file
8
.changeset/proud-lions-nail.md
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
"@pnpm/plugin-commands-script-runners": minor
|
||||
"@pnpm/default-reporter": minor
|
||||
"@pnpm/config": minor
|
||||
"pnpm": minor
|
||||
---
|
||||
|
||||
Add `--hide-reporter-prefix' option for `run` command to hide project name as prefix for lifecycle log outputs of running scripts [#7061](https://github.com/pnpm/pnpm/issues/7061).
|
||||
@@ -27,6 +27,7 @@ export function initDefaultReporter (
|
||||
hideAddedPkgsProgress?: boolean
|
||||
hideProgressPrefix?: boolean
|
||||
hideLifecycleOutput?: boolean
|
||||
hideLifecyclePrefix?: boolean
|
||||
}
|
||||
context: {
|
||||
argv: string[]
|
||||
@@ -109,6 +110,7 @@ export function toOutput$ (
|
||||
hideAddedPkgsProgress?: boolean
|
||||
hideProgressPrefix?: boolean
|
||||
hideLifecycleOutput?: boolean
|
||||
hideLifecyclePrefix?: boolean
|
||||
}
|
||||
context: {
|
||||
argv: string[]
|
||||
@@ -269,6 +271,7 @@ export function toOutput$ (
|
||||
hideAddedPkgsProgress: opts.reportingOptions?.hideAddedPkgsProgress,
|
||||
hideProgressPrefix: opts.reportingOptions?.hideProgressPrefix ?? (cmd === 'dlx'),
|
||||
hideLifecycleOutput: opts.reportingOptions?.hideLifecycleOutput,
|
||||
hideLifecyclePrefix: opts.reportingOptions?.hideLifecyclePrefix,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ export function reporterForClient (
|
||||
hideAddedPkgsProgress?: boolean
|
||||
hideProgressPrefix?: boolean
|
||||
hideLifecycleOutput?: boolean
|
||||
hideLifecyclePrefix?: boolean
|
||||
}
|
||||
): Array<Rx.Observable<Rx.Observable<{ msg: string }>>> {
|
||||
const width = opts.width ?? process.stdout.columns ?? 80
|
||||
@@ -81,6 +82,7 @@ export function reporterForClient (
|
||||
reportLifecycleScripts(log$, {
|
||||
appendOnly: (opts.appendOnly === true || opts.streamLifecycleOutput) && !opts.hideLifecycleOutput,
|
||||
aggregateOutput: opts.aggregateOutput,
|
||||
hideLifecyclePrefix: opts.hideLifecyclePrefix,
|
||||
cwd,
|
||||
width,
|
||||
}),
|
||||
|
||||
@@ -28,6 +28,7 @@ export function reportLifecycleScripts (
|
||||
opts: {
|
||||
appendOnly?: boolean
|
||||
aggregateOutput?: boolean
|
||||
hideLifecyclePrefix?: boolean
|
||||
cwd: string
|
||||
width: number
|
||||
}
|
||||
@@ -40,7 +41,7 @@ export function reportLifecycleScripts (
|
||||
lifecycle$ = lifecycle$.pipe(aggregateOutput)
|
||||
}
|
||||
|
||||
const streamLifecycleOutput = createStreamLifecycleOutput(opts.cwd)
|
||||
const streamLifecycleOutput = createStreamLifecycleOutput(opts.cwd, !!opts.hideLifecyclePrefix)
|
||||
return lifecycle$.pipe(
|
||||
map((log: LifecycleLog) => Rx.of({
|
||||
msg: streamLifecycleOutput(log),
|
||||
@@ -215,15 +216,16 @@ function highlightLastFolder (p: string) {
|
||||
|
||||
const ANSI_ESCAPES_LENGTH_OF_PREFIX = hlValue(' ').length - 1
|
||||
|
||||
function createStreamLifecycleOutput (cwd: string) {
|
||||
function createStreamLifecycleOutput (cwd: string, hideLifecyclePrefix: boolean) {
|
||||
currentColor = 0
|
||||
const colorByPrefix: ColorByPkg = new Map()
|
||||
return streamLifecycleOutput.bind(null, colorByPrefix, cwd)
|
||||
return streamLifecycleOutput.bind(null, colorByPrefix, cwd, hideLifecyclePrefix)
|
||||
}
|
||||
|
||||
function streamLifecycleOutput (
|
||||
colorByPkg: ColorByPkg,
|
||||
cwd: string,
|
||||
hideLifecyclePrefix: boolean,
|
||||
logObj: LifecycleLog
|
||||
) {
|
||||
const prefix = formatLifecycleScriptPrefix(colorByPkg, cwd, logObj.wd, logObj.stage)
|
||||
@@ -238,7 +240,7 @@ function streamLifecycleOutput (
|
||||
return `${prefix}$ ${logObj['script'] as string}`
|
||||
}
|
||||
const line = formatLine(Infinity, logObj)
|
||||
return `${prefix}: ${line}`
|
||||
return hideLifecyclePrefix ? line : `${prefix}: ${line}`
|
||||
}
|
||||
|
||||
function formatIndentedOutput (maxWidth: number, logObj: LifecycleLog) {
|
||||
|
||||
@@ -17,7 +17,6 @@ const OUTPUT_INDENTATION = chalk.magentaBright('│')
|
||||
const STATUS_INDENTATION = chalk.magentaBright('└─')
|
||||
const STATUS_RUNNING = chalk.magentaBright('Running...')
|
||||
const STATUS_DONE = chalk.magentaBright('Done in 1s')
|
||||
const EOL = '\n'
|
||||
|
||||
function replaceTimeWith1Sec (text: string) {
|
||||
return text
|
||||
@@ -136,7 +135,7 @@ ${STATUS_INDENTATION} ${STATUS_DONE}`)
|
||||
})
|
||||
})
|
||||
|
||||
test('groups lifecycle output when append-only is used', (done) => {
|
||||
test('groups lifecycle output when append-only is used', async () => {
|
||||
const output$ = toOutput$({
|
||||
context: { argv: ['install'] },
|
||||
reportingOptions: {
|
||||
@@ -231,31 +230,23 @@ test('groups lifecycle output when append-only is used', (done) => {
|
||||
wd: 'packages/foo',
|
||||
})
|
||||
|
||||
expect.assertions(1)
|
||||
|
||||
const allOutputs = [] as string[]
|
||||
|
||||
output$.pipe(take(11), map(normalizeNewline)).subscribe({
|
||||
complete: () => {
|
||||
expect(allOutputs.join(EOL)).toBe(`\
|
||||
${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`)
|
||||
done()
|
||||
},
|
||||
error: done,
|
||||
next: (output: string) => {
|
||||
allOutputs.push(output)
|
||||
},
|
||||
})
|
||||
await expect(
|
||||
firstValueFrom(
|
||||
output$.pipe(take(11), map<string, string>(normalizeNewline), toArray())
|
||||
)
|
||||
).resolves.toEqual([
|
||||
`${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`,
|
||||
])
|
||||
})
|
||||
|
||||
test('groups lifecycle output when append-only and aggregate-output are used', async () => {
|
||||
@@ -490,6 +481,123 @@ ${chalk.cyan('packages/foo')} ${POSTINSTALL}: Done`)
|
||||
})
|
||||
})
|
||||
|
||||
test('groups lifecycle output when append-only and reporter-hide-prefix are used', async () => {
|
||||
const output$ = toOutput$({
|
||||
context: { argv: ['install'] },
|
||||
reportingOptions: {
|
||||
appendOnly: true,
|
||||
outputMaxWidth: 79,
|
||||
hideLifecyclePrefix: true,
|
||||
},
|
||||
streamParser: createStreamParser(),
|
||||
})
|
||||
|
||||
lifecycleLogger.debug({
|
||||
depPath: 'packages/foo',
|
||||
optional: false,
|
||||
script: 'node foo',
|
||||
stage: 'preinstall',
|
||||
wd: 'packages/foo',
|
||||
})
|
||||
lifecycleLogger.debug({
|
||||
depPath: 'packages/foo',
|
||||
line: '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',
|
||||
stage: 'preinstall',
|
||||
stdio: 'stdout',
|
||||
wd: 'packages/foo',
|
||||
})
|
||||
lifecycleLogger.debug({
|
||||
depPath: 'packages/foo',
|
||||
exitCode: 1,
|
||||
optional: true,
|
||||
stage: 'preinstall',
|
||||
wd: 'packages/foo',
|
||||
})
|
||||
lifecycleLogger.debug({
|
||||
depPath: 'packages/foo',
|
||||
optional: false,
|
||||
script: 'node foo',
|
||||
stage: 'postinstall',
|
||||
wd: 'packages/foo',
|
||||
})
|
||||
lifecycleLogger.debug({
|
||||
depPath: 'packages/foo',
|
||||
line: 'foo I',
|
||||
stage: 'postinstall',
|
||||
stdio: 'stdout',
|
||||
wd: 'packages/foo',
|
||||
})
|
||||
lifecycleLogger.debug({
|
||||
depPath: 'packages/bar',
|
||||
optional: false,
|
||||
script: 'node bar',
|
||||
stage: 'postinstall',
|
||||
wd: 'packages/bar',
|
||||
})
|
||||
lifecycleLogger.debug({
|
||||
depPath: 'packages/bar',
|
||||
line: 'bar I',
|
||||
stage: 'postinstall',
|
||||
stdio: 'stdout',
|
||||
wd: 'packages/bar',
|
||||
})
|
||||
lifecycleLogger.debug({
|
||||
depPath: 'packages/foo',
|
||||
line: 'foo II',
|
||||
stage: 'postinstall',
|
||||
stdio: 'stdout',
|
||||
wd: 'packages/foo',
|
||||
})
|
||||
lifecycleLogger.debug({
|
||||
depPath: 'packages/foo',
|
||||
line: 'foo III',
|
||||
stage: 'postinstall',
|
||||
stdio: 'stdout',
|
||||
wd: 'packages/foo',
|
||||
})
|
||||
lifecycleLogger.debug({
|
||||
depPath: 'packages/qar',
|
||||
optional: false,
|
||||
script: 'node qar',
|
||||
stage: 'install',
|
||||
wd: 'packages/qar',
|
||||
})
|
||||
lifecycleLogger.debug({
|
||||
depPath: 'packages/qar',
|
||||
exitCode: 0,
|
||||
optional: false,
|
||||
stage: 'install',
|
||||
wd: 'packages/qar',
|
||||
})
|
||||
lifecycleLogger.debug({
|
||||
depPath: 'packages/foo',
|
||||
exitCode: 0,
|
||||
optional: false,
|
||||
stage: 'postinstall',
|
||||
wd: 'packages/foo',
|
||||
})
|
||||
|
||||
expect.assertions(1)
|
||||
|
||||
await expect(
|
||||
firstValueFrom(
|
||||
output$.pipe(map<string, string>(normalizeNewline), take(11), toArray())
|
||||
)
|
||||
).resolves.toEqual([
|
||||
`${chalk.cyan('packages/foo')} ${PREINSTALL}$ node foo`,
|
||||
'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`,
|
||||
'foo I',
|
||||
`${chalk.magenta('packages/bar')} ${POSTINSTALL}$ node bar`,
|
||||
'bar I',
|
||||
'foo II',
|
||||
'foo III',
|
||||
`${chalk.blue('packages/qar')} ${INSTALL}$ node qar`,
|
||||
`${chalk.blue('packages/qar')} ${INSTALL}: Done`,
|
||||
])
|
||||
})
|
||||
|
||||
test('collapse lifecycle output when it has too many lines', (done) => {
|
||||
const output$ = toOutput$({
|
||||
context: { argv: ['install'] },
|
||||
|
||||
@@ -90,6 +90,7 @@ export interface Config {
|
||||
failedToLoadBuiltInConfig: boolean
|
||||
resolvePeersFromWorkspaceRoot?: boolean
|
||||
deployAllFiles?: boolean
|
||||
reporterHidePrefix?: boolean
|
||||
|
||||
// proxy
|
||||
httpProxy?: string
|
||||
|
||||
@@ -103,6 +103,7 @@ export const types = Object.assign({
|
||||
'resolution-mode': ['highest', 'time-based', 'lowest-direct'],
|
||||
'resolve-peers-from-workspace-root': Boolean,
|
||||
'aggregate-output': Boolean,
|
||||
'reporter-hide-prefix': Boolean,
|
||||
'save-peer': Boolean,
|
||||
'save-workspace-protocol': Boolean,
|
||||
'script-shell': String,
|
||||
|
||||
@@ -55,6 +55,11 @@ export const REPORT_SUMMARY_OPTION_HELP = {
|
||||
name: '--report-summary',
|
||||
}
|
||||
|
||||
export const REPORTER_HIDE_PREFIX_HELP = {
|
||||
description: 'Hide project name prefix from output of running scripts. Useful when running in CI like GitHub Actions and the output from a script may create an annotation.',
|
||||
name: '--reporter-hide-prefix',
|
||||
}
|
||||
|
||||
export const shorthands = {
|
||||
parallel: [
|
||||
'--workspace-concurrency=Infinity',
|
||||
@@ -91,6 +96,7 @@ export function cliOptionsTypes () {
|
||||
reverse: Boolean,
|
||||
'resume-from': String,
|
||||
'report-summary': Boolean,
|
||||
'reporter-hide-prefix': Boolean,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,6 +136,7 @@ For options that may be used with `-r`, see "pnpm help recursive"',
|
||||
...UNIVERSAL_OPTIONS,
|
||||
SEQUENTIAL_OPTION_HELP,
|
||||
REPORT_SUMMARY_OPTION_HELP,
|
||||
REPORTER_HIDE_PREFIX_HELP,
|
||||
],
|
||||
},
|
||||
FILTERING,
|
||||
|
||||
@@ -26,6 +26,7 @@ export function initReporter (
|
||||
streamLifecycleOutput: opts.config.stream,
|
||||
throttleProgress: 200,
|
||||
hideAddedPkgsProgress: opts.config.lockfileOnly,
|
||||
hideLifecyclePrefix: opts.config.reporterHidePrefix,
|
||||
},
|
||||
streamParser,
|
||||
})
|
||||
@@ -42,6 +43,7 @@ export function initReporter (
|
||||
aggregateOutput: opts.config.aggregateOutput,
|
||||
logLevel: opts.config.loglevel as LogLevel,
|
||||
throttleProgress: 1000,
|
||||
hideLifecyclePrefix: opts.config.reporterHidePrefix,
|
||||
},
|
||||
streamParser,
|
||||
})
|
||||
|
||||
@@ -1739,6 +1739,92 @@ packages/alfa test: OK`
|
||||
)
|
||||
})
|
||||
|
||||
test('run --reporter-hide-prefix should hide prefix', async () => {
|
||||
preparePackages([
|
||||
{
|
||||
location: '.',
|
||||
package: {
|
||||
name: 'root',
|
||||
version: '0.0.0',
|
||||
private: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
location: 'packages/alfa',
|
||||
package: {
|
||||
name: 'alfa',
|
||||
version: '1.0.0',
|
||||
scripts: {
|
||||
test: "node -e \"console.log('OK')\"",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
location: 'packages/beta',
|
||||
package: {
|
||||
name: 'beta',
|
||||
version: '1.0.0',
|
||||
scripts: {
|
||||
test: "node -e \"console.log('OK')\"",
|
||||
},
|
||||
},
|
||||
},
|
||||
])
|
||||
|
||||
await writeYamlFile('pnpm-workspace.yaml', { packages: ['**', '!store/**'] })
|
||||
|
||||
const result = execPnpmSync([
|
||||
'--stream',
|
||||
'--reporter-hide-prefix',
|
||||
'--filter',
|
||||
'alfa',
|
||||
'--filter',
|
||||
'beta',
|
||||
'run',
|
||||
'test',
|
||||
])
|
||||
expect(
|
||||
result.stdout
|
||||
.toString()
|
||||
.trim()
|
||||
.split('\n')
|
||||
.sort()
|
||||
.join('\n')
|
||||
).toBe(
|
||||
`OK
|
||||
OK
|
||||
Scope: 2 of 3 workspace projects
|
||||
packages/alfa test$ node -e "console.log('OK')"
|
||||
packages/alfa test: Done
|
||||
packages/beta test$ node -e "console.log('OK')"
|
||||
packages/beta test: Done`
|
||||
)
|
||||
const singleResult = execPnpmSync([
|
||||
'--stream',
|
||||
'--reporter-hide-prefix',
|
||||
'--filter',
|
||||
'alfa',
|
||||
'run',
|
||||
'test',
|
||||
])
|
||||
|
||||
console.log(singleResult.stdout
|
||||
.toString())
|
||||
|
||||
expect(
|
||||
singleResult.stdout
|
||||
.toString()
|
||||
.trim()
|
||||
.split('\n')
|
||||
.sort()
|
||||
.join('\n')
|
||||
).toBe(
|
||||
`OK
|
||||
packages/alfa test$ node -e "console.log('OK')"
|
||||
packages/alfa test: Done`
|
||||
)
|
||||
})
|
||||
|
||||
test('peer dependencies are resolved from the root of the workspace when a new dependency is added to a workspace project', async () => {
|
||||
const projects = preparePackages([
|
||||
{
|
||||
|
||||
@@ -222,3 +222,20 @@ test('--parallel should work with single project', async () => {
|
||||
expect(output).toContain('script1: 1')
|
||||
expect(output).toContain('script2: 2')
|
||||
})
|
||||
|
||||
test('--reporter-hide-prefix should hide workspace prefix', async () => {
|
||||
prepare({
|
||||
scripts: {
|
||||
script1: 'echo 1',
|
||||
script2: 'echo 2',
|
||||
},
|
||||
})
|
||||
|
||||
const result = execPnpmSync(['--parallel', '--reporter-hide-prefix', 'run', '/script[12]/'])
|
||||
|
||||
const output = result.stdout.toString()
|
||||
expect(output).toContain('1')
|
||||
expect(output).not.toContain('script1: 1')
|
||||
expect(output).toContain('2')
|
||||
expect(output).not.toContain('script2: 2')
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user