From 3d9503461ff7d7f60f3f0ba4e1c0287197ede9be Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Mon, 24 Jul 2023 22:06:43 +0300 Subject: [PATCH] fix: local dependencies pointing to a symlink (#6854) --- .changeset/eight-countries-poke.md | 6 ++++++ .../src/symlinkDirectRootDependency.ts | 17 ++--------------- pkg-manager/core/test/install/local.ts | 11 +++++++++++ 3 files changed, 19 insertions(+), 15 deletions(-) create mode 100644 .changeset/eight-countries-poke.md diff --git a/.changeset/eight-countries-poke.md b/.changeset/eight-countries-poke.md new file mode 100644 index 0000000000..f42fe3676e --- /dev/null +++ b/.changeset/eight-countries-poke.md @@ -0,0 +1,6 @@ +--- +"@pnpm/symlink-dependency": patch +"pnpm": patch +--- + +When dealing with a local dependency that is a path to a symlink, a new symlink should be created to the original symlink, not to the actual directory location. diff --git a/fs/symlink-dependency/src/symlinkDirectRootDependency.ts b/fs/symlink-dependency/src/symlinkDirectRootDependency.ts index 0040d07864..df202f6ac0 100644 --- a/fs/symlink-dependency/src/symlinkDirectRootDependency.ts +++ b/fs/symlink-dependency/src/symlinkDirectRootDependency.ts @@ -4,7 +4,6 @@ import { type DependencyType, rootLogger, } from '@pnpm/core-loggers' -import { globalWarn } from '@pnpm/logger' import { type DependenciesField } from '@pnpm/types' import symlinkDir from 'symlink-dir' @@ -44,25 +43,13 @@ export async function symlinkDirectRootDependency ( } } - let dependencyRealLocation!: string - try { - dependencyRealLocation = await fs.realpath(dependencyLocation) - } catch (err: any) { // eslint-disable-line - if (err.code !== 'ENOENT') throw err - globalWarn(`Local dependency not found at ${dependencyLocation}`) - // Sometimes the linked in local package does not exist during installation - // and is created later via a build script. - // That is why we create the symlink even if the target directory does not exist. - dependencyRealLocation = dependencyLocation - } - const dest = path.join(destModulesDirReal, importAs) - const { reused } = await symlinkDir(dependencyRealLocation, dest) + const { reused } = await symlinkDir(dependencyLocation, dest) if (reused) return // if the link was already present, don't log rootLogger.debug({ added: { dependencyType: opts.fromDependenciesField && DEP_TYPE_BY_DEPS_FIELD_NAME[opts.fromDependenciesField] as DependencyType, - linkedFrom: dependencyRealLocation, + linkedFrom: dependencyLocation, name: importAs, realName: opts.linkedPackage.name, version: opts.linkedPackage.version, diff --git a/pkg-manager/core/test/install/local.ts b/pkg-manager/core/test/install/local.ts index 283ec24394..fdb90a4184 100644 --- a/pkg-manager/core/test/install/local.ts +++ b/pkg-manager/core/test/install/local.ts @@ -59,6 +59,17 @@ test('local file', async () => { }) }) +test('a symlink to a symlink to a local dependency is preserved', async () => { + prepareEmpty() + const localPkgDir = path.resolve('..', 'local-pkg') + f.copy('local-pkg', localPkgDir) + await symlinkDir(localPkgDir, path.resolve('../symlink')) + + await addDependenciesToPackage({}, ['link:../symlink'], await testDefaults()) + + expect(await fs.readlink(path.resolve('node_modules/local-pkg'))).toContain('symlink') +}) + test('local directory with no package.json', async () => { const project = prepareEmpty() await fs.mkdir('pkg')