Skip to content

Commit ce9f6d7

Browse files
committed
Enhance additionalPowerShellExes setting
Now the warning that's emitted when an additional PowerShell executable isn't found can be suppressed with a setting. If the setting's value has single or double quotes, it handles it. If the executable name wasn't appended, it handles it. Smarter!
1 parent d24725c commit ce9f6d7

File tree

4 files changed

+51
-7
lines changed

4 files changed

+51
-7
lines changed

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,11 @@
669669
"markdownDescription": "**Deprecated:** Specifies whether you should be prompted to update your version of `PackageManagement` if it's under 1.4.6.",
670670
"markdownDeprecationMessage": "**Deprecated:** This prompt has been removed as it's no longer strictly necessary to upgrade the `PackageManagement` module."
671671
},
672+
"powershell.suppressAdditionalExeNotFoundWarning": {
673+
"type": "boolean",
674+
"default": false,
675+
"markdownDescription": "Suppresses the warning message when any of `#powershell.powerShellAdditionalExePaths#` is not found."
676+
},
672677
"powershell.startAsLoginShell.osx": {
673678
"type": "boolean",
674679
"default": true,

src/platform.ts

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
import * as os from "os";
55
import * as path from "path";
66
import * as process from "process";
7+
import vscode = require("vscode");
78
import { integer } from "vscode-languageserver-protocol";
89
import { ILogger } from "./logging";
9-
import { PowerShellAdditionalExePathSettings } from "./settings";
10+
import { changeSetting, getSettings, PowerShellAdditionalExePathSettings } from "./settings";
1011

1112
// This uses require so we can rewire it in unit tests!
1213
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-var-requires
@@ -41,6 +42,7 @@ export interface IPowerShellExeDetails {
4142
readonly displayName: string;
4243
readonly exePath: string;
4344
readonly supportsProperArguments: boolean;
45+
readonly suppressWarning: boolean;
4446
}
4547

4648
export function getPlatformDetails(): IPlatformDetails {
@@ -149,8 +151,12 @@ export class PowerShellExeFinder {
149151
for (const additionalPwsh of this.enumerateAdditionalPowerShellInstallations()) {
150152
if (await additionalPwsh.exists()) {
151153
yield additionalPwsh;
152-
} else {
153-
void this.logger.writeAndShowWarning(`Additional PowerShell '${additionalPwsh.displayName}' not found at '${additionalPwsh.exePath}'!`);
154+
} else if (!additionalPwsh.suppressWarning
155+
&& !getSettings().suppressAdditionalExeNotFoundWarning) {
156+
const selection = await vscode.window.showWarningMessage(`Additional PowerShell '${additionalPwsh.displayName}' not found at '${additionalPwsh.exePath}'!`, "Don't Show Again");
157+
if (selection !== undefined) {
158+
await changeSetting("suppressAdditionalExeNotFoundWarning", true, true, this.logger);
159+
}
154160
}
155161
}
156162
}
@@ -223,9 +229,39 @@ export class PowerShellExeFinder {
223229
private *enumerateAdditionalPowerShellInstallations(): Iterable<IPossiblePowerShellExe> {
224230
for (const versionName in this.additionalPowerShellExes) {
225231
if (Object.prototype.hasOwnProperty.call(this.additionalPowerShellExes, versionName)) {
226-
const exePath = this.additionalPowerShellExes[versionName];
227-
if (exePath) {
228-
yield new PossiblePowerShellExe(exePath, versionName);
232+
let exePath = this.additionalPowerShellExes[versionName];
233+
if (!exePath) {
234+
continue;
235+
}
236+
237+
// Remove surrounding quotes from path (without regex)
238+
if (exePath.startsWith("'") && exePath.endsWith("'")
239+
|| exePath.startsWith("\"") && exePath.endsWith("\"")) {
240+
exePath = exePath.slice(1, -1);
241+
}
242+
243+
// Always search for what the user gave us first
244+
yield new PossiblePowerShellExe(exePath, versionName);
245+
246+
// Also search for `pwsh[.exe]` and `powershell[.exe]` if missing
247+
const args: [string, undefined, boolean, boolean]
248+
// Must be a tuple type and is suppressing the warning
249+
= [versionName, undefined, true, true];
250+
251+
// Handle Windows where '.exe' and 'powershell' are things
252+
if (this.platformDetails.operatingSystem === OperatingSystem.Windows) {
253+
if (!exePath.endsWith("pwsh.exe") && !exePath.endsWith("powershell.exe")) {
254+
if (exePath.endsWith("pwsh") || exePath.endsWith("powershell")) {
255+
// Add extension if that was missing
256+
yield new PossiblePowerShellExe(exePath + ".exe", ...args);
257+
}
258+
// Also add full exe names (this isn't an else just in case
259+
// the folder was named "pwsh" or "powershell")
260+
yield new PossiblePowerShellExe(exePath + "\\pwsh.exe", ...args);
261+
yield new PossiblePowerShellExe(exePath + "\\powershell.exe", ...args);
262+
}
263+
} else if (!exePath.endsWith("pwsh")) { // Always just 'pwsh' on non-Windows
264+
yield new PossiblePowerShellExe(exePath + "/pwsh", ...args);
229265
}
230266
}
231267
}
@@ -536,7 +572,8 @@ class PossiblePowerShellExe implements IPossiblePowerShellExe {
536572
public readonly exePath: string,
537573
public readonly displayName: string,
538574
private knownToExist?: boolean,
539-
public readonly supportsProperArguments = true) { }
575+
public readonly supportsProperArguments = true,
576+
public readonly suppressWarning = false) { }
540577

541578
public async exists(): Promise<boolean> {
542579
if (this.knownToExist === undefined) {

src/session.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,7 @@ Type 'help' to get help.
952952
this.platformDetails,
953953
// We don't pull from session settings because we want them fresh!
954954
getSettings().powerShellAdditionalExePaths,
955+
true, // Only show warning on initialization.
955956
this.logger);
956957
const availablePowerShellExes = await powershellExeFinder.getAllAvailablePowerShellInstallations();
957958

src/settings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export class Settings extends PartialSettings {
2323
// This setting is no longer used but is here to assist in cleaning up the users settings.
2424
powerShellExePath = "";
2525
promptToUpdatePowerShell = true;
26+
suppressAdditionalExeNotFoundWarning = false;
2627
startAsLoginShell = new StartAsLoginShellSettings();
2728
startAutomatically = true;
2829
enableProfileLoading = true;

0 commit comments

Comments
 (0)