diff --git a/packages/@biomejs/biome/bin/biome b/packages/@biomejs/biome/bin/biome index 1f083650770c..a96a18e25a59 100644 --- a/packages/@biomejs/biome/bin/biome +++ b/packages/@biomejs/biome/bin/biome @@ -1,5 +1,21 @@ #!/usr/bin/env node const { platform, arch, env, version, release } = process; +const { execSync } = require("child_process"); + +function isMusl() { + let stderr; + try { + stderr = execSync("ldd --version", { + stdio: ['pipe', 'pipe', 'pipe'] + }); + } catch (err) { + stderr = err.stderr; + } + if (stderr.indexOf("musl") > -1) { + return true; + } + return false; +} const PLATFORMS = { win32: { @@ -14,12 +30,21 @@ const PLATFORMS = { x64: "@biomejs/cli-linux-x64/biome", arm64: "@biomejs/cli-linux-arm64/biome", }, + "linux-musl": { + x64: "@biomejs/cli-linux-x64-musl/biome", + arm64: "@biomejs/cli-linux-arm64-musl/biome", + }, }; if (env.ROME_BINARY) { console.warn(`[WARN] The environment variable "ROME_BINARY" is deprecated. Use "BIOME_BINARY" instead.`) } -const binPath = env.BIOME_BINARY || env.ROME_BINARY || PLATFORMS?.[platform]?.[arch]; +const binPath = env.BIOME_BINARY || env.ROME_BINARY || + (platform === "linux" && isMusl() + ? PLATFORMS?.["linux-musl"]?.[arch] + : PLATFORMS?.[platform]?.[arch] + ); + if (binPath) { const packageManager = detectPackageManager(); const result = require("child_process").spawnSync( diff --git a/packages/@biomejs/biome/scripts/generate-packages.mjs b/packages/@biomejs/biome/scripts/generate-packages.mjs index 46d704324ea5..dc4d7e452743 100644 --- a/packages/@biomejs/biome/scripts/generate-packages.mjs +++ b/packages/@biomejs/biome/scripts/generate-packages.mjs @@ -1,6 +1,7 @@ import * as fs from "node:fs"; import { resolve } from "node:path"; import { fileURLToPath } from "node:url"; +import { format } from "node:util"; const CLI_ROOT = resolve(fileURLToPath(import.meta.url), "../.."); const PACKAGES_ROOT = resolve(CLI_ROOT, ".."); @@ -11,10 +12,16 @@ const rootManifest = JSON.parse( fs.readFileSync(MANIFEST_PATH).toString("utf-8"), ); -function generateNativePackage(platform, arch) { - const packageName = `@biomejs/cli-${platform}-${arch}`; - const packageRoot = resolve(PACKAGES_ROOT, `cli-${platform}-${arch}`); +function getName(platform, arch, prefix = 'cli') { + return format(`${prefix}-${platform}`, arch); +} +function generateNativePackage(platform, arch) { + const os = platform.split('-')[0]; + const buildName = getName(platform, arch) + const packageName = `@biomejs/${buildName}` + const packageRoot = resolve(PACKAGES_ROOT, buildName); + // Remove the directory just in case it already exists (it's autogenerated // so there shouldn't be anything important there anyway) fs.rmSync(packageRoot, { recursive: true, force: true }); @@ -33,8 +40,12 @@ function generateNativePackage(platform, arch) { repository, engines, homepage, - os: [platform], + os: [os], cpu: [arch], + libc: os === "linux" + ? packageName.endsWith('musl') + ? ['musl'] : ['glibc'] + : undefined }); const manifestPath = resolve(packageRoot, "package.json"); @@ -42,8 +53,8 @@ function generateNativePackage(platform, arch) { fs.writeFileSync(manifestPath, manifest); // Copy the CLI binary - const ext = platform === "win32" ? ".exe" : ""; - const binarySource = resolve(REPO_ROOT, `biome-${platform}-${arch}${ext}`); + const ext = os === "win32" ? ".exe" : ""; + const binarySource = resolve(REPO_ROOT, `${getName(platform, arch, 'biome')}${ext}`); const binaryTarget = resolve(packageRoot, `biome${ext}`); console.log(`Copy binary ${binaryTarget}`); @@ -75,7 +86,7 @@ function writeManifest(packagePath) { const nativePackages = PLATFORMS.flatMap((platform) => ARCHITECTURES.map((arch) => [ - `@biomejs/cli-${platform}-${arch}`, + `@biomejs/${getName(platform, arch)}`, rootManifest.version, ]), ); @@ -88,7 +99,7 @@ function writeManifest(packagePath) { fs.writeFileSync(manifestPath, content); } -const PLATFORMS = ["win32", "darwin", "linux"]; +const PLATFORMS = ["win32-%s", "darwin-%s", "linux-%s", "linux-%s-musl"]; const ARCHITECTURES = ["x64", "arm64"]; const WASM_TARGETS = ["bundler", "nodejs", "web"]; diff --git a/packages/@biomejs/biome/scripts/postinstall.js b/packages/@biomejs/biome/scripts/postinstall.js index 92f930790caf..9fd2df7cdfc0 100644 --- a/packages/@biomejs/biome/scripts/postinstall.js +++ b/packages/@biomejs/biome/scripts/postinstall.js @@ -1,4 +1,20 @@ const { platform, arch } = process; +const { execSync } = require("child_process"); + +function isMusl() { + let stderr; + try { + stderr = execSync("ldd --version", { + stdio: ['pipe', 'pipe', 'pipe'] + }); + } catch (err) { + stderr = err.stderr; + } + if (stderr.indexOf("musl") > -1) { + return true; + } + return false; +} const PLATFORMS = { win32: { @@ -13,9 +29,17 @@ const PLATFORMS = { x64: "@biomejs/cli-linux-x64/biome", arm64: "@biomejs/cli-linux-arm64/biome", }, + "linux-musl": { + x64: "@biomejs/cli-linux-x64-musl/biome", + arm64: "@biomejs/cli-linux-arm64-musl/biome", + }, }; -const binName = PLATFORMS?.[platform]?.[arch]; +const binName = + platform === "linux" && isMusl() + ? PLATFORMS?.["linux-musl"]?.[arch] + : PLATFORMS?.[platform]?.[arch]; + if (binName) { let binPath; try {