From 916b26b63ce92e3357698aef311c2deaa8a077c8 Mon Sep 17 00:00:00 2001 From: Tensorworker <178221229+tensorworkerr@users.noreply.github.com> Date: Fri, 16 Jan 2026 10:12:33 -0500 Subject: [PATCH] fix: prevent implicit root exclusion when user filters are provided (#10465) * fix: prevent implicit root exclusion when user filters are provided * docs: add changeset * test: remove redundant init --------- Co-authored-by: tensorworker Co-authored-by: Zoltan Kochan --- .changeset/stupid-wasps-turn.md | 5 ++++ pnpm/src/main.ts | 2 +- pnpm/test/recursive/filter.ts | 46 +++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 .changeset/stupid-wasps-turn.md create mode 100644 pnpm/test/recursive/filter.ts diff --git a/.changeset/stupid-wasps-turn.md b/.changeset/stupid-wasps-turn.md new file mode 100644 index 0000000000..bf45783ae4 --- /dev/null +++ b/.changeset/stupid-wasps-turn.md @@ -0,0 +1,5 @@ +--- +"pnpm": major +--- + +Do not exclude the root workspace project, when it is explicitly selected via a filter [#10465](https://github.com/pnpm/pnpm/pull/10465). diff --git a/pnpm/src/main.ts b/pnpm/src/main.ts index 449e1ca963..6a478b1adf 100644 --- a/pnpm/src/main.ts +++ b/pnpm/src/main.ts @@ -213,7 +213,7 @@ export async function main (inputArgv: string[]): Promise { const relativeWSDirPath = () => path.relative(process.cwd(), wsDir) || '.' if (config.workspaceRoot) { filters.push({ filter: `{${relativeWSDirPath()}}`, followProdDepsOnly: Boolean(config.filterProd.length) }) - } else if (workspaceDir && !config.includeWorkspaceRoot && (cmd === 'run' || cmd === 'exec' || cmd === 'add' || cmd === 'test')) { + } else if (filters.length === 0 && workspaceDir && !config.includeWorkspaceRoot && (cmd === 'run' || cmd === 'exec' || cmd === 'add' || cmd === 'test')) { filters.push({ filter: `!{${relativeWSDirPath()}}`, followProdDepsOnly: Boolean(config.filterProd.length) }) } diff --git a/pnpm/test/recursive/filter.ts b/pnpm/test/recursive/filter.ts new file mode 100644 index 0000000000..3d979eeb27 --- /dev/null +++ b/pnpm/test/recursive/filter.ts @@ -0,0 +1,46 @@ +import fs from 'fs' +import { prepare } from '@pnpm/prepare' +import { execPnpmSync } from '../utils/index.js' + +test('pnpm --filter add should work', async () => { + prepare({ + name: 'root', + version: '1.0.0', + pnpm: { + overrides: { + 'is-positive': '1.0.0', + }, + }, + }) + + fs.writeFileSync('pnpm-workspace.yaml', 'packages:\n - "."\n') + + const result = execPnpmSync(['--filter', 'root', 'add', 'is-positive']) + if (result.status !== 0) { + console.log(result.stdout.toString()) + console.log(result.stderr.toString()) + } + expect(result.status).toBe(0) + + const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8')) + expect(pkg.dependencies['is-positive']).toBeTruthy() +}) + +test('pnpm --filter . add should work', async () => { + prepare({ + name: 'root', + version: '1.0.0', + }) + + fs.writeFileSync('pnpm-workspace.yaml', 'packages:\n - "."\n') + + const result = execPnpmSync(['--filter', '.', 'add', 'is-positive']) + if (result.status !== 0) { + console.log(result.stdout.toString()) + console.log(result.stderr.toString()) + } + expect(result.status).toBe(0) + + const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8')) + expect(pkg.dependencies['is-positive']).toBeTruthy() +})