Skip to content

Commit

Permalink
fix(hard-link-dir): prevent fatal error on ENOENT (#6396)
Browse files Browse the repository at this point in the history
Co-authored-by: Zoltan Kochan <z@kochan.io>
  • Loading branch information
nVitius and zkochan committed Apr 14, 2023
1 parent 7a9cea4 commit e0de784
Show file tree
Hide file tree
Showing 5 changed files with 341 additions and 397 deletions.
6 changes: 6 additions & 0 deletions .changeset/fuzzy-parents-juggle.md
@@ -0,0 +1,6 @@
---
"@pnpm/fs.hard-link-dir": patch
"pnpm": patch
---

Warn user when `publishConfig.directory` of an injected workspace dependency does not exist [#6396](https://github.com/pnpm/pnpm/pull/6396).
3 changes: 3 additions & 0 deletions fs/hard-link-dir/package.json
Expand Up @@ -30,6 +30,9 @@
},
"homepage": "https://github.com/pnpm/pnpm/blob/main/fs/hard-link-dir#readme",
"funding": "https://opencollective.com/pnpm",
"peerDependencies": {
"@pnpm/logger": "^5.0.0"
},
"devDependencies": {
"@pnpm/fs.hard-link-dir": "workspace:*",
"@pnpm/prepare": "workspace:*"
Expand Down
19 changes: 17 additions & 2 deletions fs/hard-link-dir/src/index.ts
@@ -1,11 +1,26 @@
import path from 'path'
import { promises as fs } from 'fs'
import { globalWarn } from '@pnpm/logger'

export async function hardLinkDir (src: string, destDirs: string[]) {
if (destDirs.length === 0) return
// Don't try to hard link the source directory to itself
destDirs = destDirs.filter((destDir) => path.relative(destDir, src) !== '')
const files = await fs.readdir(src)
await _hardLinkDir(src, destDirs, true)
}

async function _hardLinkDir (src: string, destDirs: string[], isRoot?: boolean) {
let files: string[] = []
try {
files = await fs.readdir(src)
} catch (err: any) { // eslint-disable-line
if (!isRoot || err.code !== 'ENOENT') throw err
globalWarn(`Source directory not found when creating hardLinks for: ${src}. Creating destinations as empty: ${destDirs.join(', ')}`)
await Promise.all(
destDirs.map((dir) => fs.mkdir(dir, { recursive: true }))
)
return
}
await Promise.all(
files.map(async (file) => {
if (file === 'node_modules') return
Expand All @@ -22,7 +37,7 @@ export async function hardLinkDir (src: string, destDirs: string[]) {
return destSubdir
})
)
await hardLinkDir(srcFile, destSubdirs)
await _hardLinkDir(srcFile, destSubdirs)
return
}
await Promise.all(
Expand Down
12 changes: 12 additions & 0 deletions fs/hard-link-dir/test/index.ts
Expand Up @@ -32,3 +32,15 @@ test('hardLinkDirectory()', async () => {
expect(fs.existsSync(path.join(dest1Dir, 'node_modules/file.txt'))).toBe(false)
expect(fs.existsSync(path.join(dest2Dir, 'node_modules/file.txt'))).toBe(false)
})

test("don't fail on missing source and dest directories", async () => {
const tempDir = createTempDir()
const missingDirSrc = path.join(tempDir, 'missing_source')
const missingDirDest = path.join(tempDir, 'missing_dest')

await hardLinkDir(missingDirSrc, [missingDirDest])

// It should create an empty dest dir if src does not exist
expect(fs.existsSync(missingDirSrc)).toBe(false)
expect(fs.existsSync(missingDirDest)).toBe(true)
})

0 comments on commit e0de784

Please sign in to comment.