1 line
50 KiB
Plaintext
1 line
50 KiB
Plaintext
{"version":3,"file":"Executable.js","sourceRoot":"","sources":["../src/Executable.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport * as child_process from 'child_process';\nimport * as os from 'os';\nimport * as path from 'path';\nimport { EnvironmentMap } from './EnvironmentMap';\n\nimport { FileSystem } from './FileSystem';\nimport { PosixModeBits } from './PosixModeBits';\nimport { Text } from './Text';\nimport { InternalError } from './InternalError';\n\n/**\n * Typings for one of the streams inside IExecutableSpawnSyncOptions.stdio.\n * @public\n */\nexport type ExecutableStdioStreamMapping =\n | 'pipe'\n | 'ignore'\n | 'inherit'\n | NodeJS.WritableStream\n | NodeJS.ReadableStream\n | number\n | undefined;\n\n/**\n * Types for {@link IExecutableSpawnSyncOptions.stdio}\n * and {@link IExecutableSpawnOptions.stdio}\n * @public\n */\nexport type ExecutableStdioMapping = 'pipe' | 'ignore' | 'inherit' | ExecutableStdioStreamMapping[];\n\n/**\n * Options for Executable.tryResolve().\n * @public\n */\nexport interface IExecutableResolveOptions {\n /**\n * The current working directory. If omitted, process.cwd() will be used.\n */\n currentWorkingDirectory?: string;\n\n /**\n * The environment variables for the child process.\n *\n * @remarks\n * If `environment` and `environmentMap` are both omitted, then `process.env` will be used.\n * If `environment` and `environmentMap` cannot both be specified.\n */\n environment?: NodeJS.ProcessEnv;\n\n /**\n * The environment variables for the child process.\n *\n * @remarks\n * If `environment` and `environmentMap` are both omitted, then `process.env` will be used.\n * If `environment` and `environmentMap` cannot both be specified.\n */\n environmentMap?: EnvironmentMap;\n}\n\n/**\n * Options for {@link Executable.spawnSync}\n * @public\n */\nexport interface IExecutableSpawnSyncOptions extends IExecutableResolveOptions {\n /**\n * The content to be passed to the child process's stdin.\n *\n * NOTE: If specified, this content replaces any IExecutableSpawnSyncOptions.stdio[0]\n * mapping for stdin.\n */\n input?: string;\n\n /**\n * The stdio mappings for the child process.\n *\n * NOTE: If IExecutableSpawnSyncOptions.input is provided, it will take precedence\n * over the stdin mapping (stdio[0]).\n */\n stdio?: ExecutableStdioMapping;\n\n /**\n * The maximum time the process is allowed to run before it will be terminated.\n */\n timeoutMs?: number;\n\n /**\n * The largest amount of bytes allowed on stdout or stderr for this synchronous operation.\n * If exceeded, the child process will be terminated. The default is 200 * 1024.\n */\n maxBuffer?: number;\n}\n\n/**\n * Options for {@link Executable.spawn}\n * @public\n */\nexport interface IExecutableSpawnOptions extends IExecutableResolveOptions {\n /**\n * The stdio mappings for the child process.\n *\n * NOTE: If IExecutableSpawnSyncOptions.input is provided, it will take precedence\n * over the stdin mapping (stdio[0]).\n */\n stdio?: ExecutableStdioMapping;\n}\n\n/**\n * The options for running a process to completion using {@link Executable.(waitForExitAsync:3)}.\n *\n * @public\n */\nexport interface IWaitForExitOptions {\n /**\n * Whether or not to throw when the process completes with a non-zero exit code. Defaults to false.\n */\n throwOnNonZeroExitCode?: boolean;\n\n /**\n * The encoding of the output. If not provided, the output will not be collected.\n */\n encoding?: BufferEncoding | 'buffer';\n}\n\n/**\n * {@inheritDoc IWaitForExitOptions}\n *\n * @public\n */\nexport interface IWaitForExitWithStringOptions extends IWaitForExitOptions {\n /**\n * {@inheritDoc IWaitForExitOptions.encoding}\n */\n encoding: BufferEncoding;\n}\n\n/**\n * {@inheritDoc IWaitForExitOptions}\n *\n * @public\n */\nexport interface IWaitForExitWithBufferOptions extends IWaitForExitOptions {\n /**\n * {@inheritDoc IWaitForExitOptions.encoding}\n */\n encoding: 'buffer';\n}\n\n/**\n * The result of running a process to completion using {@link Executable.(waitForExitAsync:3)}.\n *\n * @public\n */\nexport interface IWaitForExitResult<T extends Buffer | string | never = never> {\n /**\n * The process stdout output, if encoding was specified.\n */\n stdout: T;\n\n /**\n * The process stderr output, if encoding was specified.\n */\n stderr: T;\n\n /**\n * The process exit code. If the process was terminated, this will be null.\n */\n // eslint-disable-next-line @rushstack/no-new-null\n exitCode: number | null;\n}\n\n// Common environmental state used by Executable members\ninterface IExecutableContext {\n currentWorkingDirectory: string;\n environmentMap: EnvironmentMap;\n // For Windows, the parsed PATHEXT environment variable\n windowsExecutableExtensions: string[];\n}\n\ninterface ICommandLineOptions {\n path: string;\n args: string[];\n}\n\n/**\n * Process information sourced from the system. This process info is sourced differently depending\n * on the operating system:\n * - On Windows, this uses the `wmic.exe` utility.\n * - On Unix, this uses the `ps` utility.\n *\n * @public\n */\nexport interface IProcessInfo {\n /**\n * The name of the process.\n *\n * @remarks On Windows, the process name will be empty if the process is a kernel process.\n * On Unix, the process name will be empty if the process is the root process.\n */\n processName: string;\n\n /**\n * The process ID.\n */\n processId: number;\n\n /**\n * The parent process info.\n *\n * @remarks On Windows, the parent process info will be undefined if the process is a kernel process.\n * On Unix, the parent process info will be undefined if the process is the root process.\n */\n parentProcessInfo: IProcessInfo | undefined;\n\n /**\n * The child process infos.\n */\n childProcessInfos: IProcessInfo[];\n}\n\nexport async function parseProcessListOutputAsync(\n stream: NodeJS.ReadableStream\n): Promise<Map<number, IProcessInfo>> {\n const processInfoById: Map<number, IProcessInfo> = new Map<number, IProcessInfo>();\n let seenHeaders: boolean = false;\n for await (const line of Text.readLinesFromIterableAsync(stream, { ignoreEmptyLines: true })) {\n if (!seenHeaders) {\n seenHeaders = true;\n } else {\n parseProcessInfoEntry(line, processInfoById);\n }\n }\n return processInfoById;\n}\n\n// eslint-disable-next-line @rushstack/no-new-null\nexport function parseProcessListOutput(output: Iterable<string | null>): Map<number, IProcessInfo> {\n const processInfoById: Map<number, IProcessInfo> = new Map<number, IProcessInfo>();\n let seenHeaders: boolean = false;\n for (const line of Text.readLinesFromIterable(output, { ignoreEmptyLines: true })) {\n if (!seenHeaders) {\n seenHeaders = true;\n } else {\n parseProcessInfoEntry(line, processInfoById);\n }\n }\n return processInfoById;\n}\n\n// win32 format:\n// Name ParentProcessId ProcessId\n// process name 1234 5678\n// unix format:\n// COMMAND PPID PID\n// process name 51234 56784\nconst NAME_GROUP: 'name' = 'name';\nconst PROCESS_ID_GROUP: 'pid' = 'pid';\nconst PARENT_PROCESS_ID_GROUP: 'ppid' = 'ppid';\n// eslint-disable-next-line @rushstack/security/no-unsafe-regexp\nconst PROCESS_LIST_ENTRY_REGEX: RegExp = new RegExp(\n `^(?<${NAME_GROUP}>.+?)\\\\s+(?<${PARENT_PROCESS_ID_GROUP}>\\\\d+)\\\\s+(?<${PROCESS_ID_GROUP}>\\\\d+)\\\\s*$`\n);\n\nfunction parseProcessInfoEntry(line: string, existingProcessInfoById: Map<number, IProcessInfo>): void {\n const match: RegExpMatchArray | null = line.match(PROCESS_LIST_ENTRY_REGEX);\n if (!match?.groups) {\n throw new InternalError(`Invalid process list entry: ${line}`);\n }\n\n const processName: string = match.groups[NAME_GROUP];\n const processId: number = parseInt(match.groups[PROCESS_ID_GROUP], 10);\n const parentProcessId: number = parseInt(match.groups[PARENT_PROCESS_ID_GROUP], 10);\n\n // Only care about the parent process if it is not the same as the current process.\n let parentProcessInfo: IProcessInfo | undefined;\n if (parentProcessId !== processId) {\n parentProcessInfo = existingProcessInfoById.get(parentProcessId);\n if (!parentProcessInfo) {\n // Create a new placeholder entry for the parent with the information we have so far\n parentProcessInfo = {\n processName: '',\n processId: parentProcessId,\n parentProcessInfo: undefined,\n childProcessInfos: []\n };\n existingProcessInfoById.set(parentProcessId, parentProcessInfo);\n }\n }\n\n let processInfo: IProcessInfo | undefined = existingProcessInfoById.get(processId);\n if (!processInfo) {\n // Create a new entry\n processInfo = {\n processName,\n processId,\n parentProcessInfo,\n childProcessInfos: []\n };\n existingProcessInfoById.set(processId, processInfo);\n } else {\n // Update placeholder entry\n processInfo.processName = processName;\n processInfo.parentProcessInfo = parentProcessInfo;\n }\n\n // Add the process as a child of the parent process\n parentProcessInfo?.childProcessInfos.push(processInfo);\n}\n\nfunction convertToProcessInfoByNameMap(\n processInfoById: Map<number, IProcessInfo>\n): Map<string, IProcessInfo[]> {\n const processInfoByNameMap: Map<string, IProcessInfo[]> = new Map<string, IProcessInfo[]>();\n for (const processInfo of processInfoById.values()) {\n let processInfoNameEntries: IProcessInfo[] | undefined = processInfoByNameMap.get(\n processInfo.processName\n );\n if (!processInfoNameEntries) {\n processInfoNameEntries = [];\n processInfoByNameMap.set(processInfo.processName, processInfoNameEntries);\n }\n processInfoNameEntries.push(processInfo);\n }\n return processInfoByNameMap;\n}\n\nconst OS_PLATFORM: NodeJS.Platform = os.platform();\n\nfunction getProcessListProcessOptions(): ICommandLineOptions {\n let command: string;\n let args: string[];\n if (OS_PLATFORM === 'win32') {\n command = 'wmic.exe';\n // Order of declared properties does not impact the order of the output\n args = ['process', 'get', 'Name,ParentProcessId,ProcessId'];\n } else {\n command = 'ps';\n // -A: Select all processes\n // -o: User-defined format\n // Order of declared properties impacts the order of the output, so match\n // the order of wmic.exe output\n args = ['-Ao', 'comm,ppid,pid'];\n }\n return { path: command, args };\n}\n\n/**\n * The Executable class provides a safe, portable, recommended solution for tools that need\n * to launch child processes.\n *\n * @remarks\n * The NodeJS child_process API provides a solution for launching child processes, however\n * its design encourages reliance on the operating system shell for certain features.\n * Invoking the OS shell is not safe, not portable, and generally not recommended:\n *\n * - Different shells have different behavior and command-line syntax, and which shell you\n * will get with NodeJS is unpredictable. There is no universal shell guaranteed to be\n * available on all platforms.\n *\n * - If a command parameter contains symbol characters, a shell may interpret them, which\n * can introduce a security vulnerability\n *\n * - Each shell has different rules for escaping these symbols. On Windows, the default\n * shell is incapable of escaping certain character sequences.\n *\n * The Executable API provides a pure JavaScript implementation of primitive shell-like\n * functionality for searching the default PATH, appending default file extensions on Windows,\n * and executing a file that may contain a POSIX shebang. This primitive functionality\n * is sufficient (and recommended) for most tooling scenarios.\n *\n * If you need additional shell features such as wildcard globbing, environment variable\n * expansion, piping, or built-in commands, then we recommend to use the `@microsoft/rushell`\n * library instead. Rushell is a pure JavaScript shell with a standard syntax that is\n * guaranteed to work consistently across all platforms.\n *\n * @public\n */\nexport class Executable {\n /**\n * Synchronously create a child process and optionally capture its output.\n *\n * @remarks\n * This function is similar to child_process.spawnSync(). The main differences are:\n *\n * - It does not invoke the OS shell unless the executable file is a shell script.\n * - Command-line arguments containing special characters are more accurately passed\n * through to the child process.\n * - If the filename is missing a path, then the shell's default PATH will be searched.\n * - If the filename is missing a file extension, then Windows default file extensions\n * will be searched.\n *\n * @param filename - The name of the executable file. This string must not contain any\n * command-line arguments. If the name contains any path delimiters, then the shell's\n * default PATH will not be searched.\n * @param args - The command-line arguments to be passed to the process.\n * @param options - Additional options\n * @returns the same data type as returned by the NodeJS child_process.spawnSync() API\n *\n * @privateRemarks\n *\n * NOTE: The NodeJS spawnSync() returns SpawnSyncReturns<string> or SpawnSyncReturns<Buffer>\n * polymorphically based on the options.encoding parameter value. This is a fairly confusing\n * design. In most cases, developers want string with the default encoding. If/when someone\n * wants binary output or a non-default text encoding, we will introduce a separate API function\n * with a name like \"spawnWithBufferSync\".\n */\n public static spawnSync(\n filename: string,\n args: string[],\n options?: IExecutableSpawnSyncOptions\n ): child_process.SpawnSyncReturns<string> {\n if (!options) {\n options = {};\n }\n\n const context: IExecutableContext = Executable._getExecutableContext(options);\n\n const resolvedPath: string | undefined = Executable._tryResolve(filename, options, context);\n if (!resolvedPath) {\n throw new Error(`The executable file was not found: \"${filename}\"`);\n }\n\n const spawnOptions: child_process.SpawnSyncOptionsWithStringEncoding = {\n cwd: context.currentWorkingDirectory,\n env: context.environmentMap.toObject(),\n input: options.input,\n stdio: options.stdio as child_process.StdioOptions,\n timeout: options.timeoutMs,\n maxBuffer: options.maxBuffer,\n\n // Contrary to what the NodeJS typings imply, we must explicitly specify \"utf8\" here\n // if we want the result to be SpawnSyncReturns<string> instead of SpawnSyncReturns<Buffer>.\n encoding: 'utf8',\n\n // NOTE: This is always false, because Rushell will be recommended instead of relying on the OS shell.\n shell: false\n };\n\n const normalizedCommandLine: ICommandLineOptions = Executable._buildCommandLineFixup(\n resolvedPath,\n args,\n context\n );\n\n return child_process.spawnSync(normalizedCommandLine.path, normalizedCommandLine.args, spawnOptions);\n }\n\n /**\n * Start a child process.\n *\n * @remarks\n * This function is similar to child_process.spawn(). The main differences are:\n *\n * - It does not invoke the OS shell unless the executable file is a shell script.\n * - Command-line arguments containing special characters are more accurately passed\n * through to the child process.\n * - If the filename is missing a path, then the shell's default PATH will be searched.\n * - If the filename is missing a file extension, then Windows default file extensions\n * will be searched.\n *\n * This command is asynchronous, but it does not return a `Promise`. Instead it returns\n * a Node.js `ChildProcess` supporting event notifications.\n *\n * @param filename - The name of the executable file. This string must not contain any\n * command-line arguments. If the name contains any path delimiters, then the shell's\n * default PATH will not be searched.\n * @param args - The command-line arguments to be passed to the process.\n * @param options - Additional options\n * @returns the same data type as returned by the NodeJS child_process.spawnSync() API\n */\n public static spawn(\n filename: string,\n args: string[],\n options?: IExecutableSpawnOptions\n ): child_process.ChildProcess {\n if (!options) {\n options = {};\n }\n\n const context: IExecutableContext = Executable._getExecutableContext(options);\n\n const resolvedPath: string | undefined = Executable._tryResolve(filename, options, context);\n if (!resolvedPath) {\n throw new Error(`The executable file was not found: \"${filename}\"`);\n }\n\n const spawnOptions: child_process.SpawnOptions = {\n cwd: context.currentWorkingDirectory,\n env: context.environmentMap.toObject(),\n stdio: options.stdio as child_process.StdioOptions,\n\n // NOTE: This is always false, because Rushell will be recommended instead of relying on the OS shell.\n shell: false\n };\n\n const normalizedCommandLine: ICommandLineOptions = Executable._buildCommandLineFixup(\n resolvedPath,\n args,\n context\n );\n\n return child_process.spawn(normalizedCommandLine.path, normalizedCommandLine.args, spawnOptions);\n }\n\n /* eslint-disable @rushstack/no-new-null */\n /** {@inheritDoc Executable.(waitForExitAsync:3)} */\n public static async waitForExitAsync(\n childProcess: child_process.ChildProcess,\n options: IWaitForExitWithStringOptions\n ): Promise<IWaitForExitResult<string>>;\n\n /** {@inheritDoc Executable.(waitForExitAsync:3)} */\n public static async waitForExitAsync(\n childProcess: child_process.ChildProcess,\n options: IWaitForExitWithBufferOptions\n ): Promise<IWaitForExitResult<Buffer>>;\n\n /**\n * Wait for a child process to exit and return the result.\n *\n * @param childProcess - The child process to wait for.\n * @param options - Options for waiting for the process to exit.\n */\n public static async waitForExitAsync(\n childProcess: child_process.ChildProcess,\n options?: IWaitForExitOptions\n ): Promise<IWaitForExitResult<never>>;\n\n public static async waitForExitAsync<T extends Buffer | string | never = never>(\n childProcess: child_process.ChildProcess,\n options: IWaitForExitOptions = {}\n ): Promise<IWaitForExitResult<T>> {\n const { throwOnNonZeroExitCode = false, encoding } = options;\n if (encoding && (!childProcess.stdout || !childProcess.stderr)) {\n throw new Error(\n 'An encoding was specified, but stdout and/or stderr on the child process are not defined'\n );\n }\n\n const collectedStdout: T[] = [];\n const collectedStderr: T[] = [];\n const useBufferEncoding: boolean = encoding === 'buffer';\n\n function normalizeChunk<TChunk extends Buffer | string>(chunk: Buffer | string): TChunk {\n if (typeof chunk === 'string') {\n return (useBufferEncoding ? Buffer.from(chunk) : chunk) as TChunk;\n } else {\n return (useBufferEncoding ? chunk : chunk.toString(encoding as BufferEncoding)) as TChunk;\n }\n }\n\n let errorThrown: boolean = false;\n const exitCode: number | null = await new Promise<number | null>(\n (resolve: (result: number | null) => void, reject: (error: Error) => void) => {\n if (encoding) {\n childProcess.stdout!.on('data', (chunk: Buffer | string) => {\n collectedStdout.push(normalizeChunk(chunk));\n });\n childProcess.stderr!.on('data', (chunk: Buffer | string) => {\n collectedStderr.push(normalizeChunk(chunk));\n });\n }\n childProcess.on('error', (error: Error) => {\n errorThrown = true;\n reject(error);\n });\n childProcess.on('exit', (code: number | null) => {\n if (errorThrown) {\n // We've already rejected the promise\n return;\n }\n if (code !== 0 && throwOnNonZeroExitCode) {\n reject(new Error(`Process exited with code ${code}`));\n } else {\n resolve(code);\n }\n });\n }\n );\n\n const result: IWaitForExitResult<T> = {\n exitCode\n } as IWaitForExitResult<T>;\n\n if (encoding === 'buffer') {\n result.stdout = Buffer.concat(collectedStdout as Buffer[]) as T;\n result.stderr = Buffer.concat(collectedStderr as Buffer[]) as T;\n } else if (encoding) {\n result.stdout = collectedStdout.join('') as T;\n result.stderr = collectedStderr.join('') as T;\n }\n\n return result;\n }\n /* eslint-enable @rushstack/no-new-null */\n\n /**\n * Get the list of processes currently running on the system, keyed by the process ID.\n *\n * @remarks The underlying implementation depends on the operating system:\n * - On Windows, this uses the `wmic.exe` utility.\n * - On Unix, this uses the `ps` utility.\n */\n public static async getProcessInfoByIdAsync(): Promise<Map<number, IProcessInfo>> {\n const { path: command, args } = getProcessListProcessOptions();\n const process: child_process.ChildProcess = Executable.spawn(command, args, {\n stdio: ['ignore', 'pipe', 'ignore']\n });\n if (process.stdout === null) {\n throw new InternalError('Child process did not provide stdout');\n }\n const [processInfoByIdMap] = await Promise.all([\n parseProcessListOutputAsync(process.stdout),\n // Don't collect output in the result since we process it directly\n Executable.waitForExitAsync(process, { throwOnNonZeroExitCode: true })\n ]);\n return processInfoByIdMap;\n }\n\n /**\n * {@inheritDoc Executable.getProcessInfoByIdAsync}\n */\n public static getProcessInfoById(): Map<number, IProcessInfo> {\n const { path: command, args } = getProcessListProcessOptions();\n const processOutput: child_process.SpawnSyncReturns<string> = Executable.spawnSync(command, args);\n if (processOutput.error) {\n throw new Error(`Unable to list processes: ${command} failed with error ${processOutput.error}`);\n }\n if (processOutput.status !== 0) {\n throw new Error(`Unable to list processes: ${command} exited with code ${processOutput.status}`);\n }\n return parseProcessListOutput(processOutput.output);\n }\n\n /**\n * Get the list of processes currently running on the system, keyed by the process name. All processes\n * with the same name will be grouped.\n *\n * @remarks The underlying implementation depends on the operating system:\n * - On Windows, this uses the `wmic.exe` utility.\n * - On Unix, this uses the `ps` utility.\n */\n public static async getProcessInfoByNameAsync(): Promise<Map<string, IProcessInfo[]>> {\n const processInfoById: Map<number, IProcessInfo> = await Executable.getProcessInfoByIdAsync();\n return convertToProcessInfoByNameMap(processInfoById);\n }\n\n /**\n * {@inheritDoc Executable.getProcessInfoByNameAsync}\n */\n public static getProcessInfoByName(): Map<string, IProcessInfo[]> {\n const processInfoByIdMap: Map<number, IProcessInfo> = Executable.getProcessInfoById();\n return convertToProcessInfoByNameMap(processInfoByIdMap);\n }\n\n // PROBLEM: Given an \"args\" array of strings that may contain special characters (e.g. spaces,\n // backslashes, quotes), ensure that these strings pass through to the child process's ARGV array\n // without anything getting corrupted along the way.\n //\n // On Unix you just pass the array to spawnSync(). But on Windows, this is a very complex problem:\n // - The Win32 CreateProcess() API expects the args to be encoded as a single text string\n // - The decoding of this string is up to the application (not the OS), and there are 3 different\n // algorithms in common usage: the cmd.exe shell, the Microsoft CRT library init code, and\n // the Win32 CommandLineToArgvW()\n // - The encodings are counterintuitive and have lots of special cases\n // - NodeJS spawnSync() tries do the encoding without knowing which decoder will be used\n //\n // See these articles for a full analysis:\n // http://www.windowsinspired.com/understanding-the-command-line-string-and-arguments-received-by-a-windows-program/\n // http://www.windowsinspired.com/how-a-windows-programs-splits-its-command-line-into-individual-arguments/\n private static _buildCommandLineFixup(\n resolvedPath: string,\n args: string[],\n context: IExecutableContext\n ): ICommandLineOptions {\n const fileExtension: string = path.extname(resolvedPath);\n\n if (OS_PLATFORM === 'win32') {\n // Do we need a custom handler for this file type?\n switch (fileExtension.toUpperCase()) {\n case '.EXE':\n case '.COM':\n // okay to execute directly\n break;\n case '.BAT':\n case '.CMD': {\n Executable._validateArgsForWindowsShell(args);\n\n // These file types must be invoked via the Windows shell\n let shellPath: string | undefined = context.environmentMap.get('COMSPEC');\n if (!shellPath || !Executable._canExecute(shellPath, context)) {\n shellPath = Executable.tryResolve('cmd.exe');\n }\n if (!shellPath) {\n throw new Error(\n `Unable to execute \"${path.basename(resolvedPath)}\" ` +\n `because CMD.exe was not found in the PATH`\n );\n }\n\n const shellArgs: string[] = [];\n // /D: Disable execution of AutoRun commands when starting the new shell context\n shellArgs.push('/d');\n // /S: Disable Cmd.exe's parsing of double-quote characters inside the command-line\n shellArgs.push('/s');\n // /C: Execute the following command and then exit immediately\n shellArgs.push('/c');\n\n // If the path contains special charactrers (e.g. spaces), escape them so that\n // they don't get interpreted by the shell\n shellArgs.push(Executable._getEscapedForWindowsShell(resolvedPath));\n shellArgs.push(...args);\n\n return { path: shellPath, args: shellArgs };\n }\n default:\n throw new Error(\n `Cannot execute \"${path.basename(resolvedPath)}\" because the file type is not supported`\n );\n }\n }\n\n return {\n path: resolvedPath,\n args: args\n };\n }\n\n /**\n * Given a filename, this determines the absolute path of the executable file that would\n * be executed by a shell:\n *\n * - If the filename is missing a path, then the shell's default PATH will be searched.\n * - If the filename is missing a file extension, then Windows default file extensions\n * will be searched.\n *\n * @remarks\n *\n * @param filename - The name of the executable file. This string must not contain any\n * command-line arguments. If the name contains any path delimiters, then the shell's\n * default PATH will not be searched.\n * @param options - optional other parameters\n * @returns the absolute path of the executable, or undefined if it was not found\n */\n public static tryResolve(filename: string, options?: IExecutableResolveOptions): string | undefined {\n return Executable._tryResolve(filename, options || {}, Executable._getExecutableContext(options));\n }\n\n private static _tryResolve(\n filename: string,\n options: IExecutableResolveOptions,\n context: IExecutableContext\n ): string | undefined {\n // NOTE: Since \"filename\" cannot contain command-line arguments, the \"/\" here\n // must be interpreted as a path delimiter\n const hasPathSeparators: boolean =\n filename.indexOf('/') >= 0 || (OS_PLATFORM === 'win32' && filename.indexOf('\\\\') >= 0);\n\n // Are there any path separators?\n if (hasPathSeparators) {\n // If so, then don't search the PATH. Just resolve relative to the current working directory\n const resolvedPath: string = path.resolve(context.currentWorkingDirectory, filename);\n return Executable._tryResolveFileExtension(resolvedPath, context);\n } else {\n // Otherwise if it's a bare name, then try everything in the shell PATH\n const pathsToSearch: string[] = Executable._getSearchFolders(context);\n\n for (const pathToSearch of pathsToSearch) {\n const resolvedPath: string = path.join(pathToSearch, filename);\n const result: string | undefined = Executable._tryResolveFileExtension(resolvedPath, context);\n if (result) {\n return result;\n }\n }\n\n // No match was found\n return undefined;\n }\n }\n\n private static _tryResolveFileExtension(\n resolvedPath: string,\n context: IExecutableContext\n ): string | undefined {\n if (Executable._canExecute(resolvedPath, context)) {\n return resolvedPath;\n }\n\n // Try the default file extensions\n for (const shellExtension of context.windowsExecutableExtensions) {\n const resolvedNameWithExtension: string = resolvedPath + shellExtension;\n\n if (Executable._canExecute(resolvedNameWithExtension, context)) {\n return resolvedNameWithExtension;\n }\n }\n\n return undefined;\n }\n\n private static _buildEnvironmentMap(options: IExecutableResolveOptions): EnvironmentMap {\n const environmentMap: EnvironmentMap = new EnvironmentMap();\n if (options.environment !== undefined && options.environmentMap !== undefined) {\n throw new Error(\n 'IExecutableResolveOptions.environment and IExecutableResolveOptions.environmentMap' +\n ' cannot both be specified'\n );\n }\n if (options.environment !== undefined) {\n environmentMap.mergeFromObject(options.environment);\n } else if (options.environmentMap !== undefined) {\n environmentMap.mergeFrom(options.environmentMap);\n } else {\n environmentMap.mergeFromObject(process.env);\n }\n return environmentMap;\n }\n\n /**\n * This is used when searching the shell PATH for an executable, to determine\n * whether a match should be skipped or not. If it returns true, this does not\n * guarantee that the file can be successfully executed.\n */\n private static _canExecute(filePath: string, context: IExecutableContext): boolean {\n if (!FileSystem.exists(filePath)) {\n return false;\n }\n\n if (OS_PLATFORM === 'win32') {\n // NOTE: For Windows, we don't validate that the file extension appears in PATHEXT.\n // That environment variable determines which extensions can be appended if the\n // extension is missing, but it does not affect whether a file may be executed or not.\n // Windows does have a (seldom used) ACL that can be used to deny execution permissions\n // for a file, but NodeJS doesn't expose that API, so we don't bother checking it.\n\n // However, Windows *does* require that the file has some kind of file extension\n if (path.extname(filePath) === '') {\n return false;\n }\n } else {\n // For Unix, check whether any of the POSIX execute bits are set\n try {\n // eslint-disable-next-line no-bitwise\n if ((FileSystem.getPosixModeBits(filePath) & PosixModeBits.AllExecute) === 0) {\n return false; // not executable\n }\n } catch (error) {\n // If we have trouble accessing the file, ignore the error and consider it \"not executable\"\n // since that's what a shell would do\n }\n }\n\n return true;\n }\n\n /**\n * Returns the list of folders where we will search for an executable,\n * based on the PATH environment variable.\n */\n private static _getSearchFolders(context: IExecutableContext): string[] {\n const pathList: string = context.environmentMap.get('PATH') || '';\n\n const folders: string[] = [];\n\n // Avoid processing duplicates\n const seenPaths: Set<string> = new Set<string>();\n\n // NOTE: Cmd.exe on Windows always searches the current working directory first.\n // PowerShell and Unix shells do NOT do that, because it's a security concern.\n // We follow their behavior.\n\n for (const splitPath of pathList.split(path.delimiter)) {\n const trimmedPath: string = splitPath.trim();\n if (trimmedPath !== '') {\n if (!seenPaths.has(trimmedPath)) {\n // Fun fact: If you put relative paths in your PATH environment variable,\n // all shells will dynamically match them against the current working directory.\n // This is a terrible design, and in practice nobody does that, but it is supported...\n // so we allow it here.\n const resolvedPath: string = path.resolve(context.currentWorkingDirectory, trimmedPath);\n\n if (!seenPaths.has(resolvedPath)) {\n if (FileSystem.exists(resolvedPath)) {\n folders.push(resolvedPath);\n }\n\n seenPaths.add(resolvedPath);\n }\n\n seenPaths.add(trimmedPath);\n }\n }\n }\n\n return folders;\n }\n\n private static _getExecutableContext(options: IExecutableResolveOptions | undefined): IExecutableContext {\n if (!options) {\n options = {};\n }\n\n const environment: EnvironmentMap = Executable._buildEnvironmentMap(options);\n\n let currentWorkingDirectory: string;\n if (options.currentWorkingDirectory) {\n currentWorkingDirectory = path.resolve(options.currentWorkingDirectory);\n } else {\n currentWorkingDirectory = process.cwd();\n }\n\n const windowsExecutableExtensions: string[] = [];\n\n if (OS_PLATFORM === 'win32') {\n const pathExtVariable: string = environment.get('PATHEXT') || '';\n for (const splitValue of pathExtVariable.split(';')) {\n const trimmed: string = splitValue.trim().toLowerCase();\n // Ignore malformed extensions\n if (/^\\.[a-z0-9\\.]*[a-z0-9]$/i.test(trimmed)) {\n // Don't add the same extension twice\n if (windowsExecutableExtensions.indexOf(trimmed) < 0) {\n windowsExecutableExtensions.push(trimmed);\n }\n }\n }\n }\n\n return {\n environmentMap: environment,\n currentWorkingDirectory,\n windowsExecutableExtensions\n };\n }\n\n /**\n * Given an input string containing special symbol characters, this inserts the \"^\" escape\n * character to ensure the symbols are interpreted literally by the Windows shell.\n */\n private static _getEscapedForWindowsShell(text: string): string {\n const escapableCharRegExp: RegExp = /[%\\^&|<> ]/g;\n return text.replace(escapableCharRegExp, (value) => '^' + value);\n }\n\n /**\n * Checks for characters that are unsafe to pass to a Windows batch file\n * due to the way that cmd.exe implements escaping.\n */\n private static _validateArgsForWindowsShell(args: string[]): void {\n const specialCharRegExp: RegExp = /[%\\^&|<>\\r\\n]/g;\n\n for (const arg of args) {\n const match: RegExpMatchArray | null = arg.match(specialCharRegExp);\n if (match) {\n // NOTE: It is possible to escape some of these characters by prefixing them\n // with a caret (^), which allows these characters to be successfully passed\n // through to the batch file %1 variables. But they will be expanded again\n // whenever they are used. For example, NPM's binary wrapper batch files\n // use \"%*\" to pass their arguments to Node.exe, which causes them to be expanded\n // again. Unfortunately the Cmd.exe batch language provides native escaping\n // function (that could be used to insert the carets again).\n //\n // We could work around that by adding double carets, but in general there\n // is no way to predict how many times the variable will get expanded.\n // Thus, there is no generally reliable way to pass these characters.\n throw new Error(\n `The command line argument ${JSON.stringify(arg)} contains a` +\n ` special character ${JSON.stringify(match[0])} that cannot be escaped for the Windows shell`\n );\n }\n }\n }\n}\n"]} |