diff --git a/lib/commands/run-script.js b/lib/commands/run-script.js index 86a1b6b6d87ed..0e051d36908ee 100644 --- a/lib/commands/run-script.js +++ b/lib/commands/run-script.js @@ -159,25 +159,30 @@ class RunScript extends BaseCommand { } const [cmds, runScripts] = scriptEntries.reduce((acc, s) => { - acc[cmdList.includes(s) ? 0 : 1].push(s) + acc[cmdList.includes(s[0]) ? 0 : 1].push(s) return acc }, [[], []]) const { reset, bold, green, dim, blue } = this.npm.chalk - let pkgId = ` in ${green(_id || name)}` + const inPkg = `in ${green(_id || name)}` const title = (t) => reset(bold(t)) if (cmds.length) { - output.standard(`${title('Lifecycle scripts')} included${pkgId}:`) + output.standard(`${title('Lifecycle scripts')} included ${inPkg}:`) for (const [k, v] of cmds) { output.standard(` ${k}`) output.standard(` ${dim(v)}`) } - pkgId = '' } if (runScripts.length) { - output.standard(`${title('Scripts')} available${pkgId} via \`${blue('npm run-script')}\`:`) + const via = `via \`${blue('npm run-script')}\`:` + if (!cmds.length) { + output.standard(`${title('Scripts')} available ${inPkg} ${via}`) + } else { + output.standard('') + output.standard(`available ${via}`) + } for (const [k, v] of runScripts) { output.standard(` ${k}`) output.standard(` ${dim(v)}`) diff --git a/tap-snapshots/test/lib/commands/run-script.js.test.cjs b/tap-snapshots/test/lib/commands/run-script.js.test.cjs new file mode 100644 index 0000000000000..2140adb6894c4 --- /dev/null +++ b/tap-snapshots/test/lib/commands/run-script.js.test.cjs @@ -0,0 +1,263 @@ +/* IMPORTANT + * This snapshot file is auto-generated, but designed for humans. + * It should be checked into source control and tracked carefully. + * Re-generate by setting TAP_SNAPSHOT=1 and running tests. + * Make sure to inspect the output below. Do not ignore changes! + */ +'use strict' +exports[`test/lib/commands/run-script.js TAP list scripts no args > basic report 1`] = ` +Lifecycle scripts included in x@1.2.3: + test + exit 2 + start + node server.js + stop + node kill-server.js + +available via \`npm run-script\`: + preenv + echo before the env + postenv + echo after the env +` + +exports[`test/lib/commands/run-script.js TAP list scripts parseable > must match snapshot 1`] = ` +test:exit 2 +start:node server.js +stop:node kill-server.js +preenv:echo before the env +postenv:echo after the env +` + +exports[`test/lib/commands/run-script.js TAP list scripts warn json > json report 1`] = ` +{ + test: 'exit 2', + start: 'node server.js', + stop: 'node kill-server.js', + preenv: 'echo before the env', + postenv: 'echo after the env' +} +` + +exports[`test/lib/commands/run-script.js TAP list scripts, only commands > must match snapshot 1`] = ` +Lifecycle scripts included in x@1.2.3: + preversion + echo doing the version dance +` + +exports[`test/lib/commands/run-script.js TAP list scripts, only non-commands > must match snapshot 1`] = ` +Scripts available in x@1.2.3 via \`npm run-script\`: + glorp + echo doing the glerp glop +` + +exports[`test/lib/commands/run-script.js TAP workspaces failed workspace run with succeeded runs > should log error msgs for each workspace script 1`] = ` +Lifecycle script \`glorp\` failed with error: +Error: ERR + in workspace: a@1.0.0 + at location: {CWD}/prefix/packages/a +` + +exports[`test/lib/commands/run-script.js TAP workspaces list all scripts --json > must match snapshot 1`] = ` +{ a: { glorp: 'echo a doing the glerp glop' } } +{ b: { glorp: 'echo b doing the glerp glop' } } +{ + c: { test: 'exit 0', posttest: 'echo posttest', lorem: 'echo c lorem' } +} +{ d: { test: 'exit 0', posttest: 'echo posttest' } } +{ e: { test: 'exit 0', start: 'echo start something' } } +{ noscripts: {} } +` + +exports[`test/lib/commands/run-script.js TAP workspaces list all scripts --parseable > must match snapshot 1`] = ` +a:glorp:echo a doing the glerp glop +b:glorp:echo b doing the glerp glop +c:test:exit 0 +c:posttest:echo posttest +c:lorem:echo c lorem +d:test:exit 0 +d:posttest:echo posttest +e:test:exit 0 +e:start:echo start something +` + +exports[`test/lib/commands/run-script.js TAP workspaces list all scripts > must match snapshot 1`] = ` +Scripts available in a@1.0.0 via \`npm run-script\`: + glorp + echo a doing the glerp glop + +Scripts available in b@2.0.0 via \`npm run-script\`: + glorp + echo b doing the glerp glop + +Lifecycle scripts included in c@1.0.0: + test + exit 0 + posttest + echo posttest + +available via \`npm run-script\`: + lorem + echo c lorem + +Lifecycle scripts included in d@1.0.0: + test + exit 0 + posttest + echo posttest + +Lifecycle scripts included in e: + test + exit 0 + start + echo start something +` + +exports[`test/lib/commands/run-script.js TAP workspaces list all scripts with colors > must match snapshot 1`] = ` +Scripts available in a@1.0.0 via \`npm run-script\`: + glorp + echo a doing the glerp glop + +Scripts available in b@2.0.0 via \`npm run-script\`: + glorp + echo b doing the glerp glop + +Lifecycle scripts included in c@1.0.0: + test + exit 0 + posttest + echo posttest + +available via \`npm run-script\`: + lorem + echo c lorem + +Lifecycle scripts included in d@1.0.0: + test + exit 0 + posttest + echo posttest + +Lifecycle scripts included in e: + test + exit 0 + start + echo start something +` + +exports[`test/lib/commands/run-script.js TAP workspaces list regular scripts, filtered by name > must match snapshot 1`] = ` +Scripts available in a@1.0.0 via \`npm run-script\`: + glorp + echo a doing the glerp glop + +Scripts available in b@2.0.0 via \`npm run-script\`: + glorp + echo b doing the glerp glop +` + +exports[`test/lib/commands/run-script.js TAP workspaces list regular scripts, filtered by parent folder > must match snapshot 1`] = ` +Scripts available in a@1.0.0 via \`npm run-script\`: + glorp + echo a doing the glerp glop + +Scripts available in b@2.0.0 via \`npm run-script\`: + glorp + echo b doing the glerp glop + +Lifecycle scripts included in c@1.0.0: + test + exit 0 + posttest + echo posttest + +available via \`npm run-script\`: + lorem + echo c lorem + +Lifecycle scripts included in d@1.0.0: + test + exit 0 + posttest + echo posttest + +Lifecycle scripts included in e: + test + exit 0 + start + echo start something +` + +exports[`test/lib/commands/run-script.js TAP workspaces list regular scripts, filtered by path > must match snapshot 1`] = ` +Scripts available in a@1.0.0 via \`npm run-script\`: + glorp + echo a doing the glerp glop +` + +exports[`test/lib/commands/run-script.js TAP workspaces missing scripts in all workspaces > should log error msgs for each workspace script 1`] = ` +Lifecycle script \`missing-script\` failed with error: +Error: Missing script: "missing-script" + +To see a list of scripts, run: + npm run + in workspace: a@1.0.0 + at location: {CWD}/prefix/packages/a +Lifecycle script \`missing-script\` failed with error: +Error: Missing script: "missing-script" + +To see a list of scripts, run: + npm run + in workspace: b@2.0.0 + at location: {CWD}/prefix/packages/b +Lifecycle script \`missing-script\` failed with error: +Error: Missing script: "missing-script" + +To see a list of scripts, run: + npm run + in workspace: c@1.0.0 + at location: {CWD}/prefix/packages/c +Lifecycle script \`missing-script\` failed with error: +Error: Missing script: "missing-script" + +To see a list of scripts, run: + npm run + in workspace: d@1.0.0 + at location: {CWD}/prefix/packages/d +Lifecycle script \`missing-script\` failed with error: +Error: Missing script: "missing-script" + +To see a list of scripts, run: + npm run + in workspace: e + at location: {CWD}/prefix/packages/e +Lifecycle script \`missing-script\` failed with error: +Error: Missing script: "missing-script" + +To see a list of scripts, run: + npm run + in workspace: noscripts@1.0.0 + at location: {CWD}/prefix/packages/noscripts +` + +exports[`test/lib/commands/run-script.js TAP workspaces missing scripts in some workspaces > should log error msgs for each workspace script 1`] = ` +Lifecycle script \`test\` failed with error: +Error: Missing script: "test" + +To see a list of scripts, run: + npm run + in workspace: a@1.0.0 + at location: {CWD}/prefix/packages/a +Lifecycle script \`test\` failed with error: +Error: Missing script: "test" + +To see a list of scripts, run: + npm run + in workspace: b@2.0.0 + at location: {CWD}/prefix/packages/b +` + +exports[`test/lib/commands/run-script.js TAP workspaces single failed workspace run > should log error msgs for each workspace script 1`] = ` +Lifecycle script \`test\` failed with error: +Error: err + in workspace: c@1.0.0 + at location: {CWD}/prefix/packages/c +` diff --git a/test/lib/commands/run-script.js b/test/lib/commands/run-script.js index b1c0c95b2deae..5009f13205747 100644 --- a/test/lib/commands/run-script.js +++ b/test/lib/commands/run-script.js @@ -30,7 +30,7 @@ const mockRs = async (t, { windows = false, runScript, ...opts } = {}) => { ...mock, RUN_SCRIPTS: () => RUN_SCRIPTS, runScript: mock['run-script'], - cleanLogs: () => mock.logs.error.map(cleanCwd), + cleanLogs: () => mock.logs.error.map(cleanCwd).join('\n'), } } @@ -423,20 +423,7 @@ t.test('list scripts', async t => { t.test('no args', async t => { const output = await mockList(t) - t.strictSame( - output, - [ - 'Lifecycle scripts included in x@1.2.3:', - ' test\n exit 2', - ' start\n node server.js', - ' stop\n node kill-server.js', - '\navailable via `npm run-script`:', - ' preenv\n echo before the env', - ' postenv\n echo after the env', - '', - ].join('\n'), - 'basic report' - ) + t.matchSnapshot(output, 'basic report') }) t.test('silent', async t => { @@ -445,18 +432,12 @@ t.test('list scripts', async t => { }) t.test('warn json', async t => { const output = await mockList(t, { json: true }) - t.strictSame(output, JSON.stringify(scripts, 0, 2), 'json report') + t.matchSnapshot(output, 'json report') }) t.test('parseable', async t => { const output = await mockList(t, { parseable: true }) - t.strictSame(output, [ - 'test:exit 2', - 'start:node server.js', - 'stop:node kill-server.js', - 'preenv:echo before the env', - 'postenv:echo after the env', - ].join('\n')) + t.matchSnapshot(output) }) }) @@ -486,11 +467,7 @@ t.test('list scripts, only commands', async t => { }) await runScript.exec([]) - t.strictSame(joinedOutput(), [ - 'Lifecycle scripts included in x@1.2.3:', - ' preversion\n echo doing the version dance', - '', - ].join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('list scripts, only non-commands', async t => { @@ -505,11 +482,7 @@ t.test('list scripts, only non-commands', async t => { }) await runScript.exec([]) - t.strictSame(joinedOutput(), [ - 'Scripts available in x@1.2.3 via `npm run-script`:', - ' glorp\n echo doing the glerp glop', - '', - ].join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('workspaces', async t => { @@ -591,145 +564,37 @@ t.test('workspaces', async t => { t.test('list all scripts', async t => { const { joinedOutput } = await mockWorkspaces(t) - t.strictSame(joinedOutput(), [ - 'Scripts available in a@1.0.0 via `npm run-script`:', - ' glorp\n echo a doing the glerp glop', - '', - 'Scripts available in b@2.0.0 via `npm run-script`:', - ' glorp\n echo b doing the glerp glop', - '', - 'Lifecycle scripts included in c@1.0.0:', - ' test\n exit 0', - ' posttest\n echo posttest', - '\navailable via `npm run-script`:', - ' lorem\n echo c lorem', - '', - 'Lifecycle scripts included in d@1.0.0:', - ' test\n exit 0', - ' posttest\n echo posttest', - '', - 'Lifecycle scripts included in e:', - ' test\n exit 0', - ' start\n echo start something', - '', - ].join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('list regular scripts, filtered by name', async t => { const { joinedOutput } = await mockWorkspaces(t, { workspaces: ['a', 'b'] }) - t.strictSame(joinedOutput(), [ - 'Scripts available in a@1.0.0 via `npm run-script`:', - ' glorp\n echo a doing the glerp glop', - '', - 'Scripts available in b@2.0.0 via `npm run-script`:', - ' glorp\n echo b doing the glerp glop', - '', - ].join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('list regular scripts, filtered by path', async t => { const { joinedOutput } = await mockWorkspaces(t, { workspaces: ['./packages/a'] }) - t.strictSame(joinedOutput(), [ - 'Scripts available in a@1.0.0 via `npm run-script`:', - ' glorp\n echo a doing the glerp glop', - '', - ].join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('list regular scripts, filtered by parent folder', async t => { const { joinedOutput } = await mockWorkspaces(t, { workspaces: ['./packages'] }) - t.strictSame(joinedOutput(), [ - 'Scripts available in a@1.0.0 via `npm run-script`:', - ' glorp\n echo a doing the glerp glop', - '', - 'Scripts available in b@2.0.0 via `npm run-script`:', - ' glorp\n echo b doing the glerp glop', - '', - 'Lifecycle scripts included in c@1.0.0:', - ' test\n exit 0', - ' posttest\n echo posttest', - '\navailable via `npm run-script`:', - ' lorem\n echo c lorem', - '', - 'Lifecycle scripts included in d@1.0.0:', - ' test\n exit 0', - ' posttest\n echo posttest', - '', - 'Lifecycle scripts included in e:', - ' test\n exit 0', - ' start\n echo start something', - '', - ].join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('list all scripts with colors', async t => { const { joinedOutput } = await mockWorkspaces(t, { color: 'always' }) - t.strictSame(joinedOutput(), [ - /* eslint-disable-next-line max-len */ - '\u001b[1mScripts\u001b[22m available in \x1B[32ma@1.0.0\x1B[39m via `\x1B[34mnpm run-script\x1B[39m`:', - ' glorp\n \x1B[2mecho a doing the glerp glop\x1B[22m', - '', - /* eslint-disable-next-line max-len */ - '\u001b[1mScripts\u001b[22m available in \x1B[32mb@2.0.0\x1B[39m via `\x1B[34mnpm run-script\x1B[39m`:', - ' glorp\n \x1B[2mecho b doing the glerp glop\x1B[22m', - '', - '\x1B[0m\x1B[1mLifecycle scripts\x1B[22m\x1B[0m included in \x1B[32mc@1.0.0\x1B[39m:', - ' test\n \x1B[2mexit 0\x1B[22m', - ' posttest\n \x1B[2mecho posttest\x1B[22m', - '\navailable via `\x1B[34mnpm run-script\x1B[39m`:', - ' lorem\n \x1B[2mecho c lorem\x1B[22m', - '', - '\x1B[0m\x1B[1mLifecycle scripts\x1B[22m\x1B[0m included in \x1B[32md@1.0.0\x1B[39m:', - ' test\n \x1B[2mexit 0\x1B[22m', - ' posttest\n \x1B[2mecho posttest\x1B[22m', - '', - '\x1B[0m\x1B[1mLifecycle scripts\x1B[22m\x1B[0m included in \x1B[32me\x1B[39m:', - ' test\n \x1B[2mexit 0\x1B[22m', - ' start\n \x1B[2mecho start something\x1B[22m', - '', - ].join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('list all scripts --json', async t => { const { joinedOutput } = await mockWorkspaces(t, { json: true }) - t.strictSame(joinedOutput(), - '{\n' + - ' "a": {\n' + - ' "glorp": "echo a doing the glerp glop"\n' + - ' },\n' + - ' "b": {\n' + - ' "glorp": "echo b doing the glerp glop"\n' + - ' },\n' + - ' "c": {\n' + - ' "test": "exit 0",\n' + - ' "posttest": "echo posttest",\n' + - ' "lorem": "echo c lorem"\n' + - ' },\n' + - ' "d": {\n' + - ' "test": "exit 0",\n' + - ' "posttest": "echo posttest"\n' + - ' },\n' + - ' "e": {\n' + - ' "test": "exit 0",\n' + - ' "start": "echo start something"\n' + - ' },\n' + - ' "noscripts": {}\n' + - '}') + t.matchSnapshot(joinedOutput()) }) t.test('list all scripts --parseable', async t => { const { joinedOutput } = await mockWorkspaces(t, { parseable: true }) - t.strictSame(joinedOutput(), [ - 'a:glorp:echo a doing the glerp glop', - 'b:glorp:echo b doing the glerp glop', - 'c:test:exit 0', - 'c:posttest:echo posttest', - 'c:lorem:echo c lorem', - 'd:test:exit 0', - 'd:posttest:echo posttest', - 'e:test:exit 0', - 'e:start:echo start something', - ].join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('list no scripts --loglevel=silent', async t => { @@ -774,34 +639,8 @@ t.test('workspaces', async t => { await runScript.exec(['missing-script']) t.match(RUN_SCRIPTS(), []) - t.strictSame( + t.matchSnapshot( cleanLogs(), - [ - 'Lifecycle script `missing-script` failed with error:', - 'Error: Missing script: "missing-script"\n\nTo see a list of scripts, run:\n npm run', - ' in workspace: a@1.0.0', - ' at location: {CWD}/prefix/packages/a', - 'Lifecycle script `missing-script` failed with error:', - 'Error: Missing script: "missing-script"\n\nTo see a list of scripts, run:\n npm run', - ' in workspace: b@2.0.0', - ' at location: {CWD}/prefix/packages/b', - 'Lifecycle script `missing-script` failed with error:', - 'Error: Missing script: "missing-script"\n\nTo see a list of scripts, run:\n npm run', - ' in workspace: c@1.0.0', - ' at location: {CWD}/prefix/packages/c', - 'Lifecycle script `missing-script` failed with error:', - 'Error: Missing script: "missing-script"\n\nTo see a list of scripts, run:\n npm run', - ' in workspace: d@1.0.0', - ' at location: {CWD}/prefix/packages/d', - 'Lifecycle script `missing-script` failed with error:', - 'Error: Missing script: "missing-script"\n\nTo see a list of scripts, run:\n npm run', - ' in workspace: e', - ' at location: {CWD}/prefix/packages/e', - 'Lifecycle script `missing-script` failed with error:', - 'Error: Missing script: "missing-script"\n\nTo see a list of scripts, run:\n npm run', - ' in workspace: noscripts@1.0.0', - ' at location: {CWD}/prefix/packages/noscripts', - ], 'should log error msgs for each workspace script' ) }) @@ -813,18 +652,8 @@ t.test('workspaces', async t => { }) t.match(RUN_SCRIPTS(), []) - t.strictSame( + t.matchSnapshot( cleanLogs(), - [ - 'Lifecycle script `test` failed with error:', - 'Error: Missing script: "test"\n\nTo see a list of scripts, run:\n npm run', - ' in workspace: a@1.0.0', - ' at location: {CWD}/prefix/packages/a', - 'Lifecycle script `test` failed with error:', - 'Error: Missing script: "test"\n\nTo see a list of scripts, run:\n npm run', - ' in workspace: b@2.0.0', - ' at location: {CWD}/prefix/packages/b', - ], 'should log error msgs for each workspace script' ) }) @@ -861,14 +690,8 @@ t.test('workspaces', async t => { workspaces: ['c'], }) - t.strictSame( + t.matchSnapshot( cleanLogs(), - [ - 'Lifecycle script `test` failed with error:', - 'Error: err', - ' in workspace: c@1.0.0', - ' at location: {CWD}/prefix/packages/c', - ], 'should log error msgs for each workspace script' ) }) @@ -884,14 +707,8 @@ t.test('workspaces', async t => { workspaces: ['a', 'b'], }) - t.strictSame( + t.matchSnapshot( cleanLogs(), - [ - 'Lifecycle script `glorp` failed with error:', - 'Error: ERR', - ' in workspace: a@1.0.0', - ' at location: {CWD}/prefix/packages/a', - ], 'should log error msgs for each workspace script' )