oxc/npm/oxlint/bin/oxc_language_server
rzvxa 56cbdf5f0e ci(oxlint): add oxc_language_server binary to the oxlint package. (#3350)
I didn't introduce a new set of native packages for the `oxc_language_server` binary, This change temporarily bundles them as part of oxlint, We most probably would want to make it an optional dependency in the future if we start to add more futures like formatting, jump to definition, etc to it.
2024-05-27 02:46:43 +00:00

147 lines
3.4 KiB
JavaScript

#!/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];
}