提交 f8bd0e3d 编写于 作者: D Daniel Imms

Use findExecutable based on tasks function

上级 ea5435a4
......@@ -4,8 +4,9 @@
*--------------------------------------------------------------------------------------------*/
import { IProcessEnvironment, isLinux, isMacintosh, isWindows } from 'vs/base/common/platform';
import { readFile } from 'vs/base/node/pfs';
import { basename } from 'vs/base/common/path';
import { readFile, exists } from 'vs/base/node/pfs';
import * as path from 'vs/base/common/path';
import { isString } from 'vs/base/common/types';
let mainProcessParentEnv: IProcessEnvironment | undefined;
......@@ -18,7 +19,7 @@ export async function getMainProcessParentEnv(): Promise<IProcessEnvironment> {
// env using /proc/<pid>/environ.
if (isLinux) {
const mainProcessId = process.ppid;
const codeProcessName = basename(process.argv[0]);
const codeProcessName = path.basename(process.argv[0]);
let pid: number = 0;
let ppid: number = mainProcessId;
let name: string = codeProcessName;
......@@ -76,4 +77,56 @@ export async function getMainProcessParentEnv(): Promise<IProcessEnvironment> {
}
return mainProcessParentEnv!;
}
export async function findExecutable(command: string, cwd?: string, paths?: string[]): Promise<string | undefined> {
// If we have an absolute path then we take it.
if (path.isAbsolute(command)) {
return await exists(command) ? command : undefined;
}
if (cwd === undefined) {
cwd = process.cwd();
}
const dir = path.dirname(command);
if (dir !== '.') {
// We have a directory and the directory is relative (see above). Make the path absolute
// to the current working directory.
const fullPath = path.join(cwd, command);
return await exists(fullPath) ? fullPath : undefined;
}
if (paths === undefined && isString(process.env.PATH)) {
paths = process.env.PATH.split(path.delimiter);
}
// No PATH environment. Make path absolute to the cwd.
if (paths === undefined || paths.length === 0) {
const fullPath = path.join(cwd, command);
return await exists(fullPath) ? fullPath : undefined;
}
// We have a simple file name. We get the path variable from the env
// and try to find the executable on the path.
for (let pathEntry of paths) {
// The path entry is absolute.
let fullPath: string;
if (path.isAbsolute(pathEntry)) {
fullPath = path.join(pathEntry, command);
} else {
fullPath = path.join(cwd, pathEntry, command);
}
if (await exists(fullPath)) {
return fullPath;
}
if (isWindows) {
let withExtension = fullPath + '.com';
if (await exists(withExtension)) {
return withExtension;
}
withExtension = fullPath + '.exe';
if (await exists(withExtension)) {
return withExtension;
}
}
}
const fullPath = path.join(cwd, command);
return await exists(fullPath) ? fullPath : undefined;
}
\ No newline at end of file
......@@ -15,6 +15,8 @@ import { IShellLaunchConfig, ITerminalChildProcess, SHELL_PATH_INVALID_EXIT_CODE
import { exec } from 'child_process';
import { ILogService } from 'vs/platform/log/common/log';
import { stat } from 'vs/base/node/pfs';
import { findExecutable } from 'vs/workbench/contrib/terminal/node/terminalEnvironment';
import { URI } from 'vs/base/common/uri';
export class TerminalProcess implements ITerminalChildProcess, IDisposable {
private _exitCode: number;
......@@ -25,7 +27,6 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
private _isDisposed: boolean = false;
private _titleInterval: NodeJS.Timer | null = null;
private _initialCwd: string;
private _foundExecutableInPath: boolean = false;
private readonly _onProcessData = new Emitter<string>();
public get onProcessData(): Event<string> { return this._onProcessData.event; }
......@@ -69,54 +70,25 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
stat(shellLaunchConfig.executable!).then(stat => {
if (!stat.isFile() && !stat.isSymbolicLink()) {
this._exitCode = stat.isDirectory() ? SHELL_PATH_DIRECTORY_EXIT_CODE : SHELL_PATH_INVALID_EXIT_CODE;
this._queueProcessExit();
this._processStartupComplete = Promise.resolve(undefined);
return;
return this._launchFailed(stat.isDirectory() ? SHELL_PATH_DIRECTORY_EXIT_CODE : SHELL_PATH_INVALID_EXIT_CODE);
}
this.setupPtyProcess(shellLaunchConfig, options);
}, (err) => {
if (err && err.code === 'ENOENT' && !this.checkIfExistsInPath(shellLaunchConfig.executable!)) {
this._exitCode = SHELL_PATH_INVALID_EXIT_CODE;
this._queueProcessExit();
this._processStartupComplete = Promise.resolve(undefined);
return;
}, async (err) => {
if (err && err.code === 'ENOENT') {
let cwd = shellLaunchConfig.cwd instanceof URI ? shellLaunchConfig.cwd.path : shellLaunchConfig.cwd!;
const executable = await findExecutable(shellLaunchConfig.executable!, cwd);
if (!executable) {
return this._launchFailed(SHELL_PATH_INVALID_EXIT_CODE);
}
}
this.setupPtyProcess(shellLaunchConfig, options);
});
}
private checkInsideDirRecursively(execPath: string, executable: string): void {
try {
fs.readdirSync(execPath).forEach((file) => {
const pathToFile = path.join(execPath, file);
const isDirectory = fs.statSync(pathToFile).isDirectory();
if (!isDirectory) {
if (executable === file) {
this._foundExecutableInPath = true;
}
} else {
this.checkInsideDirRecursively(execPath, executable);
}
});
}
catch (err) {
if (err.code !== 'ENOENT') {
throw err;
}
}
}
private checkIfExistsInPath(executable: string): boolean {
if (process.env.PATH) {
const envPath = process.env.PATH.split(path.delimiter);
envPath.forEach(eachPath => {
if (!path.isAbsolute(eachPath)) {
this.checkInsideDirRecursively(eachPath, executable);
}
});
}
return this._foundExecutableInPath;
private _launchFailed(exitCode: number): void {
this._exitCode = exitCode;
this._queueProcessExit();
this._processStartupComplete = Promise.resolve(undefined);
}
private setupPtyProcess(shellLaunchConfig: IShellLaunchConfig, options: pty.IPtyForkOptions): void {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册