Преглед изворни кода

refactor(nix): use native Bun APIs and propagate errors (#12694)

Jérôme Benoit пре 2 месеци
родитељ
комит
79879b43ce
2 измењених фајлова са 26 додато и 46 уклоњено
  1. 22 34
      nix/scripts/canonicalize-node-modules.ts
  2. 4 12
      nix/scripts/normalize-bun-binaries.ts

+ 22 - 34
nix/scripts/canonicalize-node-modules.ts

@@ -1,27 +1,32 @@
 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)
@@ -29,37 +34,23 @@ for (const entry of directories) {
     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 })
@@ -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)

+ 4 - 12
nix/scripts/normalize-bun-binaries.ts

@@ -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) {
@@ -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
@@ -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)) {
@@ -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) {