Skip to content

Refactor the startup arguments method to use async/await #2482

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 19, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
230 changes: 115 additions & 115 deletions src/process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,134 +22,111 @@ export class PowerShellProcess {

private consoleTerminal: vscode.Terminal = undefined;
private consoleCloseSubscription: vscode.Disposable;
private sessionDetails: utils.IEditorServicesSessionDetails;

constructor(
public exePath: string,
private bundledModulesPath: string,
private title: string,
private log: Logger,
private startArgs: string,
private startPsesArgs: string,
private sessionFilePath: string,
private sessionSettings: Settings.ISettings) {

this.onExited = this.onExitedEmitter.event;
}

public start(logFileName: string): Thenable<utils.IEditorServicesSessionDetails> {

return new Promise<utils.IEditorServicesSessionDetails>(
(resolve, reject) => {
try {
const psesModulePath =
path.resolve(
__dirname,
this.bundledModulesPath,
"PowerShellEditorServices/PowerShellEditorServices.psd1");

const editorServicesLogPath = this.log.getLogFilePath(logFileName);

const featureFlags =
this.sessionSettings.developer.featureFlags !== undefined
? this.sessionSettings.developer.featureFlags.map((f) => `'${f}'`).join(", ")
: "";

this.startArgs +=
`-LogPath '${PowerShellProcess.escapeSingleQuotes(editorServicesLogPath)}' ` +
`-SessionDetailsPath '${PowerShellProcess.escapeSingleQuotes(this.sessionFilePath)}' ` +
`-FeatureFlags @(${featureFlags}) `;

if (this.sessionSettings.integratedConsole.useLegacyReadLine) {
this.startArgs += "-UseLegacyReadLine";
}

const powerShellArgs = [];

const useLoginShell: boolean =
(utils.isMacOS && this.sessionSettings.startAsLoginShell.osx)
|| (utils.isLinux && this.sessionSettings.startAsLoginShell.linux);

if (useLoginShell && this.isLoginShell(this.exePath)) {
// This MUST be the first argument.
powerShellArgs.push("-Login");
}

powerShellArgs.push("-NoProfile");
powerShellArgs.push("-NonInteractive");

// Only add ExecutionPolicy param on Windows
if (utils.isWindows) {
powerShellArgs.push("-ExecutionPolicy", "Bypass");
}

const startEditorServices = "Import-Module '" +
PowerShellProcess.escapeSingleQuotes(psesModulePath) +
"'; Start-EditorServices " + this.startArgs;

if (utils.isWindows) {
powerShellArgs.push(
"-Command",
startEditorServices);
} else {
// Use -EncodedCommand for better quote support on non-Windows
powerShellArgs.push(
"-EncodedCommand",
Buffer.from(startEditorServices, "utf16le").toString("base64"));
}

this.log.write(
"Language server starting --",
" PowerShell executable: " + this.exePath,
" PowerShell args: " + powerShellArgs.join(" "),
" PowerShell Editor Services args: " + startEditorServices);

// Make sure no old session file exists
utils.deleteSessionFile(this.sessionFilePath);

// Launch PowerShell in the integrated terminal
this.consoleTerminal =
vscode.window.createTerminal({
name: this.title,
shellPath: this.exePath,
shellArgs: powerShellArgs,
hideFromUser: !this.sessionSettings.integratedConsole.showOnStartup,
});

if (this.sessionSettings.integratedConsole.showOnStartup) {
// We still need to run this to set the active terminal to the Integrated Console.
this.consoleTerminal.show(true);
}

// Start the language client
utils.waitForSessionFile(
this.sessionFilePath,
(sessionDetails, error) => {
// Clean up the session file
utils.deleteSessionFile(this.sessionFilePath);

if (error) {
reject(error);
} else {
this.sessionDetails = sessionDetails;
resolve(this.sessionDetails);
}
});

this.consoleCloseSubscription =
vscode.window.onDidCloseTerminal(
(terminal) => {
if (terminal === this.consoleTerminal) {
this.log.write("powershell.exe terminated or terminal UI was closed");
this.onExitedEmitter.fire();
}
});

this.consoleTerminal.processId.then(
(pid) => { this.log.write(`powershell.exe started, pid: ${pid}`); });
} catch (e) {
reject(e);
}
public async start(logFileName: string): Promise<utils.IEditorServicesSessionDetails> {
const editorServicesLogPath = this.log.getLogFilePath(logFileName);

const psesModulePath =
path.resolve(
__dirname,
this.bundledModulesPath,
"PowerShellEditorServices/PowerShellEditorServices.psd1");

const featureFlags =
this.sessionSettings.developer.featureFlags !== undefined
? this.sessionSettings.developer.featureFlags.map((f) => `'${f}'`).join(", ")
: "";

this.startPsesArgs +=
`-LogPath '${PowerShellProcess.escapeSingleQuotes(editorServicesLogPath)}' ` +
`-SessionDetailsPath '${PowerShellProcess.escapeSingleQuotes(this.sessionFilePath)}' ` +
`-FeatureFlags @(${featureFlags}) `;

if (this.sessionSettings.integratedConsole.useLegacyReadLine) {
this.startPsesArgs += "-UseLegacyReadLine";
}

const powerShellArgs = [];

const useLoginShell: boolean =
(utils.isMacOS && this.sessionSettings.startAsLoginShell.osx)
|| (utils.isLinux && this.sessionSettings.startAsLoginShell.linux);

if (useLoginShell && this.isLoginShell(this.exePath)) {
// This MUST be the first argument.
powerShellArgs.push("-Login");
}

powerShellArgs.push("-NoProfile");
powerShellArgs.push("-NonInteractive");

// Only add ExecutionPolicy param on Windows
if (utils.isWindows) {
powerShellArgs.push("-ExecutionPolicy", "Bypass");
}

const startEditorServices = "Import-Module '" +
PowerShellProcess.escapeSingleQuotes(psesModulePath) +
"'; Start-EditorServices " + this.startPsesArgs;

if (utils.isWindows) {
powerShellArgs.push(
"-Command",
startEditorServices);
} else {
// Use -EncodedCommand for better quote support on non-Windows
powerShellArgs.push(
"-EncodedCommand",
Buffer.from(startEditorServices, "utf16le").toString("base64"));
}

this.log.write(
"Language server starting --",
" PowerShell executable: " + this.exePath,
" PowerShell args: " + powerShellArgs.join(" "),
" PowerShell Editor Services args: " + startEditorServices);

// Make sure no old session file exists
utils.deleteSessionFile(this.sessionFilePath);

// Launch PowerShell in the integrated terminal
this.consoleTerminal =
vscode.window.createTerminal({
name: this.title,
shellPath: this.exePath,
shellArgs: powerShellArgs,
hideFromUser: !this.sessionSettings.integratedConsole.showOnStartup,
});

if (this.sessionSettings.integratedConsole.showOnStartup) {
// We still need to run this to set the active terminal to the Integrated Console.
this.consoleTerminal.show(true);
}

// Start the language client
const sessionDetails = await this.waitForSessionFile();

// Subscribe a log event for when the terminal closes
this.consoleCloseSubscription = vscode.window.onDidCloseTerminal((terminal) => this.onTerminalClose(terminal));

// Log that the PowerShell terminal process has been started
const terminalPid = await this.consoleTerminal.processId;
const pwshName = path.basename(this.exePath);
this.log.write(`${pwshName} started, pid: ${terminalPid}`);

return sessionDetails;
}

public showConsole(preserveFocus: boolean) {
Expand Down Expand Up @@ -188,4 +165,27 @@ export class PowerShellProcess {

return true;
}

private waitForSessionFile(): Promise<utils.IEditorServicesSessionDetails> {
return new Promise((resolve, reject) => {
utils.waitForSessionFile(this.sessionFilePath, (sessionDetails, error) => {
utils.deleteSessionFile(this.sessionFilePath);

if (error) {
return reject(error);
}

resolve(sessionDetails);
});
});
}

private onTerminalClose(terminal: vscode.Terminal) {
if (terminal !== this.consoleTerminal) {
return;
}

this.log.write("powershell.exe terminated or terminal UI was closed");
this.onExitedEmitter.fire();
}
}