From fa4f9133b04ef39b32e0617916996ae4e4736e8c Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Thu, 10 Feb 2022 00:13:28 +0200 Subject: [PATCH] fix(package-store): don't print info message about relinking pkgs (#4316) close #4314 --- .changeset/good-kings-change.md | 8 ++++ package.json | 1 + .../storeController/createImportPackage.ts | 20 +++++---- .../test/createImportPackage.spec.ts | 32 ++++++++++++++ pnpm-lock.yaml | 43 ++++++++----------- 5 files changed, 72 insertions(+), 32 deletions(-) create mode 100644 .changeset/good-kings-change.md diff --git a/.changeset/good-kings-change.md b/.changeset/good-kings-change.md new file mode 100644 index 0000000000..4bedfe7873 --- /dev/null +++ b/.changeset/good-kings-change.md @@ -0,0 +1,8 @@ +--- +"@pnpm/package-store": patch +"pnpm": patch +--- + +This fixes an issue introduced in pnpm v6.30.0. + +When a package is not linked to `node_modules`, no info message should be printed about it being "relinked" from the store [#4314](https://github.com/pnpm/pnpm/issues/4314). diff --git a/package.json b/package.json index 654f1fffde..a57da53702 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "overrides": { "@yarnpkg/core": "3.2.0-rc.9", "ansi-regex@<5": "^5.0.1", + "clipanion": "3.2.0-rc.6", "glob-parent@3": "^5.1.2", "hosted-git-info@<3.0.8": "^3.0.8", "hosted-git-info@4": "npm:@zkochan/hosted-git-info@^4.0.2", diff --git a/packages/package-store/src/storeController/createImportPackage.ts b/packages/package-store/src/storeController/createImportPackage.ts index 65feb7f320..8814c51fd7 100644 --- a/packages/package-store/src/storeController/createImportPackage.ts +++ b/packages/package-store/src/storeController/createImportPackage.ts @@ -8,8 +8,10 @@ import importIndexedDir, { ImportFile } from '../fs/importIndexedDir' const limitLinking = pLimit(16) +type FilesMap = Record + interface ImportOptions { - filesMap: Record + filesMap: FilesMap force: boolean fromStore: boolean } @@ -133,32 +135,34 @@ async function linkOrCopy (existingPath: string, newPath: string) { } async function pkgLinkedToStore ( - filesMap: Record, + filesMap: FilesMap, to: string ) { if (filesMap['package.json']) { - if (await isSameFile(path.join(to, 'package.json'), filesMap['package.json'])) { + if (await isSameFile('package.json', to, filesMap)) { return true } } else { // An injected package might not have a package.json. // This will probably only even happen in a Bit workspace. const [anyFile] = Object.keys(filesMap) - if (await isSameFile(path.join(to, anyFile), filesMap[anyFile])) return true + if (await isSameFile(anyFile, to, filesMap)) return true } - globalInfo(`Relinking ${to} from the store`) return false } -async function isSameFile (linkedFile: string, fileFromStore: string) { +async function isSameFile (filename: string, linkedPkgDir: string, filesMap: FilesMap) { + const linkedFile = path.join(linkedPkgDir, filename) let stats0!: Stats try { stats0 = await fs.stat(linkedFile) } catch (err: any) { // eslint-disable-line if (err.code === 'ENOENT') return false } - const stats1 = await fs.stat(fileFromStore) - return stats0.ino === stats1.ino + const stats1 = await fs.stat(filesMap[filename]) + if (stats0.ino === stats1.ino) return true + globalInfo(`Relinking ${linkedPkgDir} from the store`) + return false } export async function copyPkg ( diff --git a/packages/package-store/test/createImportPackage.spec.ts b/packages/package-store/test/createImportPackage.spec.ts index 272a00efd4..5b8f8a5616 100644 --- a/packages/package-store/test/createImportPackage.spec.ts +++ b/packages/package-store/test/createImportPackage.spec.ts @@ -11,6 +11,12 @@ jest.mock('fs', () => { }) jest.mock('path-temp', () => (dir: string) => path.join(dir, '_tmp')) jest.mock('rename-overwrite', () => jest.fn()) +const globalInfo = jest.fn() +const globalWarn = jest.fn() +const baseLogger = jest.fn(() => ({ debug: jest.fn() })) +baseLogger['globalInfo'] = globalInfo +baseLogger['globalWarn'] = globalWarn +jest.mock('@pnpm/logger', () => baseLogger) // eslint-disable-next-line import createImportPackage from '@pnpm/package-store/lib/storeController/createImportPackage' @@ -162,6 +168,7 @@ test('packageImportMethod=hardlink does not relink package from store if package }) test('packageImportMethod=hardlink relinks package from store if package.json is not linked from the store', async () => { + globalInfo.mockReset() const importPackage = createImportPackage('hardlink') fsMock.promises.copyFile = jest.fn() fsMock.promises.rename = jest.fn() @@ -175,6 +182,7 @@ test('packageImportMethod=hardlink relinks package from store if package.json is force: false, fromStore: true, })).toBe('hardlink') + expect(globalInfo).toBeCalledWith('Relinking project/package from the store') }) test('packageImportMethod=hardlink does not relink package from store if package.json is not present in the store', async () => { @@ -193,3 +201,27 @@ test('packageImportMethod=hardlink does not relink package from store if package fromStore: true, })).toBe(undefined) }) + +test('packageImportMethod=hardlink links packages when they are not found', async () => { + globalInfo.mockReset() + const importPackage = createImportPackage('hardlink') + fsMock.promises.copyFile = jest.fn() + fsMock.promises.rename = jest.fn() + fsMock.promises.stat = jest.fn((file) => { + if (file === path.join('project/package', 'package.json')) { + const err = new Error() + err['code'] = 'ENOENT' + throw err + } + return { ino: 0 } + }) + expect(await importPackage('project/package', { + filesMap: { + 'index.js': 'hash2', + 'package.json': 'hash1', + }, + force: false, + fromStore: true, + })).toBe('hardlink') + expect(globalInfo).not.toBeCalledWith('Relinking project/package from the store') +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6b9f82c96d..487b2b6150 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,6 +7,7 @@ neverBuiltDependencies: overrides: '@yarnpkg/core': 3.2.0-rc.9 ansi-regex@<5: ^5.0.1 + clipanion: 3.2.0-rc.6 glob-parent@3: ^5.1.2 hosted-git-info@<3.0.8: ^3.0.8 hosted-git-info@4: npm:@zkochan/hosted-git-info@^4.0.2 @@ -5795,7 +5796,7 @@ packages: camelcase: 5.3.1 chalk: 3.0.0 ci-info: 3.3.0 - clipanion: 3.2.0-rc.8 + clipanion: 3.2.0-rc.6 cross-spawn: 7.0.3 diff: 4.0.2 globby: 11.1.0 @@ -5911,7 +5912,7 @@ packages: '@yarnpkg/fslib': 2.6.1-rc.9 '@yarnpkg/parsers': 2.5.0-rc.12 chalk: 3.0.0 - clipanion: 3.2.0-rc.8 + clipanion: 3.2.0-rc.6 cross-spawn: 7.0.3 fast-glob: 3.2.11 micromatch: 4.0.4 @@ -5927,7 +5928,7 @@ packages: '@yarnpkg/fslib': 2.6.1-rc.9 '@yarnpkg/parsers': 2.5.0-rc.12 chalk: 3.0.0 - clipanion: 3.2.0-rc.8 + clipanion: 3.2.0-rc.6 cross-spawn: 7.0.3 fast-glob: 3.2.11 micromatch: 4.0.4 @@ -6279,9 +6280,9 @@ packages: delegates: 1.0.0 readable-stream: 2.3.7 - /are-we-there-yet/2.0.0: - resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} - engines: {node: '>=10'} + /are-we-there-yet/3.0.0: + resolution: {integrity: sha512-0GWpv50YSOcLXaN6/FAKY3vfRbllXWV2xvfA/oKJF8pzFhWXPV+yjhJXDBbjscDYowv7Yw1A3uigpzn5iEGTyw==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16} dependencies: delegates: 1.0.0 readable-stream: 3.6.0 @@ -6662,7 +6663,7 @@ packages: hasBin: true dependencies: caniuse-lite: 1.0.30001310 - electron-to-chromium: 1.4.67 + electron-to-chromium: 1.4.68 escalade: 3.1.1 node-releases: 2.0.2 picocolors: 1.0.0 @@ -6971,17 +6972,11 @@ packages: resolution: {integrity: sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==} dev: true - /clipanion/3.1.0: - resolution: {integrity: sha512-v025Hz+IDQ15FpOyK8p02h5bFznMu6rLFsJSyOPR+7WrbSnZ1Ek6pblPukV7K5tC/dsWfncQPIrJ4iUy2PXkbw==} + /clipanion/3.2.0-rc.6: + resolution: {integrity: sha512-lcByFNxi1L/sskjD/YybFZI43bnkm/AuUNFcF5i5Znz6nvWCH9gfq4qkNmAk5MhS/MPY5Im8jiqYH54h23Vc7Q==} dependencies: typanion: 3.7.1 - /clipanion/3.2.0-rc.8: - resolution: {integrity: sha512-GiVWNN3kESWEe+KumOUF/chLclLP3xdJ5PkIRmAxZr5k8Mff3DXs2F536VMc+llnpW88PGGMxqwQcIwXdE/pfA==} - dependencies: - typanion: 3.7.1 - dev: false - /cliui/6.0.0: resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} dependencies: @@ -7806,8 +7801,8 @@ packages: /ee-first/1.1.1: resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=} - /electron-to-chromium/1.4.67: - resolution: {integrity: sha512-A6a2jEPLueEDfb7kvh7/E94RKKnIb01qL+4I7RFxtajmo+G9F5Ei7HgY5PRbQ4RDrh6DGDW66P0hD5XI2nRAcg==} + /electron-to-chromium/1.4.68: + resolution: {integrity: sha512-cId+QwWrV8R1UawO6b9BR1hnkJ4EJPCPAr4h315vliHUtVUJDk39Sg1PMNnaWKfj5x+93ssjeJ9LKL6r8LaMiA==} dev: true /emittery/0.8.1: @@ -8312,7 +8307,7 @@ packages: resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} peerDependencies: - eslint: '>=5 || *' + eslint: '>=5 || * || *' dependencies: eslint: 8.8.0 eslint-visitor-keys: 2.1.0 @@ -11630,7 +11625,7 @@ packages: graceful-fs: 4.2.9 make-fetch-happen: 9.1.0 nopt: /@pnpm/nopt/0.2.1 - npmlog: 6.0.0 + npmlog: 6.0.1 rimraf: 3.0.2 semver: 7.3.5 tar: 6.1.11 @@ -11773,11 +11768,11 @@ packages: gauge: 2.7.4 set-blocking: 2.0.0 - /npmlog/6.0.0: - resolution: {integrity: sha512-03ppFRGlsyUaQFbGC2C8QWJN/C/K7PsfyD9aQdhVKAQIH4sQBc8WASqFBP7O+Ut4d2oo5LoeoboB3cGdBZSp6Q==} + /npmlog/6.0.1: + resolution: {integrity: sha512-BTHDvY6nrRHuRfyjt1MAufLxYdVXZfd099H4+i1f0lPywNQyI4foeNXJRObB/uy+TYqUW0vAD9gbdSOXPst7Eg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16} dependencies: - are-we-there-yet: 2.0.0 + are-we-there-yet: 3.0.0 console-control-strings: 1.1.0 gauge: 4.0.0 set-blocking: 2.0.0 @@ -14628,7 +14623,7 @@ packages: '@verdaccio/ui-theme': 6.0.0-6-next.15 async: 3.2.3 body-parser: 1.19.1 - clipanion: 3.1.0 + clipanion: 3.2.0-rc.6 compression: 1.7.4 cookies: 0.8.0 cors: 2.8.5 @@ -14683,7 +14678,7 @@ packages: '@verdaccio/ui-theme': 6.0.0-6-next.16 async: 3.2.3 body-parser: 1.19.1 - clipanion: 3.1.0 + clipanion: 3.2.0-rc.6 compression: 1.7.4 cookies: 0.8.0 cors: 2.8.5