Skip to content

Commit 0c7c1bd

Browse files
authored
WIP: Add support for side-by-side PS Core preview on Linux/macOS (#1366)
* Add support for side-by-side PS Core preview on Linux/macOS This PR supports listing the symlinks for pwsh & pwsh-preview. The preferred default version is pwsh if both are present however, the default will be pwsh-preview if it's installed and pwsh isn't. So this only support side-by-side on Linux/macOS up to two versions: stable and preview. * Adjust name of default PS Core on Linux/macOS * Make a bit DRY-er. Thx @tylerl0706 * Remove support for pre-ship PS Core Linux/macOS binary name - powershell * Add support for PowerShell Core installed in a Snap * Simplify impl of getting available PS on Linux/macOS
1 parent 31ff94e commit 0c7c1bd

File tree

1 file changed

+51
-12
lines changed

1 file changed

+51
-12
lines changed

src/platform.ts

+51-12
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,19 @@
33
*--------------------------------------------------------*/
44

55
import fs = require("fs");
6-
import os = require("os");
76
import path = require("path");
87
import process = require("process");
9-
import vscode = require("vscode");
108
import Settings = require("./settings");
119

10+
const linuxExePath = "/usr/bin/pwsh";
11+
const linuxPreviewExePath = "/usr/bin/pwsh-preview";
12+
13+
const snapExePath = "/snap/bin/pwsh";
14+
const snapPreviewExePath = "/snap/bin/pwsh-preview";
15+
16+
const macOSExePath = "/usr/local/bin/pwsh";
17+
const macOSPreviewExePath = "/usr/local/bin/pwsh-preview";
18+
1219
export enum OperatingSystem {
1320
Unknown,
1421
Windows,
@@ -47,6 +54,13 @@ export function getPlatformDetails(): IPlatformDetails {
4754
};
4855
}
4956

57+
/**
58+
* Gets the default instance of PowerShell for the specified platform.
59+
* On Windows, the default version of PowerShell is "Windows PowerShell".
60+
* @param platformDetails Specifies information about the platform - primarily the operating system.
61+
* @param use32Bit On Windows, this boolean determines whether the 32-bit version of Windows PowerShell is returned.
62+
* @returns A string containing the path of the default version of PowerShell.
63+
*/
5064
export function getDefaultPowerShellPath(
5165
platformDetails: IPlatformDetails,
5266
use32Bit: boolean = false): string | null {
@@ -68,14 +82,21 @@ export function getDefaultPowerShellPath(
6882
: SysnativePowerShellPath;
6983
}
7084
} else if (platformDetails.operatingSystem === OperatingSystem.MacOS) {
71-
powerShellExePath = "/usr/local/bin/powershell";
72-
if (fs.existsSync("/usr/local/bin/pwsh")) {
73-
powerShellExePath = "/usr/local/bin/pwsh";
85+
// Always default to the stable version of PowerShell (if installed) but handle case of only Preview installed
86+
powerShellExePath = macOSExePath;
87+
if (!fs.existsSync(macOSExePath) && fs.existsSync(macOSPreviewExePath)) {
88+
powerShellExePath = macOSPreviewExePath;
7489
}
7590
} else if (platformDetails.operatingSystem === OperatingSystem.Linux) {
76-
powerShellExePath = "/usr/bin/powershell";
77-
if (fs.existsSync("/usr/bin/pwsh")) {
78-
powerShellExePath = "/usr/bin/pwsh";
91+
// Always default to the stable version of PowerShell (if installed) but handle case of only Preview installed
92+
// as well as the Snaps case - https://snapcraft.io/
93+
powerShellExePath = linuxExePath;
94+
if (!fs.existsSync(linuxExePath) && fs.existsSync(linuxPreviewExePath)) {
95+
powerShellExePath = linuxPreviewExePath;
96+
} else if (fs.existsSync(snapExePath)) {
97+
powerShellExePath = snapExePath;
98+
} else if (fs.existsSync(snapPreviewExePath)) {
99+
powerShellExePath = snapPreviewExePath;
79100
}
80101
}
81102

@@ -108,6 +129,12 @@ export function fixWindowsPowerShellPath(powerShellExePath: string, platformDeta
108129
return powerShellExePath;
109130
}
110131

132+
/**
133+
* Gets a list of all available PowerShell instance on the specified platform.
134+
* @param platformDetails Specifies information about the platform - primarily the operating system.
135+
* @param sessionSettings Specifies the user/workspace settings. Additional PowerShell exe paths loaded from settings.
136+
* @returns An array of IPowerShellExeDetails objects with the PowerShell name & exe path for each instance found.
137+
*/
111138
export function getAvailablePowerShellExes(
112139
platformDetails: IPlatformDetails,
113140
sessionSettings: Settings.ISettings | undefined): IPowerShellExeDetails[] {
@@ -162,13 +189,25 @@ export function getAvailablePowerShellExes(
162189
}
163190
} else {
164191
// Handle Linux and macOS case
165-
paths.push({
166-
versionName: "PowerShell Core",
167-
exePath: this.getDefaultPowerShellPath(platformDetails),
192+
let exePaths: string[];
193+
194+
if (platformDetails.operatingSystem === OperatingSystem.Linux) {
195+
exePaths = [ linuxExePath, snapExePath, linuxPreviewExePath, snapPreviewExePath ];
196+
} else {
197+
exePaths = [ macOSExePath, macOSPreviewExePath ];
198+
}
199+
200+
exePaths.forEach((exePath) => {
201+
if (fs.existsSync(exePath)) {
202+
paths.push({
203+
versionName: "PowerShell Core" + (/-preview/.test(exePath) ? " Preview" : ""),
204+
exePath,
205+
});
206+
}
168207
});
169208
}
170209

171-
// When unit testing, we don't have session settings to test so skip reading this setting
210+
// When unit testing, we don't have session settings available to test, so skip reading this setting
172211
if (sessionSettings) {
173212
// Add additional PowerShell paths as configured in settings
174213
for (const additionalPowerShellExePath of sessionSettings.powerShellAdditionalExePaths) {

0 commit comments

Comments
 (0)