diff --git a/.changeset/old-otters-sleep.md b/.changeset/old-otters-sleep.md new file mode 100644 index 00000000000..8ca6bf06ede --- /dev/null +++ b/.changeset/old-otters-sleep.md @@ -0,0 +1,6 @@ +--- +"@pnpm/hooks.read-package-hook": patch +"pnpm": patch +--- + +It should be possible to override a dependency with a local package using relative path from the workspace root directory [#5493](https://github.com/pnpm/pnpm/issues/5493). diff --git a/hooks/read-package-hook/src/createVersionsOverrider.ts b/hooks/read-package-hook/src/createVersionsOverrider.ts index a61c792c1fc..69e2cc03fd1 100644 --- a/hooks/read-package-hook/src/createVersionsOverrider.ts +++ b/hooks/read-package-hook/src/createVersionsOverrider.ts @@ -16,9 +16,14 @@ export function createVersionsOverrider ( if (override.newPref.startsWith('link:')) { linkTarget = path.join(rootDir, override.newPref.substring(5)) } + let linkFileTarget: string | undefined + if (override.newPref.startsWith('file:')) { + linkFileTarget = path.join(rootDir, override.newPref.substring(5)) + } return { ...override, linkTarget, + linkFileTarget, } }) ) as [VersionOverrideWithParent[], VersionOverride[]] @@ -44,6 +49,7 @@ interface VersionOverride { } newPref: string linkTarget?: string + linkFileTarget?: string } interface VersionOverrideWithParent extends VersionOverride { @@ -72,6 +78,10 @@ function overrideDeps (versionOverrides: VersionOverride[], deps: Dependencies, deps[versionOverride.targetPkg.name] = `link:${normalizePath(path.relative(dir, versionOverride.linkTarget))}` continue } + if (versionOverride.linkFileTarget) { + deps[versionOverride.targetPkg.name] = `file:${versionOverride.linkFileTarget}` + continue + } deps[versionOverride.targetPkg.name] = versionOverride.newPref } } diff --git a/hooks/read-package-hook/test/createVersionOverrider.test.ts b/hooks/read-package-hook/test/createVersionOverrider.test.ts index 4d918b1345b..4341d3851a3 100644 --- a/hooks/read-package-hook/test/createVersionOverrider.test.ts +++ b/hooks/read-package-hook/test/createVersionOverrider.test.ts @@ -252,3 +252,22 @@ test('createVersionsOverrider() should work for scoped parent and scoped child', }, }) }) + +test('createVersionsOverrider() overrides dependencies with file', () => { + const overrider = createVersionsOverrider({ + qar: 'file:../qar', + }, process.cwd()) + expect(overrider({ + name: 'foo', + version: '1.2.0', + dependencies: { + qar: '3.0.0', + }, + }, path.resolve('pkg'))).toStrictEqual({ + name: 'foo', + version: '1.2.0', + dependencies: { + qar: `file:${path.resolve('../qar')}`, + }, + }) +}) diff --git a/resolving/local-resolver/test/index.ts b/resolving/local-resolver/test/index.ts index 0cb31ed6b91..0412a1910ad 100644 --- a/resolving/local-resolver/test/index.ts +++ b/resolving/local-resolver/test/index.ts @@ -12,6 +12,17 @@ test('resolve directory', async () => { expect(resolveResult!.resolution['type']).toEqual('directory') }) +test('resolve directory specified using absolute path', async () => { + const linkedDir = path.join(__dirname, '..') + const normalizedLinkedDir = normalize(linkedDir) + const resolveResult = await resolveFromLocal({ pref: `link:${linkedDir}` }, { projectDir: __dirname }) + expect(resolveResult!.id).toEqual('link:..') + expect(resolveResult!.normalizedPref).toEqual(`link:${normalizedLinkedDir}`) + expect(resolveResult!['manifest']!.name).toEqual('@pnpm/local-resolver') + expect(resolveResult!.resolution['directory']).toEqual(normalizedLinkedDir) + expect(resolveResult!.resolution['type']).toEqual('directory') +}) + test('resolve injected directory', async () => { const resolveResult = await resolveFromLocal({ injected: true, pref: '..' }, { projectDir: __dirname }) expect(resolveResult!.id).toEqual('file:..')