oxc/npm/oxlint/bin/oxc_language_server
2025-01-18 14:05:58 +08:00

147 lines
3.4 KiB
JavaScript
Executable file

#!/usr/bin/env node
const isMusl = () => {
let musl = false;
if (process.platform === "linux") {
musl = isMuslFromFilesystem();
if (musl === null) {
musl = isMuslFromReport();
}
if (musl === null) {
musl = isMuslFromChildProcess();
}
}
return musl;
};
const isFileMusl = (f) => f.includes("libc.musl-") || f.includes("ld-musl-");
const isMuslFromFilesystem = () => {
const { readFileSync } = require("fs");
try {
return readFileSync("/usr/bin/ldd", "utf-8").includes("musl");
} catch {
return null;
}
};
const isMuslFromReport = () => {
const report =
typeof process.report.getReport === "function"
? process.report.getReport()
: null;
if (!report) {
return null;
}
if (report.header && report.header.glibcVersionRuntime) {
return false;
}
if (Array.isArray(report.sharedObjects)) {
if (report.sharedObjects.some(isFileMusl)) {
return true;
}
}
return false;
};
const isMuslFromChildProcess = () => {
try {
return require("child_process")
.execSync("ldd --version", { encoding: "utf8" })
.includes("musl");
} catch (e) {
// If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false
return false;
}
};
const { platform, arch, env, version, release } = process;
const BIN_NAME = "oxc_language_server";
const PLATFORMS = {
win32: {
x64: {
musl: `@oxlint/win32-x64/${BIN_NAME}.exe`,
gnu: `@oxlint/win32-x64/${BIN_NAME}.exe`,
},
arm64: {
musl: `@oxlint/win32-arm64/${BIN_NAME}.exe`,
gnu: `@oxlint/win32-arm64/${BIN_NAME}.exe`,
},
},
darwin: {
x64: {
musl: `@oxlint/darwin-x64/${BIN_NAME}`,
gnu: `@oxlint/darwin-x64/${BIN_NAME}`,
},
arm64: {
musl: `@oxlint/darwin-arm64/${BIN_NAME}`,
gnu: `@oxlint/darwin-arm64/${BIN_NAME}`,
},
},
linux: {
x64: {
musl: `@oxlint/linux-x64-musl/${BIN_NAME}`,
gnu: `@oxlint/linux-x64-gnu/${BIN_NAME}`,
},
arm64: {
musl: `@oxlint/linux-arm64-musl/${BIN_NAME}`,
gnu: `@oxlint/linux-arm64-gnu/${BIN_NAME}`,
},
},
};
let binPath = PLATFORMS[platform]?.[arch]?.[isMusl() ? "musl" : "gnu"];
if (binPath) {
const result = require("child_process").spawnSync(
require.resolve(binPath),
process.argv.slice(2),
{
shell: false,
stdio: "inherit",
env: {
...env,
JS_RUNTIME_VERSION: version,
JS_RUNTIME_NAME: release.name,
NODE_PACKAGE_MANAGER: detectPackageManager(),
},
}
);
if (result.error) {
throw result.error;
}
process.exitCode = result.status;
} else {
let target = `${platform}-${arch}`;
if (isMusl()) {
target = `${target}-musl`;
}
console.error(
`The oxc_language_server CLI package doesn't ship with prebuilt binaries for your platform (${target}) yet. ` +
"You can create an issue at https://github.com/oxc-project/oxc/issues for support."
);
process.exitCode = 1;
}
/**
* NPM, Yarn, and other package manager set the `npm_config_user_agent`. It has the following format:
*
* ```
* "npm/8.3.0 node/v16.13.2 win32 x64 workspaces/false
* ```
*
* @returns The package manager string (`npm/8.3.0`) or null if the user agent string isn't set.
*/
function detectPackageManager() {
const userAgent = env.npm_config_user_agent;
if (userAgent == null) {
return null;
}
return userAgent.split(" ")[0];
}