diff --git a/src/node/util.ts b/src/node/util.ts index e33ed4585..37eefc707 100644 --- a/src/node/util.ts +++ b/src/node/util.ts @@ -377,11 +377,31 @@ export const getMediaMime = (filePath?: string): string => { return (filePath && mimeTypes[path.extname(filePath)]) || "text/plain" } -export const isWsl = async (): Promise => { - return ( - (process.platform === "linux" && os.release().toLowerCase().indexOf("microsoft") !== -1) || - (await fs.readFile("/proc/version", "utf8")).toLowerCase().indexOf("microsoft") !== -1 - ) +/** + * A helper function that checks if the platform is Windows Subsystem for Linux + * (WSL) + * + * @see https://github.com/sindresorhus/is-wsl/blob/main/index.js + * @returns {Boolean} boolean if it is WSL + */ +export const isWsl = async ( + platform: NodeJS.Platform, + osRelease: string, + procVersionFilePath: string, +): Promise => { + if (platform !== "linux") { + return false + } + + if (osRelease.toLowerCase().includes("microsoft")) { + return true + } + + try { + return (await fs.readFile(procVersionFilePath, "utf8")).toLowerCase().includes("microsoft") + } catch (_) { + return false + } } /** @@ -398,7 +418,7 @@ export const open = async (address: URL | string): Promise => { } const args = [] as string[] const options = {} as cp.SpawnOptions - const platform = (await isWsl()) ? "wsl" : process.platform + const platform = (await isWsl(process.platform, os.release(), "/proc/version")) ? "wsl" : process.platform let command = platform === "darwin" ? "open" : "xdg-open" if (platform === "win32" || platform === "wsl") { command = platform === "wsl" ? "cmd.exe" : "cmd" diff --git a/test/unit/node/util.test.ts b/test/unit/node/util.test.ts index e37aeac92..0237296e5 100644 --- a/test/unit/node/util.test.ts +++ b/test/unit/node/util.test.ts @@ -4,6 +4,7 @@ import * as path from "path" import { generateUuid } from "../../../src/common/util" import { tmpdir } from "../../../src/node/constants" import * as util from "../../../src/node/util" +import { clean, tmpdir as tempDirHelper } from "../../utils/helpers" describe("getEnvPaths", () => { describe("on darwin", () => { @@ -482,3 +483,57 @@ describe("humanPath", () => { expect(actual).toBe(expected) }) }) + +describe("isWsl", () => { + const testName = "wsl" + + beforeAll(async () => { + await clean(testName) + }) + + describe("on Linux (microsoft)", () => { + it("should return true", async () => { + const fileName = "proc-version" + const osRelease = "5.4.0-1066-gke" + const pathToFile = path.join(await tempDirHelper(testName), fileName) + await fs.writeFile( + pathToFile, + "Linux version 3.4.0-Microsoft (Microsoft@Microsoft.com) (gcc version 4.7 (GCC) ) #1 SMP PREEMPT Wed Dec 31 14:42:53 PST 2014", + ) + expect(await util.isWsl("linux", osRelease, pathToFile)).toBe(true) + }) + }) + describe("on Linux (non-microsoft)", () => { + it("should return false", async () => { + const fileName = "proc-version2" + const osRelease = "Linux" + const pathToFile = path.join(await tempDirHelper(testName), fileName) + await fs.writeFile( + pathToFile, + "Linux version 5.4.0-1066-gke (buildd@lcy02-amd64-039) (gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04)) #69-Ubuntu SMP Fri Mar 11 13:52:45 UTC 202", + ) + expect(await util.isWsl("linux", osRelease, pathToFile)).toBe(false) + }) + }) + describe("on Win32 with microsoft in /proc/version", () => { + it("should return false", async () => { + const fileName = "proc-version3" + const osRelease = "3.4.0-Microsoft" + const pathToFile = path.join(await tempDirHelper(testName), fileName) + await fs.writeFile( + pathToFile, + "Linux version 3.4.0-Microsoft (Microsoft@Microsoft.com) (gcc version 4.7 (GCC) ) #1 SMP PREEMPT Wed Dec 31 14:42:53 PST 2014", + ) + expect(await util.isWsl("win32", osRelease, pathToFile)).toBe(false) + }) + }) + describe("on Darwin", () => { + it("should return false", async () => { + const fileName = "proc-version4" + const osRelease = + "Darwin Roadrunner.local 10.3.0 Darwin Kernel Version 10.3.0: Fri Feb 26 11:58:09 PST 2010; root:xnu-1504.3.12~1/RELEASE_I386 i386" + const pathToFile = path.join(await tempDirHelper(testName), fileName) + expect(await util.isWsl("darwin", osRelease, pathToFile)).toBe(false) + }) + }) +})