Skip to content

Commit

Permalink
fix(package-store): don't print info message about relinking pkgs
Browse files Browse the repository at this point in the history
close #4314
  • Loading branch information
zkochan committed Feb 9, 2022
1 parent 01a3bfb commit 36d0331
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 32 deletions.
8 changes: 8 additions & 0 deletions .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).
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -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",
Expand Down
20 changes: 12 additions & 8 deletions packages/package-store/src/storeController/createImportPackage.ts
Expand Up @@ -8,8 +8,10 @@ import importIndexedDir, { ImportFile } from '../fs/importIndexedDir'

const limitLinking = pLimit(16)

type FilesMap = Record<string, string>

interface ImportOptions {
filesMap: Record<string, string>
filesMap: FilesMap
force: boolean
fromStore: boolean
}
Expand Down Expand Up @@ -133,32 +135,34 @@ async function linkOrCopy (existingPath: string, newPath: string) {
}

async function pkgLinkedToStore (
filesMap: Record<string, string>,
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 (
Expand Down
32 changes: 32 additions & 0 deletions packages/package-store/test/createImportPackage.spec.ts
Expand Up @@ -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'
Expand Down Expand Up @@ -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()
Expand All @@ -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 () => {
Expand All @@ -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')
})
43 changes: 19 additions & 24 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 36d0331

Please sign in to comment.