diff --git a/.changeset/dark-monkeys-peel.md b/.changeset/dark-monkeys-peel.md new file mode 100644 index 0000000000..2f411465a2 --- /dev/null +++ b/.changeset/dark-monkeys-peel.md @@ -0,0 +1,6 @@ +--- +"@pnpm/plugin-commands-store": patch +"pnpm": patch +--- + +Fix `pnpm store path` and `pnpm store status` using workspace root for path resolution when `storeDir` is relative [#10290](https://github.com/pnpm/pnpm/issues/10290). diff --git a/store/plugin-commands-store/src/store.ts b/store/plugin-commands-store/src/store.ts index 1c96b68100..546bf230c2 100644 --- a/store/plugin-commands-store/src/store.ts +++ b/store/plugin-commands-store/src/store.ts @@ -74,7 +74,7 @@ class StoreStatusError extends PnpmError { } } -export type StoreCommandOptions = Pick & CreateStoreControllerOptions & { +export type StoreCommandOptions = Pick & CreateStoreControllerOptions & { reporter?: (logObj: LogBase) => void } @@ -85,7 +85,7 @@ export async function handler (opts: StoreCommandOptions, params: string[]): Pro return statusCmd(opts) as Promise case 'path': return getStorePath({ - pkgRoot: opts.dir, + pkgRoot: opts.workspaceDir ?? opts.dir, storePath: opts.storeDir, pnpmHomeDir: opts.pnpmHomeDir, }) @@ -115,8 +115,9 @@ export async function handler (opts: StoreCommandOptions, params: string[]): Pro async function statusCmd (opts: StoreCommandOptions): Promise { const modifiedPkgs = await storeStatus(Object.assign(opts, { + lockfileDir: opts.lockfileDir ?? opts.workspaceDir ?? opts.dir, storeDir: await getStorePath({ - pkgRoot: opts.dir, + pkgRoot: opts.workspaceDir ?? opts.dir, storePath: opts.storeDir, pnpmHomeDir: opts.pnpmHomeDir, }), diff --git a/store/plugin-commands-store/test/storePath.ts b/store/plugin-commands-store/test/storePath.ts index 118818eb2a..64b0bdb707 100644 --- a/store/plugin-commands-store/test/storePath.ts +++ b/store/plugin-commands-store/test/storePath.ts @@ -30,3 +30,30 @@ test('CLI prints the current store path', async () => { expect(candidateStorePath).toBe(expectedStorePath) }) + +test('CLI prints the current store path when storeDir is relative', async () => { + prepare() + + const workspaceDir = process.cwd() + const subpackageDir = path.join(workspaceDir, 'packages', 'foo') + const relativeStoreDir = '../store' + + const candidateStorePath = await store.handler({ + cacheDir: path.resolve('cache'), + dir: subpackageDir, + workspaceDir, + pnpmHomeDir: '', + rawConfig: { + registry: REGISTRY, + }, + registries: { default: REGISTRY }, + storeDir: relativeStoreDir, + userConfig: {}, + dlxCacheMaxAge: 0, + virtualStoreDirMaxLength: process.platform === 'win32' ? 60 : 120, + }, ['path']) + + // relativeStoreDir should resolve from workspaceDir, not dir + const expectedStorePath = path.join(workspaceDir, relativeStoreDir, STORE_VERSION) + expect(candidateStorePath).toBe(expectedStorePath) +}) diff --git a/store/plugin-commands-store/test/storeStatus.ts b/store/plugin-commands-store/test/storeStatus.ts index 0bfe381c8f..0664ff0cb9 100644 --- a/store/plugin-commands-store/test/storeStatus.ts +++ b/store/plugin-commands-store/test/storeStatus.ts @@ -99,3 +99,49 @@ test('CLI does not fail when store status does not find modified packages', asyn virtualStoreDirMaxLength: process.platform === 'win32' ? 60 : 120, }, ['status']) }) + +test('CLI does not fail when storeDir is relative', async () => { + const project = prepare() + const cacheDir = path.resolve('cache') + const workspaceDir = process.cwd() + const subpackageDir = path.join(workspaceDir, 'packages', 'foo') + const relativeStoreDir = '../.store' + + fs.writeFileSync('pnpm-workspace.yaml', `packages: + - "packages/*" +storeDir: "${relativeStoreDir}" +`, 'utf8') + + // make subpackage + fs.mkdirSync(subpackageDir, { recursive: true }) + fs.writeFileSync( + path.join(subpackageDir, 'package.json'), + JSON.stringify({ name: 'foo', version: '0.0.0' }) + ) + + await execa('node', [ + pnpmBin, + 'add', + 'is-positive@3.1.0', + `--registry=${REGISTRY}`, + '--verify-store-integrity', + ]) + + const modulesState = project.readModulesManifest() + + // relativeStoreDir should resolve from workspaceDir, not dir + await store.handler({ + cacheDir, + dir: subpackageDir, + workspaceDir, + pnpmHomeDir: '', + rawConfig: { + registry: REGISTRY, + }, + registries: modulesState!.registries!, + storeDir: relativeStoreDir, + userConfig: {}, + dlxCacheMaxAge: 0, + virtualStoreDirMaxLength: process.platform === 'win32' ? 60 : 120, + }, ['status']) +})