Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 22 additions & 34 deletions nix/scripts/canonicalize-node-modules.ts
Original file line number Diff line number Diff line change
@@ -1,65 +1,56 @@
import { lstat, mkdir, readdir, rm, symlink } from "fs/promises"
import { join, relative } from "path"

type SemverLike = {
valid: (value: string) => string | null
rcompare: (left: string, right: string) => number
}

type Entry = {
dir: string
version: string
label: string
}

async function isDirectory(path: string) {
try {
const info = await lstat(path)
return info.isDirectory()
} catch {
return false
}
}

const isValidSemver = (v: string) => Bun.semver.satisfies(v, "x.x.x")

const root = process.cwd()
const bunRoot = join(root, "node_modules/.bun")
const linkRoot = join(bunRoot, "node_modules")
const directories = (await readdir(bunRoot)).sort()

const versions = new Map<string, Entry[]>()

for (const entry of directories) {
const full = join(bunRoot, entry)
const info = await lstat(full)
if (!info.isDirectory()) {
if (!(await isDirectory(full))) {
continue
}
const parsed = parseEntry(entry)
if (!parsed) {
continue
}
const list = versions.get(parsed.name) ?? []
list.push({ dir: full, version: parsed.version, label: entry })
list.push({ dir: full, version: parsed.version })
versions.set(parsed.name, list)
}

const semverModule = (await import(join(bunRoot, "node_modules/semver"))) as
| SemverLike
| {
default: SemverLike
}
const semver = "default" in semverModule ? semverModule.default : semverModule
const selections = new Map<string, Entry>()

for (const [slug, list] of versions) {
list.sort((a, b) => {
const left = semver.valid(a.version)
const right = semver.valid(b.version)
if (left && right) {
const delta = semver.rcompare(left, right)
if (delta !== 0) {
return delta
}
}
if (left && !right) {
return -1
}
if (!left && right) {
return 1
}
const aValid = isValidSemver(a.version)
const bValid = isValidSemver(b.version)
if (aValid && bValid) return -Bun.semver.order(a.version, b.version)
if (aValid) return -1
if (bValid) return 1
return b.version.localeCompare(a.version)
})
selections.set(slug, list[0])
const first = list[0]
if (first) selections.set(slug, first)
}

await rm(linkRoot, { recursive: true, force: true })
Expand All @@ -77,10 +68,7 @@ for (const [slug, entry] of Array.from(selections.entries()).sort((a, b) => a[0]
await mkdir(parent, { recursive: true })
const linkPath = join(parent, leaf)
const desired = join(entry.dir, "node_modules", slug)
const exists = await lstat(desired)
.then((info) => info.isDirectory())
.catch(() => false)
if (!exists) {
if (!(await isDirectory(desired))) {
continue
}
const relativeTarget = relative(parent, desired)
Expand Down
16 changes: 4 additions & 12 deletions nix/scripts/normalize-bun-binaries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type PackageManifest = {

const root = process.cwd()
const bunRoot = join(root, "node_modules/.bun")
const bunEntries = (await safeReadDir(bunRoot)).sort()
const bunEntries = (await readdir(bunRoot)).sort()
let rewritten = 0

for (const entry of bunEntries) {
Expand Down Expand Up @@ -45,11 +45,11 @@ for (const entry of bunEntries) {
}
}

console.log(`[normalize-bun-binaries] rewrote ${rewritten} links`)
console.log(`[normalize-bun-binaries] rebuilt ${rewritten} links`)

async function collectPackages(modulesRoot: string) {
const found: string[] = []
const topLevel = (await safeReadDir(modulesRoot)).sort()
const topLevel = (await readdir(modulesRoot)).sort()
for (const name of topLevel) {
if (name === ".bin" || name === ".bun") {
continue
Expand All @@ -59,7 +59,7 @@ async function collectPackages(modulesRoot: string) {
continue
}
if (name.startsWith("@")) {
const scoped = (await safeReadDir(full)).sort()
const scoped = (await readdir(full)).sort()
for (const child of scoped) {
const scopedDir = join(full, child)
if (await isDirectory(scopedDir)) {
Expand Down Expand Up @@ -121,14 +121,6 @@ async function isDirectory(path: string) {
}
}

async function safeReadDir(path: string) {
try {
return await readdir(path)
} catch {
return []
}
}

function normalizeBinName(name: string) {
const slash = name.lastIndexOf("/")
if (slash >= 0) {
Expand Down
Loading