mirror of
https://github.com/pnpm/pnpm.git
synced 2026-01-11 00:18:32 -05:00
feat: reduce directory nesting in virtual store directory (#3117)
ref #3115
This commit is contained in:
5
.changeset/real-feet-grow.md
Normal file
5
.changeset/real-feet-grow.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/constants": major
|
||||
---
|
||||
|
||||
Bump layout version to 5.
|
||||
6
.changeset/rich-spiders-fail.md
Normal file
6
.changeset/rich-spiders-fail.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"dependency-path": major
|
||||
"pnpm": major
|
||||
---
|
||||
|
||||
All packages inside the virtual store directory should be on the same depth. Instead of subdirectories, one directory is used with # instead of slashes.
|
||||
@@ -2,6 +2,6 @@ export const WANTED_LOCKFILE = 'pnpm-lock.yaml'
|
||||
export const LOCKFILE_VERSION = 5.2
|
||||
|
||||
export const ENGINE_NAME = `${process.platform}-${process.arch}-node-${process.version.split('.')[0]}`
|
||||
export const LAYOUT_VERSION = 4
|
||||
export const LAYOUT_VERSION = 5
|
||||
|
||||
export const WORKSPACE_MANIFEST_FILENAME = 'pnpm-workspace.yaml'
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Registries } from '@pnpm/types'
|
||||
import crypto = require('crypto')
|
||||
import encodeRegistry = require('encode-registry')
|
||||
import normalize = require('normalize-path')
|
||||
import path = require('path')
|
||||
@@ -130,6 +131,14 @@ export function parse (dependencyPath: string) {
|
||||
}
|
||||
|
||||
export function depPathToFilename (depPath: string, lockfileDir: string) {
|
||||
const filename = depPathToFilenameUnescaped(depPath, lockfileDir).replace(/\//g, '#')
|
||||
if (filename.length > 120) {
|
||||
return `${filename.substring(0, 50)}_${crypto.createHash('md5').update(filename).digest('hex')}`
|
||||
}
|
||||
return filename
|
||||
}
|
||||
|
||||
function depPathToFilenameUnescaped (depPath: string, lockfileDir: string) {
|
||||
if (depPath.indexOf('file:') !== 0) {
|
||||
if (depPath.startsWith('/')) {
|
||||
depPath = depPath.substring(1)
|
||||
@@ -139,6 +148,5 @@ export function depPathToFilename (depPath: string, lockfileDir: string) {
|
||||
}
|
||||
|
||||
const absolutePath = normalize(path.join(lockfileDir, depPath.slice(5)))
|
||||
const lastSlash = absolutePath.lastIndexOf('/')
|
||||
return `local/${encodeURIComponent(absolutePath.substr(0, lastSlash + 1))}${absolutePath.substr(lastSlash + 1)}`
|
||||
return `local#${absolutePath}`
|
||||
}
|
||||
|
||||
@@ -120,9 +120,11 @@ test('resolve()', () => {
|
||||
|
||||
test('depPathToFilename()', () => {
|
||||
expect(depPathToFilename('/foo/1.0.0', process.cwd())).toBe('foo@1.0.0')
|
||||
expect(depPathToFilename('/@foo/bar/1.0.0', process.cwd())).toBe('@foo/bar@1.0.0')
|
||||
expect(depPathToFilename('github.com/something/foo/0000', process.cwd())).toBe('github.com/something/foo@0000')
|
||||
expect(depPathToFilename('/@foo/bar/1.0.0', process.cwd())).toBe('@foo#bar@1.0.0')
|
||||
expect(depPathToFilename('github.com/something/foo/0000', process.cwd())).toBe('github.com#something#foo@0000')
|
||||
|
||||
const filename = depPathToFilename('file:./test/foo-1.0.0.tgz_foo@2.0.0', process.cwd())
|
||||
expect(filename).toMatch(/%2Ffoo-1.0.0.tgz_foo@2.0.0$/)
|
||||
expect(filename).toMatch(/^local#.*#foo-1\.0\.0\.tgz_foo@2\.0\.0$/)
|
||||
|
||||
expect(depPathToFilename('abcd/'.repeat(200), process.cwd())).toBe('abcd#abcd#abcd#abcd#abcd#abcd#abcd#abcd#abcd#abcd#_36cae148b21d1f0b46577e42f8f4dbae')
|
||||
})
|
||||
|
||||
@@ -5,28 +5,23 @@ Object {
|
||||
"entries": Object {
|
||||
".pnpm": Object {
|
||||
"entries": Object {
|
||||
"@zkochan": Object {
|
||||
"@zkochan#git-config@0.1.0": Object {
|
||||
"entries": Object {
|
||||
"git-config@0.1.0": Object {
|
||||
"node_modules": Object {
|
||||
"entries": Object {
|
||||
"node_modules": Object {
|
||||
"@zkochan": Object {
|
||||
"entries": Object {
|
||||
"@zkochan": Object {
|
||||
"entries": Object {
|
||||
"git-config": Object {
|
||||
"depPath": "/@zkochan/git-config/0.1.0",
|
||||
"entryType": "index",
|
||||
},
|
||||
},
|
||||
"entryType": "directory",
|
||||
},
|
||||
"ini": Object {
|
||||
"entryType": "symlink",
|
||||
"target": "../../../ini@1.3.8/node_modules/ini",
|
||||
"git-config": Object {
|
||||
"depPath": "/@zkochan/git-config/0.1.0",
|
||||
"entryType": "index",
|
||||
},
|
||||
},
|
||||
"entryType": "directory",
|
||||
},
|
||||
"ini": Object {
|
||||
"entryType": "symlink",
|
||||
"target": "../../ini@1.3.8/node_modules/ini",
|
||||
},
|
||||
},
|
||||
"entryType": "directory",
|
||||
},
|
||||
@@ -68,7 +63,7 @@ Object {
|
||||
"entries": Object {
|
||||
"git-config": Object {
|
||||
"entryType": "symlink",
|
||||
"target": "./.pnpm/@zkochan/git-config@0.1.0/node_modules/@zkochan/git-config",
|
||||
"target": "./.pnpm/@zkochan#git-config@0.1.0/node_modules/@zkochan/git-config",
|
||||
},
|
||||
},
|
||||
"entryType": "directory",
|
||||
|
||||
@@ -26,7 +26,7 @@ describe('FUSE handlers', () => {
|
||||
handlers.readdir('/.pnpm', (returnCode, files) => {
|
||||
expect(returnCode).toBe(0)
|
||||
expect(files!.sort()).toStrictEqual([
|
||||
'@zkochan',
|
||||
'@zkochan#git-config@0.1.0',
|
||||
'ini@1.3.8',
|
||||
'is-positive@1.0.0',
|
||||
].sort())
|
||||
@@ -39,11 +39,11 @@ describe('FUSE handlers', () => {
|
||||
expect(returnCode).toBe(0)
|
||||
expect(files).toStrictEqual(['is-positive'])
|
||||
})
|
||||
handlers.readdir('/.pnpm/@zkochan/git-config@0.1.0/node_modules/@zkochan', (returnCode, files) => {
|
||||
handlers.readdir('/.pnpm/@zkochan#git-config@0.1.0/node_modules/@zkochan', (returnCode, files) => {
|
||||
expect(returnCode).toBe(0)
|
||||
expect(files).toStrictEqual(['git-config'])
|
||||
})
|
||||
handlers.readdir('/.pnpm/@zkochan/git-config@0.1.0/node_modules/@zkochan/git-config', (returnCode, files) => {
|
||||
handlers.readdir('/.pnpm/@zkochan#git-config@0.1.0/node_modules/@zkochan/git-config', (returnCode, files) => {
|
||||
expect(returnCode).toBe(0)
|
||||
expect(files!.sort()).toStrictEqual([
|
||||
'package.json',
|
||||
@@ -57,14 +57,14 @@ describe('FUSE handlers', () => {
|
||||
'index.js',
|
||||
].sort())
|
||||
})
|
||||
handlers.readdir('/.pnpm/@zkochan/git-config@0.1.0/node_modules/@zkochan/git-config/test', (returnCode, files) => {
|
||||
handlers.readdir('/.pnpm/@zkochan#git-config@0.1.0/node_modules/@zkochan/git-config/test', (returnCode, files) => {
|
||||
expect(returnCode).toBe(0)
|
||||
expect(files!.sort()).toStrictEqual([
|
||||
'index.js',
|
||||
'fixtures',
|
||||
].sort())
|
||||
})
|
||||
handlers.readdir('/.pnpm/@zkochan/git-config@0.1.0/node_modules/@zkochan/git-config/does-not-exist', (returnCode, files) => {
|
||||
handlers.readdir('/.pnpm/@zkochan#git-config@0.1.0/node_modules/@zkochan/git-config/does-not-exist', (returnCode, files) => {
|
||||
expect(returnCode).toBe(Fuse.ENOENT)
|
||||
})
|
||||
handlers.readdir('/.pnpm/is-positive@1.0.0/node_modules/is-positive', (returnCode, files) => {
|
||||
@@ -76,20 +76,20 @@ describe('FUSE handlers', () => {
|
||||
'readme.md',
|
||||
].sort())
|
||||
})
|
||||
handlers.readdir('/.pnpm/@zkochan/git-config@0.1.0/node_modules/@types', (returnCode) => {
|
||||
handlers.readdir('/.pnpm/@zkochan#git-config@0.1.0/node_modules/@types', (returnCode) => {
|
||||
expect(returnCode).toBe(Fuse.ENOENT)
|
||||
})
|
||||
})
|
||||
it('getattr', () => {
|
||||
handlers.getattr('/.pnpm/@zkochan/git-config@0.1.0/node_modules/@zkochan/git-config/index.js', (returnCode, stat) => {
|
||||
handlers.getattr('/.pnpm/@zkochan#git-config@0.1.0/node_modules/@zkochan/git-config/index.js', (returnCode, stat) => {
|
||||
expect(returnCode).toBe(0)
|
||||
expect(stat.mode).toBe(33188)
|
||||
})
|
||||
handlers.getattr('/.pnpm/@zkochan/git-config@0.1.0/node_modules/@zkochan/git-config/test/fixtures', (returnCode, stat) => {
|
||||
handlers.getattr('/.pnpm/@zkochan#git-config@0.1.0/node_modules/@zkochan/git-config/test/fixtures', (returnCode, stat) => {
|
||||
expect(returnCode).toBe(0)
|
||||
expect(stat.mode).toBe(16877)
|
||||
})
|
||||
handlers.getattr('/.pnpm/@zkochan/git-config@0.1.0/node_modules/@zkochan/git-config/index.jsx', (returnCode, stat) => {
|
||||
handlers.getattr('/.pnpm/@zkochan#git-config@0.1.0/node_modules/@zkochan/git-config/index.jsx', (returnCode, stat) => {
|
||||
expect(returnCode).toBe(Fuse.ENOENT)
|
||||
})
|
||||
handlers.getattr('/.pnpm/is-positive@1.0.0/node_modules/is-positive/package.json', (returnCode, stat) => {
|
||||
@@ -98,7 +98,7 @@ describe('FUSE handlers', () => {
|
||||
})
|
||||
})
|
||||
it('open and read', (done) => {
|
||||
const p = '/.pnpm/@zkochan/git-config@0.1.0/node_modules/@zkochan/git-config/index.js'
|
||||
const p = '/.pnpm/@zkochan#git-config@0.1.0/node_modules/@zkochan/git-config/index.js'
|
||||
handlers.open(p, 0, (exitCode, fd) => {
|
||||
expect(exitCode).toBe(0)
|
||||
expect(fd && fd > 0).toBeTruthy()
|
||||
|
||||
@@ -250,7 +250,6 @@ test('top peer dependency is linked on subsequent install', async () => {
|
||||
|
||||
test('top peer dependency is linked on subsequent install. Reverse order', async () => {
|
||||
prepareEmpty()
|
||||
console.log(process.cwd())
|
||||
|
||||
const manifest = await addDependenciesToPackage({}, ['abc-parent-with-ab@1.0.0'], await testDefaults())
|
||||
|
||||
@@ -364,7 +363,7 @@ test('scoped peer dependency is linked', async () => {
|
||||
prepareEmpty()
|
||||
await addDependenciesToPackage({}, ['for-testing-scoped-peers'], await testDefaults())
|
||||
|
||||
const pkgVariation = path.resolve('node_modules/.pnpm/@having/scoped-peer@1.0.0_@scoped+peer@1.0.0/node_modules')
|
||||
const pkgVariation = path.resolve('node_modules/.pnpm/@having#scoped-peer@1.0.0_@scoped+peer@1.0.0/node_modules')
|
||||
await okFile(path.join(pkgVariation, '@having', 'scoped-peer'))
|
||||
await okFile(path.join(pkgVariation, '@scoped', 'peer'))
|
||||
})
|
||||
@@ -851,10 +850,10 @@ test('local tarball dependency with peer dependency', async () => {
|
||||
'foo@100.0.0',
|
||||
], await testDefaults({ reporter }))
|
||||
|
||||
const localPkgDirs = await fs.readdir('node_modules/.pnpm/local')
|
||||
const integrityLocalPkgDirs = (await fs.readdir('node_modules/.pnpm'))
|
||||
.filter((dir) => dir.startsWith('local#'))
|
||||
|
||||
expect(localPkgDirs.length).toBe(1)
|
||||
expect(localPkgDirs[0].endsWith('_bar@100.0.0+foo@100.0.0')).toBeTruthy()
|
||||
expect(integrityLocalPkgDirs.length).toBe(1)
|
||||
|
||||
await rimraf('node_modules')
|
||||
|
||||
@@ -867,7 +866,11 @@ test('local tarball dependency with peer dependency', async () => {
|
||||
},
|
||||
], await testDefaults())
|
||||
|
||||
expect(await fs.readdir('node_modules/.pnpm/local')).toStrictEqual(localPkgDirs)
|
||||
{
|
||||
const updatedLocalPkgDirs = (await fs.readdir('node_modules/.pnpm'))
|
||||
.filter((dir) => dir.startsWith('local#'))
|
||||
expect(updatedLocalPkgDirs).toStrictEqual(integrityLocalPkgDirs)
|
||||
}
|
||||
})
|
||||
|
||||
test('peer dependency that is resolved by a dev dependency', async () => {
|
||||
|
||||
Reference in New Issue
Block a user