diff --git a/.changeset/fix-recursive-run-no-script.md b/.changeset/fix-recursive-run-no-script.md new file mode 100644 index 0000000000..db71460db8 --- /dev/null +++ b/.changeset/fix-recursive-run-no-script.md @@ -0,0 +1,6 @@ +--- +"pnpm": patch +"@pnpm/plugin-commands-script-runners": patch +--- + +`pnpm run -r` and `pnpm run --filter` now fail with a non-zero exit code when no packages have the specified script. Previously, this only failed when all packages were selected. Use `--if-present` to suppress this error [#6844](https://github.com/pnpm/pnpm/issues/6844). diff --git a/exec/plugin-commands-script-runners/src/runRecursive.ts b/exec/plugin-commands-script-runners/src/runRecursive.ts index 2a64011cca..7de1c91cb4 100644 --- a/exec/plugin-commands-script-runners/src/runRecursive.ts +++ b/exec/plugin-commands-script-runners/src/runRecursive.ts @@ -8,7 +8,6 @@ import { makeNodeRequireOption, type RunLifecycleHookOptions, } from '@pnpm/lifecycle' -import { logger } from '@pnpm/logger' import { groupStart } from '@pnpm/log.group' import { sortPackages } from '@pnpm/sort-packages' import pLimit from 'p-limit' @@ -187,10 +186,7 @@ export async function runRecursive ( if (allPackagesAreSelected) { throw new PnpmError('RECURSIVE_RUN_NO_SCRIPT', `None of the packages has a "${scriptName}" script`) } else { - logger.info({ - message: `None of the selected packages has a "${scriptName}" script`, - prefix: opts.workspaceDir, - }) + throw new PnpmError('RECURSIVE_RUN_NO_SCRIPT', `None of the selected packages has a "${scriptName}" script`) } } opts.reportSummary && await writeRecursiveSummary({ diff --git a/exec/plugin-commands-script-runners/test/runRecursive.ts b/exec/plugin-commands-script-runners/test/runRecursive.ts index 8b9ac8c5ed..c57ec1fabf 100644 --- a/exec/plugin-commands-script-runners/test/runRecursive.ts +++ b/exec/plugin-commands-script-runners/test/runRecursive.ts @@ -380,7 +380,7 @@ test('`pnpm recursive run` fails when run with a filter that includes all packag expect(err.code).toBe('ERR_PNPM_RECURSIVE_RUN_NO_SCRIPT') }) -test('`pnpm recursive run` succeeds when run against a subset of packages and no package has the desired command', async () => { +test('`pnpm recursive run` fails when run against a subset of packages and no package has the desired command, unless if-present is set', async () => { preparePackages([ { name: 'project-1', @@ -422,14 +422,28 @@ test('`pnpm recursive run` succeeds when run against a subset of packages and no [{ namePattern: 'project-1' }], { workspaceDir: process.cwd() } ) + + // Recursive run does not fail when if-present is true await run.handler({ ...DEFAULT_OPTS, allProjects, dir: process.cwd(), + ifPresent: true, recursive: true, selectedProjectsGraph, workspaceDir: process.cwd(), }, ['this-command-does-not-exist']) + + await expect( + run.handler({ + ...DEFAULT_OPTS, + allProjects, + dir: process.cwd(), + recursive: true, + selectedProjectsGraph, + workspaceDir: process.cwd(), + }, ['this-command-does-not-exist']) + ).rejects.toThrow(/None of the selected packages has a/) }) test('"pnpm run --filter " without specifying the script name', async () => {