/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as path from "path" import * as fs from "fs" import { fileURLToPath } from "url" import { createRequire } from "node:module" import type { IProductConfiguration } from "./deps/vscode/vs/base/common/product.js" const require = createRequire(import.meta.url) const __dirname = path.dirname(fileURLToPath(import.meta.url)) const isWindows = process.platform === "win32" // increase number of stack frames(from 10, https://github.com/v8/v8/wiki/Stack-Trace-API) Error.stackTraceLimit = 100 if (!process.env["VSCODE_HANDLES_SIGPIPE"]) { // Workaround for Electron not installing a handler to ignore SIGPIPE // (https://github.com/electron/electron/issues/13254) let didLogAboutSIGPIPE = false process.on("SIGPIPE", () => { // See https://github.com/microsoft/vscode-remote-release/issues/6543 // In certain situations, the console itself can be in a broken pipe state // so logging SIGPIPE to the console will cause an infinite async loop if (!didLogAboutSIGPIPE) { didLogAboutSIGPIPE = true console.error(new Error(`Unexpected SIGPIPE`)) } }) } // Setup current working directory in all our node & electron processes // - Windows: call `process.chdir()` to always set application folder as cwd // - all OS: store the `process.cwd()` inside `VSCODE_CWD` for consistent lookups function setupCurrentWorkingDirectory(): void { try { // Store the `process.cwd()` inside `VSCODE_CWD` // for consistent lookups, but make sure to only // do this once unless defined already from e.g. // a parent process. if (typeof process.env["VSCODE_CWD"] !== "string") { process.env["VSCODE_CWD"] = process.cwd() } // Windows: always set application folder as current working dir if (process.platform === "win32") { process.chdir(path.dirname(process.execPath)) } } catch (err) { console.error(err) } } setupCurrentWorkingDirectory() /** * Add support for redirecting the loading of node modules * * Note: only applies when running out of sources. */ export function devInjectNodeModuleLookupPath(injectPath: string): void { if (!process.env["VSCODE_DEV"]) { return // only applies running out of sources } if (!injectPath) { throw new Error("Missing injectPath") } // register a loader hook const Module = require("node:module") Module.register("./bootstrap-import.js", { parentURL: import.meta.url, data: injectPath }) } export function removeGlobalNodeJsModuleLookupPaths(): void { if (typeof process?.versions?.electron === "string") { return // Electron disables global search paths in https://github.com/electron/electron/blob/3186c2f0efa92d275dc3d57b5a14a60ed3846b0e/shell/common/node_bindings.cc#L653 } const Module = require("module") const globalPaths = Module.globalPaths const originalResolveLookupPaths = Module._resolveLookupPaths Module._resolveLookupPaths = function (moduleName: string, parent: any): string[] { const paths = originalResolveLookupPaths(moduleName, parent) if (Array.isArray(paths)) { let commonSuffixLength = 0 while ( commonSuffixLength < paths.length && paths[paths.length - 1 - commonSuffixLength] === globalPaths[globalPaths.length - 1 - commonSuffixLength] ) { commonSuffixLength++ } return paths.slice(0, paths.length - commonSuffixLength) } return paths } const originalNodeModulePaths = Module._nodeModulePaths Module._nodeModulePaths = function (from: string): string[] { let paths: string[] = originalNodeModulePaths(from) if (!isWindows) { return paths } // On Windows, remove drive(s) and users' home directory from search paths, // UNLESS 'from' is explicitly set to one of those. const isDrive = (p: string) => p.length >= 3 && p.endsWith(":\\") if (!isDrive(from)) { paths = paths.filter((p) => !isDrive(path.dirname(p))) } if (process.env.HOMEDRIVE && process.env.HOMEPATH) { const userDir = path.dirname(path.join(process.env.HOMEDRIVE, process.env.HOMEPATH)) const isUsersDir = (p: string) => path.relative(p, userDir).length === 0 // Check if 'from' is the same as 'userDir' if (!isUsersDir(from)) { paths = paths.filter((p) => !isUsersDir(path.dirname(p))) } } return paths } } /** * Helper to enable portable mode. */ export function configurePortable(product: Partial): { portableDataPath: string isPortable: boolean } { const appRoot = path.dirname(__dirname) function getApplicationPath(): string { if (process.env["VSCODE_DEV"]) { return appRoot } if (process.platform === "darwin") { return path.dirname(path.dirname(path.dirname(appRoot))) } return path.dirname(path.dirname(appRoot)) } function getPortableDataPath(): string { if (process.env["VSCODE_PORTABLE"]) { return process.env["VSCODE_PORTABLE"] } if (process.platform === "win32" || process.platform === "linux") { return path.join(getApplicationPath(), "data") } const portableDataName = product.portable || `${product.applicationName}-portable-data` return path.join(path.dirname(getApplicationPath()), portableDataName) } const portableDataPath = getPortableDataPath() const isPortable = !("target" in product) && fs.existsSync(portableDataPath) const portableTempPath = path.join(portableDataPath, "tmp") const isTempPortable = isPortable && fs.existsSync(portableTempPath) if (isPortable) { process.env["VSCODE_PORTABLE"] = portableDataPath } else { delete process.env["VSCODE_PORTABLE"] } if (isTempPortable) { if (process.platform === "win32") { process.env["TMP"] = portableTempPath process.env["TEMP"] = portableTempPath } else { process.env["TMPDIR"] = portableTempPath } } return { portableDataPath, isPortable, } }