mirror of
https://github.com/pnpm/pnpm.git
synced 2026-01-07 14:38:32 -05:00
perf: don't random ID to temp file names (#6817)
This commit is contained in:
8
.changeset/tough-houses-admire.md
Normal file
8
.changeset/tough-houses-admire.md
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
"@pnpm/package-requester": patch
|
||||
"@pnpm/fs.indexed-pkg-importer": patch
|
||||
"@pnpm/npm-resolver": patch
|
||||
"@pnpm/cafs": patch
|
||||
---
|
||||
|
||||
Improve performance by removing cryptographically generated id from temporary file names.
|
||||
@@ -23,7 +23,7 @@
|
||||
"make-empty-dir": "^2.0.0",
|
||||
"p-limit": "^3.1.0",
|
||||
"path-exists": "^4.0.0",
|
||||
"path-temp": "^2.0.0",
|
||||
"path-temp": "^2.1.0",
|
||||
"rename-overwrite": "^4.0.3",
|
||||
"sanitize-filename": "^1.6.3"
|
||||
},
|
||||
|
||||
@@ -5,7 +5,7 @@ import { globalWarn, logger } from '@pnpm/logger'
|
||||
import rimraf from '@zkochan/rimraf'
|
||||
import sanitizeFilename from 'sanitize-filename'
|
||||
import makeEmptyDir from 'make-empty-dir'
|
||||
import pathTemp from 'path-temp'
|
||||
import { fastPathTemp as pathTemp } from 'path-temp'
|
||||
import renameOverwrite from 'rename-overwrite'
|
||||
|
||||
const filenameConflictsLogger = logger('_filename-conflicts')
|
||||
@@ -20,7 +20,7 @@ export async function importIndexedDir (
|
||||
keepModulesDir?: boolean
|
||||
}
|
||||
) {
|
||||
const stage = pathTemp(path.dirname(newDir))
|
||||
const stage = pathTemp(newDir)
|
||||
try {
|
||||
await tryImportIndexedDir(importFile, stage, filenames)
|
||||
if (opts.keepModulesDir) {
|
||||
|
||||
@@ -19,7 +19,7 @@ jest.mock('@pnpm/graceful-fs', () => {
|
||||
default: fsMock,
|
||||
}
|
||||
})
|
||||
jest.mock('path-temp', () => (dir: string) => path.join(dir, '_tmp'))
|
||||
jest.mock('path-temp', () => ({ fastPathTemp: (file: string) => `${file}_tmp` }))
|
||||
jest.mock('rename-overwrite', () => jest.fn())
|
||||
jest.mock('fs-extra', () => ({
|
||||
copy: jest.fn(),
|
||||
@@ -48,12 +48,12 @@ test('packageImportMethod=auto: clone files by default', async () => {
|
||||
})).toBe('clone')
|
||||
expect(gfs.copyFile).toBeCalledWith(
|
||||
path.join('hash1'),
|
||||
path.join('project', '_tmp', 'package.json'),
|
||||
path.join('project', 'package_tmp', 'package.json'),
|
||||
fs.constants.COPYFILE_FICLONE_FORCE
|
||||
)
|
||||
expect(gfs.copyFile).toBeCalledWith(
|
||||
path.join('hash2'),
|
||||
path.join('project', '_tmp', 'index.js'),
|
||||
path.join('project', 'package_tmp', 'index.js'),
|
||||
fs.constants.COPYFILE_FICLONE_FORCE
|
||||
)
|
||||
})
|
||||
@@ -71,8 +71,8 @@ test('packageImportMethod=auto: link files if cloning fails', async () => {
|
||||
force: false,
|
||||
fromStore: false,
|
||||
})).toBe('hardlink')
|
||||
expect(gfs.link).toBeCalledWith(path.join('hash1'), path.join('project', '_tmp', 'package.json'))
|
||||
expect(gfs.link).toBeCalledWith(path.join('hash2'), path.join('project', '_tmp', 'index.js'))
|
||||
expect(gfs.link).toBeCalledWith(path.join('hash1'), path.join('project', 'package_tmp', 'package.json'))
|
||||
expect(gfs.link).toBeCalledWith(path.join('hash2'), path.join('project', 'package_tmp', 'index.js'))
|
||||
expect(gfs.copyFile).toBeCalled()
|
||||
;(gfs.copyFile as jest.Mock).mockClear()
|
||||
|
||||
@@ -86,8 +86,8 @@ test('packageImportMethod=auto: link files if cloning fails', async () => {
|
||||
fromStore: false,
|
||||
})).toBe('hardlink')
|
||||
expect(gfs.copyFile).not.toBeCalled()
|
||||
expect(gfs.link).toBeCalledWith(path.join('hash1'), path.join('project2', '_tmp', 'package.json'))
|
||||
expect(gfs.link).toBeCalledWith(path.join('hash2'), path.join('project2', '_tmp', 'index.js'))
|
||||
expect(gfs.link).toBeCalledWith(path.join('hash1'), path.join('project2', 'package_tmp', 'package.json'))
|
||||
expect(gfs.link).toBeCalledWith(path.join('hash2'), path.join('project2', 'package_tmp', 'index.js'))
|
||||
})
|
||||
|
||||
test('packageImportMethod=auto: link files if cloning fails and even hard linking fails but not with EXDEV error', async () => {
|
||||
@@ -109,7 +109,7 @@ test('packageImportMethod=auto: link files if cloning fails and even hard linkin
|
||||
force: false,
|
||||
fromStore: false,
|
||||
})).toBe('hardlink')
|
||||
expect(gfs.link).toBeCalledWith(path.join('hash2'), path.join('project', '_tmp', 'index.js'))
|
||||
expect(gfs.link).toBeCalledWith(path.join('hash2'), path.join('project', 'package_tmp', 'index.js'))
|
||||
expect(gfs.link).toBeCalledTimes(2)
|
||||
expect(gfs.copyFile).toBeCalledTimes(1)
|
||||
})
|
||||
@@ -131,7 +131,7 @@ test('packageImportMethod=auto: chooses copying if cloning and hard linking is n
|
||||
force: false,
|
||||
fromStore: false,
|
||||
})).toBe('copy')
|
||||
expect(gfs.copyFile).toBeCalledWith(path.join('hash2'), path.join('project', '_tmp', 'index.js'))
|
||||
expect(gfs.copyFile).toBeCalledWith(path.join('hash2'), path.join('project', 'package_tmp', 'index.js'))
|
||||
expect(gfs.copyFile).toBeCalledTimes(2)
|
||||
})
|
||||
|
||||
@@ -154,8 +154,8 @@ test('packageImportMethod=hardlink: fall back to copying if hardlinking fails',
|
||||
})).toBe('hardlink')
|
||||
expect(gfs.link).toBeCalledTimes(3)
|
||||
expect(gfs.copyFile).toBeCalledTimes(2) // One time the target already exists, so it won't be copied
|
||||
expect(gfs.copyFile).toBeCalledWith(path.join('hash1'), path.join('project', '_tmp', 'package.json'))
|
||||
expect(gfs.copyFile).toBeCalledWith(path.join('hash2'), path.join('project', '_tmp', 'index.js'))
|
||||
expect(gfs.copyFile).toBeCalledWith(path.join('hash1'), path.join('project', 'package_tmp', 'package.json'))
|
||||
expect(gfs.copyFile).toBeCalledWith(path.join('hash2'), path.join('project', 'package_tmp', 'index.js'))
|
||||
})
|
||||
|
||||
test('packageImportMethod=hardlink does not relink package from store if package.json is linked from the store', async () => {
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
"p-limit": "^3.1.0",
|
||||
"p-map-values": "^1.0.0",
|
||||
"p-queue": "^6.6.2",
|
||||
"path-temp": "^2.0.0",
|
||||
"path-temp": "^2.1.0",
|
||||
"promise-share": "^1.0.0",
|
||||
"ramda": "npm:@pnpm/ramda@0.28.1",
|
||||
"rename-overwrite": "^4.0.3",
|
||||
|
||||
@@ -48,7 +48,7 @@ import pMapValues from 'p-map-values'
|
||||
import PQueue from 'p-queue'
|
||||
import loadJsonFile from 'load-json-file'
|
||||
import pDefer from 'p-defer'
|
||||
import pathTemp from 'path-temp'
|
||||
import { fastPathTemp as pathTemp } from 'path-temp'
|
||||
import pShare from 'promise-share'
|
||||
import pick from 'ramda/src/pick'
|
||||
import renameOverwrite from 'rename-overwrite'
|
||||
@@ -656,7 +656,7 @@ async function writeJsonFile (filePath: string, data: unknown) {
|
||||
// There is actually no need to create the directory in 99% of cases.
|
||||
// So by using cafs API, we'll improve performance.
|
||||
await fs.mkdir(targetDir, { recursive: true })
|
||||
const temp = pathTemp(targetDir)
|
||||
const temp = pathTemp(filePath)
|
||||
await gfs.writeFile(temp, JSON.stringify(data))
|
||||
await renameOverwrite(temp, filePath)
|
||||
}
|
||||
|
||||
32
pnpm-lock.yaml
generated
32
pnpm-lock.yaml
generated
@@ -1704,8 +1704,8 @@ importers:
|
||||
specifier: ^4.0.0
|
||||
version: 4.0.0
|
||||
path-temp:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
rename-overwrite:
|
||||
specifier: ^4.0.3
|
||||
version: 4.0.3
|
||||
@@ -3631,8 +3631,8 @@ importers:
|
||||
specifier: ^6.6.2
|
||||
version: 6.6.2
|
||||
path-temp:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
promise-share:
|
||||
specifier: ^1.0.0
|
||||
version: 1.0.0
|
||||
@@ -4945,8 +4945,8 @@ importers:
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0
|
||||
path-temp:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
ramda:
|
||||
specifier: npm:@pnpm/ramda@0.28.1
|
||||
version: /@pnpm/ramda@0.28.1
|
||||
@@ -5495,8 +5495,8 @@ importers:
|
||||
specifier: ^3.1.0
|
||||
version: 3.1.0
|
||||
path-temp:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
rename-overwrite:
|
||||
specifier: ^4.0.3
|
||||
version: 4.0.3
|
||||
@@ -5577,8 +5577,8 @@ importers:
|
||||
specifier: ^8.1.1
|
||||
version: 8.1.1
|
||||
path-temp:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
ramda:
|
||||
specifier: npm:@pnpm/ramda@0.28.1
|
||||
version: /@pnpm/ramda@0.28.1
|
||||
@@ -5965,8 +5965,8 @@ importers:
|
||||
specifier: ^1.0.1
|
||||
version: 1.0.1
|
||||
path-temp:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
root-link-target:
|
||||
specifier: ^3.1.0
|
||||
version: 3.1.0
|
||||
@@ -15167,6 +15167,13 @@ packages:
|
||||
dependencies:
|
||||
unique-string: 2.0.0
|
||||
|
||||
/path-temp@2.1.0:
|
||||
resolution: {integrity: sha512-cMMJTAZlion/RWRRC48UbrDymEIt+/YSD/l8NqjneyDw2rDOBQcP5yRkMB4CYGn47KMhZvbblBP7Z79OsMw72w==}
|
||||
engines: {node: '>=8.15'}
|
||||
dependencies:
|
||||
unique-string: 2.0.0
|
||||
dev: false
|
||||
|
||||
/path-to-regexp@0.1.7:
|
||||
resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==}
|
||||
|
||||
@@ -17979,7 +17986,6 @@ time:
|
||||
/path-absolute@1.0.1: '2018-11-28T20:25:53.253Z'
|
||||
/path-exists@4.0.0: '2019-04-04T03:29:16.887Z'
|
||||
/path-name@1.0.0: '2016-10-20T18:43:50.780Z'
|
||||
/path-temp@2.0.0: '2019-05-04T14:35:52.401Z'
|
||||
/pidtree@0.6.0: '2022-06-05T18:35:44.206Z'
|
||||
/preferred-pm@3.0.3: '2021-02-09T01:16:52.150Z'
|
||||
/pretty-bytes@5.6.0: '2021-02-21T14:04:35.036Z'
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
"p-limit": "^3.1.0",
|
||||
"p-memoize": "4.0.1",
|
||||
"parse-npm-tarball-url": "^3.0.0",
|
||||
"path-temp": "^2.0.0",
|
||||
"path-temp": "^2.1.0",
|
||||
"ramda": "npm:@pnpm/ramda@0.28.1",
|
||||
"rename-overwrite": "^4.0.3",
|
||||
"semver": "^7.5.4",
|
||||
|
||||
@@ -9,7 +9,7 @@ import { type PackageManifest } from '@pnpm/types'
|
||||
import getRegistryName from 'encode-registry'
|
||||
import loadJsonFile from 'load-json-file'
|
||||
import pLimit from 'p-limit'
|
||||
import pathTemp from 'path-temp'
|
||||
import { fastPathTemp as pathTemp } from 'path-temp'
|
||||
import pick from 'ramda/src/pick'
|
||||
import renameOverwrite from 'rename-overwrite'
|
||||
import { toRaw } from './toRaw'
|
||||
@@ -272,7 +272,7 @@ async function saveMeta (pkgMirror: string, meta: PackageMeta): Promise<void> {
|
||||
await fs.mkdir(dir, { recursive: true })
|
||||
createdDirs.add(dir)
|
||||
}
|
||||
const temp = pathTemp(dir)
|
||||
const temp = pathTemp(pkgMirror)
|
||||
await gfs.writeFile(temp, JSON.stringify(meta))
|
||||
await renameOverwrite(temp, pkgMirror)
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"get-stream": "^6.0.1",
|
||||
"gunzip-maybe": "1.4.2",
|
||||
"p-limit": "^3.1.0",
|
||||
"path-temp": "^2.0.0",
|
||||
"path-temp": "^2.1.0",
|
||||
"rename-overwrite": "^4.0.3",
|
||||
"safe-promise-defer": "^1.0.1",
|
||||
"ssri": "10.0.4",
|
||||
|
||||
@@ -2,7 +2,7 @@ import { promises as fs, type Stats } from 'fs'
|
||||
import path from 'path'
|
||||
import type { FileWriteResult, PackageFileInfo } from '@pnpm/cafs-types'
|
||||
import getStream from 'get-stream'
|
||||
import pathTemp from 'path-temp'
|
||||
import { fastPathTemp as pathTemp } from 'path-temp'
|
||||
import renameOverwrite from 'rename-overwrite'
|
||||
import ssri from 'ssri'
|
||||
import { addFilesFromDir } from './addFilesFromDir'
|
||||
@@ -108,7 +108,7 @@ async function writeBufferToCafs (
|
||||
//
|
||||
// If we don't allow --no-verify-store-integrity then we probably can write
|
||||
// to the final file directly.
|
||||
const temp = pathTemp(path.dirname(fileDest))
|
||||
const temp = pathTemp(fileDest)
|
||||
await writeFile(temp, buffer, mode)
|
||||
// Unfortunately, "birth time" (time of file creation) is available not on all filesystems.
|
||||
// We log the creation time ourselves and save it in the package index file.
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"@pnpm/fs.indexed-pkg-importer": "workspace:*",
|
||||
"@pnpm/store-controller-types": "workspace:*",
|
||||
"mem": "^8.1.1",
|
||||
"path-temp": "^2.0.0",
|
||||
"path-temp": "^2.1.0",
|
||||
"ramda": "npm:@pnpm/ramda@0.28.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
"@zkochan/rimraf": "^2.1.2",
|
||||
"can-link": "^2.0.0",
|
||||
"path-absolute": "^1.0.1",
|
||||
"path-temp": "^2.0.0",
|
||||
"path-temp": "^2.1.0",
|
||||
"root-link-target": "^3.1.0",
|
||||
"touch": "3.1.0"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user