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 359e172641..3f66fc5283 100644 --- a/exec/plugin-commands-script-runners/src/exec.ts +++ b/exec/plugin-commands-script-runners/src/exec.ts @@ -148,6 +148,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 index 5409d2b121..78450c05d5 100644 --- a/pnpm/test/exec.ts +++ b/pnpm/test/exec.ts @@ -1,5 +1,7 @@ +import fs from 'fs' +import path from 'path' import { prepare, preparePackages } from '@pnpm/prepare' -import { execPnpmSync } from './utils/index.js' +import { execPnpm, execPnpmSync } from './utils/index.js' test('exec with executionEnv', async () => { prepare({ @@ -71,3 +73,28 @@ test('recursive exec when some packages define different executionEnv', async () '>>> node-version-unset: v19.0.0', ]) }) + +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) +})