mirror of
https://github.com/pnpm/pnpm.git
synced 2026-04-10 18:18:56 -04:00
fix: don't copy file during linking if the target exists
This commit is contained in:
5
.changeset/three-grapes-begin.md
Normal file
5
.changeset/three-grapes-begin.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/package-store": patch
|
||||
---
|
||||
|
||||
Do not try to copy a file during linking, if the target already exists.
|
||||
@@ -120,6 +120,9 @@ async function linkOrCopy (existingPath: string, newPath: string) {
|
||||
try {
|
||||
await fs.link(existingPath, newPath)
|
||||
} catch (err) {
|
||||
// If a hard link to the same file already exists
|
||||
// then trying to copy it will make an empty file from it.
|
||||
if (err['code'] === 'EEXIST') return
|
||||
// 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"
|
||||
|
||||
@@ -120,7 +120,12 @@ test('packageImportMethod=auto: chooses copying if cloning and hard linking is n
|
||||
|
||||
test('packageImportMethod=hardlink: fall back to copying if hardlinking fails', async () => {
|
||||
const importPackage = createImportPackage('hardlink')
|
||||
fsMock.link = jest.fn(() => {
|
||||
fsMock.link = jest.fn((src: string, dest: string) => {
|
||||
if (dest.endsWith('license')) {
|
||||
const err = new Error('')
|
||||
err['code'] = 'EEXIST'
|
||||
throw err
|
||||
}
|
||||
throw new Error('This file system does not support hard linking')
|
||||
})
|
||||
fsMock.copyFile = jest.fn()
|
||||
@@ -128,11 +133,13 @@ test('packageImportMethod=hardlink: fall back to copying if hardlinking fails',
|
||||
filesMap: {
|
||||
'index.js': 'hash2',
|
||||
'package.json': 'hash1',
|
||||
license: 'hash3',
|
||||
},
|
||||
force: false,
|
||||
fromStore: false,
|
||||
})).toBe('hardlink')
|
||||
expect(fsMock.link).toBeCalled()
|
||||
expect(fsMock.link).toBeCalledTimes(3)
|
||||
expect(fsMock.copyFile).toBeCalledTimes(2) // One time the target already exists, so it won't be copied
|
||||
expect(fsMock.copyFile).toBeCalledWith(path.join('hash1'), path.join('project', '_tmp', 'package.json'))
|
||||
expect(fsMock.copyFile).toBeCalledWith(path.join('hash2'), path.join('project', '_tmp', 'index.js'))
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user