Skip to content

Instantly share code, notes, and snippets.

@aleclarson
Created October 18, 2024 18:47
Show Gist options
  • Save aleclarson/998eef1ec6341d5535f577b136dcea4f to your computer and use it in GitHub Desktop.
Save aleclarson/998eef1ec6341d5535f577b136dcea4f to your computer and use it in GitHub Desktop.
import { vol } from 'memfs'
import vfs from 'node:fs'
import path from 'node:path'
import { isMatch } from 'picomatch'
const fixturesDir = new URL('__fixtures__', import.meta.url).pathname
const nodeModulesDir = path.join(fixturesDir, 'node_modules')
const fromNodeModulesDir = new URL('../../node_modules', import.meta.url)
.pathname
const fs = await vi.importActual<typeof vfs>('node:fs')
const nodeModulesFilter = (file: string) =>
/\/(@alien-rpc|@types\/node|undici-types)\//.test(file)
vol.fromJSON(
recursiveRead(path.join(fromNodeModulesDir, '.pnpm'), {
filter: nodeModulesFilter,
fs,
}),
path.join(nodeModulesDir, '.pnpm')
)
const packageLinks = findPackageLinks(fromNodeModulesDir, {
filter: nodeModulesFilter,
fs,
})
for (const file of packageLinks) {
const target = fs.readlinkSync(path.join(fromNodeModulesDir, file))
console.log(file, '→', target)
const newFile = path.join(nodeModulesDir, file)
vfs.mkdirSync(path.dirname(newFile), {
recursive: true,
})
vfs.symlinkSync(target, newFile)
}
console.log(Object.keys(vol.toJSON()).join('\n'))
function findPackageLinks(
dir: string,
opts: {
links?: string[]
root?: string
fs?: typeof fs
recursive?: boolean
filter?: (file: string) => boolean
} = {}
) {
const {
links = [],
root = dir,
fs = vfs,
recursive = true,
filter = () => true,
} = opts
const recursiveOptions = {
links,
root,
fs,
recursive: false,
filter,
}
for (const name of fs.readdirSync(dir)) {
const file = path.join(dir, name)
const stat = fs.lstatSync(file)
if (stat.isSymbolicLink()) {
if (filter(file)) {
links.push(path.relative(root, file))
}
}
// Recurse into “package scope” directories.
else if (recursive && name[0] === '@' && stat.isDirectory()) {
findPackageLinks(file, recursiveOptions)
}
}
return links
}
function recursiveRead(
dir: string,
opts: {
files?: Record<string, string>
root?: string
fs?: typeof fs
filter?: (file: string) => boolean
dot?: boolean
ignored?: string[]
ignoreSymlinks?: boolean
} = {}
): Record<string, string> {
const {
files = {},
root = dir,
fs = vfs,
filter = () => true,
dot = false,
ignored = [],
ignoreSymlinks = false,
} = opts
const recursiveOptions = {
files,
root,
fs,
filter,
dot,
ignored,
ignoreSymlinks,
}
for (const name of fs.readdirSync(dir)) {
if (!dot && name === '.') {
continue
}
const file = path.join(dir, name)
if (isMatch(file, ignored)) {
continue
}
if (ignoreSymlinks && fs.lstatSync(file).isSymbolicLink()) {
continue
}
const stat = fs.statSync(file)
if (stat.isDirectory()) {
recursiveRead(file, recursiveOptions)
} else if (filter(file)) {
const key = path.relative(root, file)
files[key] = fs.readFileSync(file, 'utf8')
}
}
return files
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment