diff --git a/.changeset/soft-insects-fly.md b/.changeset/soft-insects-fly.md new file mode 100644 index 0000000000..74c81c84e4 --- /dev/null +++ b/.changeset/soft-insects-fly.md @@ -0,0 +1,5 @@ +--- +"@pnpm/package-store": patch +--- + +If creating a hard-link to a file from the store fails, fall back to copying the file. diff --git a/packages/package-store/src/storeController/createImportPackage.ts b/packages/package-store/src/storeController/createImportPackage.ts index 53898a704a..b573edbe41 100644 --- a/packages/package-store/src/storeController/createImportPackage.ts +++ b/packages/package-store/src/storeController/createImportPackage.ts @@ -5,8 +5,6 @@ import fs = require('mz/fs') import pLimit from 'p-limit' import path = require('path') import exists = require('path-exists') -import pathTemp = require('path-temp') -import renameOverwrite = require('rename-overwrite') import importIndexedDir from '../fs/importIndexedDir' const limitLinking = pLimit(16) @@ -112,7 +110,18 @@ async function hardlinkPkg ( if (!opts.fromStore || opts.force || !await exists(pkgJsonPath) || !await pkgLinkedToStore(pkgJsonPath, opts.filesMap['package.json'], to)) { importingLogger.debug({ to, method: 'hardlink' }) - await importIndexedDir(fs.link, to, opts.filesMap) + await importIndexedDir(linkOrCopy, to, opts.filesMap) + } +} + +async function linkOrCopy (existingPath: string, newPath: string) { + try { + await fs.link(existingPath, newPath) + } catch (err) { + // In some VERY rare cases (1 in a thousand), hard-link creation fails on Windows. + // In that case, we just fall back to copying. + // This issue is reproducible with "pnpm add @material-ui/icons@4.9.1" + await fs.copyFile(existingPath, newPath) } }