nixos: vendor local package definitions
This commit is contained in:
135
nixos/packages/t3code/normalize-bun-binaries.ts
Normal file
135
nixos/packages/t3code/normalize-bun-binaries.ts
Normal file
@@ -0,0 +1,135 @@
|
||||
import { lstat, mkdir, readdir, rm, symlink } from "fs/promises";
|
||||
import { join, relative } from "path";
|
||||
|
||||
type PackageManifest = {
|
||||
name?: string;
|
||||
bin?: string | Record<string, string>;
|
||||
};
|
||||
|
||||
const bunRoot = join(process.cwd(), "node_modules/.bun");
|
||||
const bunEntries = (await readdir(bunRoot)).sort();
|
||||
|
||||
for (const entry of bunEntries) {
|
||||
const modulesRoot = join(bunRoot, entry, "node_modules");
|
||||
if (!(await exists(modulesRoot))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const binRoot = join(modulesRoot, ".bin");
|
||||
await rm(binRoot, { recursive: true, force: true });
|
||||
await mkdir(binRoot, { recursive: true });
|
||||
|
||||
const packageDirs = await collectPackages(modulesRoot);
|
||||
for (const packageDir of packageDirs) {
|
||||
const manifest = await readManifest(packageDir);
|
||||
if (!manifest?.bin) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const seen = new Set<string>();
|
||||
if (typeof manifest.bin == "string") {
|
||||
const fallback = manifest.name ?? packageDir.split("/").pop();
|
||||
if (fallback) {
|
||||
await linkBinary(binRoot, fallback, packageDir, manifest.bin, seen);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
const entries = Object.entries(manifest.bin).sort((a, b) => a[0].localeCompare(b[0]));
|
||||
for (const [name, target] of entries) {
|
||||
await linkBinary(binRoot, name, packageDir, target, seen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function collectPackages(modulesRoot: string) {
|
||||
const found: string[] = [];
|
||||
const topLevel = (await readdir(modulesRoot)).sort();
|
||||
|
||||
for (const name of topLevel) {
|
||||
if (name == ".bin" || name == ".bun") {
|
||||
continue;
|
||||
}
|
||||
|
||||
const full = join(modulesRoot, name);
|
||||
if (!(await isDirectory(full))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (name.startsWith("@")) {
|
||||
const scoped = (await readdir(full)).sort();
|
||||
for (const child of scoped) {
|
||||
const scopedDir = join(full, child);
|
||||
if (await isDirectory(scopedDir)) {
|
||||
found.push(scopedDir);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
found.push(full);
|
||||
}
|
||||
|
||||
return found.sort();
|
||||
}
|
||||
|
||||
async function readManifest(dir: string) {
|
||||
const file = Bun.file(join(dir, "package.json"));
|
||||
if (!(await file.exists())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (await file.json()) as PackageManifest;
|
||||
}
|
||||
|
||||
async function linkBinary(
|
||||
binRoot: string,
|
||||
name: string,
|
||||
packageDir: string,
|
||||
target: string,
|
||||
seen: Set<string>,
|
||||
) {
|
||||
if (!name || !target) {
|
||||
return;
|
||||
}
|
||||
|
||||
const normalizedName = normalizeBinName(name);
|
||||
if (seen.has(normalizedName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const resolved = join(packageDir, target);
|
||||
const script = Bun.file(resolved);
|
||||
if (!(await script.exists())) {
|
||||
return;
|
||||
}
|
||||
|
||||
seen.add(normalizedName);
|
||||
const destination = join(binRoot, normalizedName);
|
||||
const relativeTarget = relative(binRoot, resolved);
|
||||
await rm(destination, { force: true });
|
||||
await symlink(relativeTarget.length == 0 ? "." : relativeTarget, destination);
|
||||
}
|
||||
|
||||
async function exists(path: string) {
|
||||
try {
|
||||
await lstat(path);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function isDirectory(path: string) {
|
||||
try {
|
||||
const info = await lstat(path);
|
||||
return info.isDirectory();
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeBinName(name: string) {
|
||||
const slash = name.lastIndexOf("/");
|
||||
return slash >= 0 ? name.slice(slash + 1) : name;
|
||||
}
|
||||
Reference in New Issue
Block a user