diff --git a/.changeset/happy-paws-walk.md b/.changeset/happy-paws-walk.md new file mode 100644 index 0000000000..809dbae153 --- /dev/null +++ b/.changeset/happy-paws-walk.md @@ -0,0 +1,6 @@ +--- +"@pnpm/plugin-commands-script-runners": patch +"pnpm": patch +--- + +When running "pnpm exec" from a subdirectory of a project, don't change the current working directory to the root of the project [#5759](https://github.com/pnpm/pnpm/issues/5759). diff --git a/exec/plugin-commands-script-runners/src/exec.ts b/exec/plugin-commands-script-runners/src/exec.ts index 20df4608ca..7658290638 100644 --- a/exec/plugin-commands-script-runners/src/exec.ts +++ b/exec/plugin-commands-script-runners/src/exec.ts @@ -146,6 +146,7 @@ export type ExecOpts = Required> & { implicitlyFellbackFromRun?: boolean } & Pick { '--store-dir', path.resolve(DEFAULT_OPTS.storeDir), ]) + process.chdir('project-1') await exec.handler({ ...DEFAULT_OPTS, dir: path.resolve('project-1'), diff --git a/pnpm/test/exec.ts b/pnpm/test/exec.ts new file mode 100644 index 0000000000..87d40f146b --- /dev/null +++ b/pnpm/test/exec.ts @@ -0,0 +1,29 @@ +import fs from 'fs' +import path from 'path' +import { prepare } from '@pnpm/prepare' +import { execPnpm, execPnpmSync } from './utils/index.js' + +test("exec should respect the caller's current working directory", async () => { + prepare({ + name: 'root', + version: '1.0.0', + }) + + const projectRoot = process.cwd() + fs.mkdirSync('some-directory', { recursive: true }) + const subdirPath = path.join(projectRoot, 'some-directory') + + await execPnpm(['install']) + + const cmdFilePath = path.join(subdirPath, 'cwd.txt') + + execPnpmSync( + ['exec', 'node', '-e', `require('fs').writeFileSync(${JSON.stringify(cmdFilePath)}, process.cwd(), 'utf8')`], + { + cwd: subdirPath, + expectSuccess: true, + } + ) + + expect(fs.readFileSync(cmdFilePath, 'utf8')).toBe(subdirPath) +})