From b64259cc2e0e4c88fcb153f8515b980271ce6992 Mon Sep 17 00:00:00 2001 From: Keith Hill Date: Wed, 13 Jun 2018 20:39:19 -0600 Subject: [PATCH 1/6] 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. --- src/platform.ts | 47 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/src/platform.ts b/src/platform.ts index 73e4bb1804..0ff5757769 100644 --- a/src/platform.ts +++ b/src/platform.ts @@ -3,12 +3,18 @@ *--------------------------------------------------------*/ import fs = require("fs"); -import os = require("os"); import path = require("path"); import process = require("process"); -import vscode = require("vscode"); import Settings = require("./settings"); +const linuxLegacyExePath = "/usr/bin/powershell"; +const linuxExePath = "/usr/bin/pwsh"; +const linuxPreviewExePath = "/usr/bin/pwsh-preview"; + +const macOSLegacyExePath = "/usr/local/bin/powershell"; +const macOSExePath = "/usr/local/bin/pwsh"; +const macOSPreviewExePath = "/usr/local/bin/pwsh-preview"; + export enum OperatingSystem { Unknown, Windows, @@ -68,14 +74,18 @@ export function getDefaultPowerShellPath( : SysnativePowerShellPath; } } else if (platformDetails.operatingSystem === OperatingSystem.MacOS) { - powerShellExePath = "/usr/local/bin/powershell"; - if (fs.existsSync("/usr/local/bin/pwsh")) { - powerShellExePath = "/usr/local/bin/pwsh"; + powerShellExePath = macOSLegacyExePath; + if (fs.existsSync(macOSExePath)) { + powerShellExePath = macOSExePath; + } else if (fs.existsSync(macOSPreviewExePath)) { + powerShellExePath = macOSPreviewExePath; } } else if (platformDetails.operatingSystem === OperatingSystem.Linux) { - powerShellExePath = "/usr/bin/powershell"; - if (fs.existsSync("/usr/bin/pwsh")) { - powerShellExePath = "/usr/bin/pwsh"; + powerShellExePath = linuxLegacyExePath; + if (fs.existsSync(linuxExePath)) { + powerShellExePath = linuxExePath; + } else if (fs.existsSync(linuxPreviewExePath)) { + powerShellExePath = linuxPreviewExePath; } } @@ -162,10 +172,29 @@ export function getAvailablePowerShellExes( } } else { // Handle Linux and macOS case + const defaultExePath = this.getDefaultPowerShellPath(platformDetails); paths.push({ versionName: "PowerShell Core", - exePath: this.getDefaultPowerShellPath(platformDetails), + exePath: defaultExePath, }); + + // If defaultExePath is pwsh, check to see if pwsh-preview is installed and if so, make it available. + // If the defaultExePath is already pwsh-preview, then pwsh is not installed - nothing to do. + if (platformDetails.operatingSystem === OperatingSystem.MacOS) { + if ((defaultExePath === macOSExePath) && fs.existsSync(macOSPreviewExePath)) { + paths.push({ + versionName: "PowerShell Core Preview", + exePath: macOSPreviewExePath, + }); + } + } else if (platformDetails.operatingSystem === OperatingSystem.Linux) { + if ((defaultExePath === linuxExePath) && fs.existsSync(linuxPreviewExePath)) { + paths.push({ + versionName: "PowerShell Core Preview", + exePath: linuxPreviewExePath, + }); + } + } } // When unit testing, we don't have session settings to test so skip reading this setting From 65d5a56b0a73a0720b14281193bbc5a941a6e4b8 Mon Sep 17 00:00:00 2001 From: Keith Hill Date: Wed, 13 Jun 2018 20:54:42 -0600 Subject: [PATCH 2/6] Adjust name of default PS Core on Linux/macOS --- src/platform.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform.ts b/src/platform.ts index 0ff5757769..d45af143fc 100644 --- a/src/platform.ts +++ b/src/platform.ts @@ -174,7 +174,7 @@ export function getAvailablePowerShellExes( // Handle Linux and macOS case const defaultExePath = this.getDefaultPowerShellPath(platformDetails); paths.push({ - versionName: "PowerShell Core", + versionName: "PowerShell Core" + (/-preview/.test(defaultExePath) ? " Preview" : ""), exePath: defaultExePath, }); From 2ef97e43a52e8b92d267da8b00284647560caf79 Mon Sep 17 00:00:00 2001 From: Keith Hill Date: Thu, 14 Jun 2018 14:46:55 -0600 Subject: [PATCH 3/6] Make a bit DRY-er. Thx @tylerl0706 --- src/platform.ts | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/platform.ts b/src/platform.ts index d45af143fc..6535208b67 100644 --- a/src/platform.ts +++ b/src/platform.ts @@ -180,20 +180,21 @@ export function getAvailablePowerShellExes( // If defaultExePath is pwsh, check to see if pwsh-preview is installed and if so, make it available. // If the defaultExePath is already pwsh-preview, then pwsh is not installed - nothing to do. + let osExePath; + let osPreviewExePath; if (platformDetails.operatingSystem === OperatingSystem.MacOS) { - if ((defaultExePath === macOSExePath) && fs.existsSync(macOSPreviewExePath)) { - paths.push({ - versionName: "PowerShell Core Preview", - exePath: macOSPreviewExePath, - }); - } + osExePath = macOSExePath; + osPreviewExePath = macOSPreviewExePath; } else if (platformDetails.operatingSystem === OperatingSystem.Linux) { - if ((defaultExePath === linuxExePath) && fs.existsSync(linuxPreviewExePath)) { - paths.push({ - versionName: "PowerShell Core Preview", - exePath: linuxPreviewExePath, - }); - } + osExePath = linuxExePath; + osPreviewExePath = linuxPreviewExePath; + } + + if ((osExePath === defaultExePath) && fs.existsSync(osPreviewExePath)) { + paths.push({ + versionName: "PowerShell Core Preview", + exePath: osPreviewExePath, + }); } } From fc22305cd84214843f0378f6bb5bdeba54d016ae Mon Sep 17 00:00:00 2001 From: Keith Hill Date: Mon, 18 Jun 2018 19:55:48 -0600 Subject: [PATCH 4/6] Remove support for pre-ship PS Core Linux/macOS binary name - powershell --- src/platform.ts | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/platform.ts b/src/platform.ts index 6535208b67..4d4113e66f 100644 --- a/src/platform.ts +++ b/src/platform.ts @@ -7,11 +7,9 @@ import path = require("path"); import process = require("process"); import Settings = require("./settings"); -const linuxLegacyExePath = "/usr/bin/powershell"; const linuxExePath = "/usr/bin/pwsh"; const linuxPreviewExePath = "/usr/bin/pwsh-preview"; -const macOSLegacyExePath = "/usr/local/bin/powershell"; const macOSExePath = "/usr/local/bin/pwsh"; const macOSPreviewExePath = "/usr/local/bin/pwsh-preview"; @@ -53,6 +51,13 @@ export function getPlatformDetails(): IPlatformDetails { }; } +/** + * Gets the default instance of PowerShell for the specified platform. + * On Windows, the default version of PowerShell is "Windows PowerShell". + * @param platformDetails Specifies information about the platform - primarily the operating system. + * @param use32Bit On Windows, this boolean determines will find the 32-bit version of Windows PowerShell. + * @returns A string containing the path of the default version of PowerShell. + */ export function getDefaultPowerShellPath( platformDetails: IPlatformDetails, use32Bit: boolean = false): string | null { @@ -74,17 +79,15 @@ export function getDefaultPowerShellPath( : SysnativePowerShellPath; } } else if (platformDetails.operatingSystem === OperatingSystem.MacOS) { - powerShellExePath = macOSLegacyExePath; - if (fs.existsSync(macOSExePath)) { - powerShellExePath = macOSExePath; - } else if (fs.existsSync(macOSPreviewExePath)) { + // Always default to the stable version of PowerShell (if installed) but handle case of only Preview installed + powerShellExePath = macOSExePath; + if (!fs.existsSync(macOSExePath) && fs.existsSync(macOSPreviewExePath)) { powerShellExePath = macOSPreviewExePath; } } else if (platformDetails.operatingSystem === OperatingSystem.Linux) { - powerShellExePath = linuxLegacyExePath; - if (fs.existsSync(linuxExePath)) { - powerShellExePath = linuxExePath; - } else if (fs.existsSync(linuxPreviewExePath)) { + // Always default to the stable version of PowerShell (if installed) but handle case of only Preview installed + powerShellExePath = linuxExePath; + if (!fs.existsSync(linuxExePath) && fs.existsSync(linuxPreviewExePath)) { powerShellExePath = linuxPreviewExePath; } } @@ -118,6 +121,12 @@ export function fixWindowsPowerShellPath(powerShellExePath: string, platformDeta return powerShellExePath; } +/** + * Gets a list of all available PowerShell instance on the specified platform. + * @param platformDetails Specifies information about the platform - primarily the operating system. + * @param sessionSettings Specifies the user/workspace settings. Additional PowerShell exe paths loaded from settings. + * @returns An array of IPowerShellExeDetails objects with the PowerShell name & exe path for each instance found. + */ export function getAvailablePowerShellExes( platformDetails: IPlatformDetails, sessionSettings: Settings.ISettings | undefined): IPowerShellExeDetails[] { @@ -178,7 +187,7 @@ export function getAvailablePowerShellExes( exePath: defaultExePath, }); - // If defaultExePath is pwsh, check to see if pwsh-preview is installed and if so, make it available. + // If defaultExePath is pwsh, check to see if pwsh-preview is also installed and if so, make it available. // If the defaultExePath is already pwsh-preview, then pwsh is not installed - nothing to do. let osExePath; let osPreviewExePath; From d85f94326e725c332a2940b368c3026a8950c5e8 Mon Sep 17 00:00:00 2001 From: Keith Hill Date: Wed, 27 Jun 2018 20:32:46 -0600 Subject: [PATCH 5/6] Add support for PowerShell Core installed in a Snap --- src/platform.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/platform.ts b/src/platform.ts index 4d4113e66f..0e9fb2db2f 100644 --- a/src/platform.ts +++ b/src/platform.ts @@ -10,6 +10,9 @@ import Settings = require("./settings"); const linuxExePath = "/usr/bin/pwsh"; const linuxPreviewExePath = "/usr/bin/pwsh-preview"; +const snapExePath = "/snap/bin/pwsh"; +const snapPreviewExePath = "/snap/bin/pwsh-preview"; + const macOSExePath = "/usr/local/bin/pwsh"; const macOSPreviewExePath = "/usr/local/bin/pwsh-preview"; @@ -86,9 +89,14 @@ export function getDefaultPowerShellPath( } } else if (platformDetails.operatingSystem === OperatingSystem.Linux) { // Always default to the stable version of PowerShell (if installed) but handle case of only Preview installed + // as well as the Snaps case - https://snapcraft.io/ powerShellExePath = linuxExePath; if (!fs.existsSync(linuxExePath) && fs.existsSync(linuxPreviewExePath)) { powerShellExePath = linuxPreviewExePath; + } else if (fs.existsSync(snapExePath)) { + powerShellExePath = snapExePath; + } else if (fs.existsSync(snapPreviewExePath)) { + powerShellExePath = snapPreviewExePath; } } @@ -196,7 +204,7 @@ export function getAvailablePowerShellExes( osPreviewExePath = macOSPreviewExePath; } else if (platformDetails.operatingSystem === OperatingSystem.Linux) { osExePath = linuxExePath; - osPreviewExePath = linuxPreviewExePath; + osPreviewExePath = fs.existsSync(linuxPreviewExePath) ? linuxPreviewExePath : snapPreviewExePath; } if ((osExePath === defaultExePath) && fs.existsSync(osPreviewExePath)) { From 7545dfda243fcc07383d54ca5c3c16b2c24b701b Mon Sep 17 00:00:00 2001 From: Keith Hill Date: Sun, 1 Jul 2018 17:43:59 -0600 Subject: [PATCH 6/6] Simplify impl of getting available PS on Linux/macOS --- src/platform.ts | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/src/platform.ts b/src/platform.ts index 0e9fb2db2f..eb6146fb9a 100644 --- a/src/platform.ts +++ b/src/platform.ts @@ -58,7 +58,7 @@ export function getPlatformDetails(): IPlatformDetails { * Gets the default instance of PowerShell for the specified platform. * On Windows, the default version of PowerShell is "Windows PowerShell". * @param platformDetails Specifies information about the platform - primarily the operating system. - * @param use32Bit On Windows, this boolean determines will find the 32-bit version of Windows PowerShell. + * @param use32Bit On Windows, this boolean determines whether the 32-bit version of Windows PowerShell is returned. * @returns A string containing the path of the default version of PowerShell. */ export function getDefaultPowerShellPath( @@ -189,33 +189,25 @@ export function getAvailablePowerShellExes( } } else { // Handle Linux and macOS case - const defaultExePath = this.getDefaultPowerShellPath(platformDetails); - paths.push({ - versionName: "PowerShell Core" + (/-preview/.test(defaultExePath) ? " Preview" : ""), - exePath: defaultExePath, - }); + let exePaths: string[]; - // If defaultExePath is pwsh, check to see if pwsh-preview is also installed and if so, make it available. - // If the defaultExePath is already pwsh-preview, then pwsh is not installed - nothing to do. - let osExePath; - let osPreviewExePath; - if (platformDetails.operatingSystem === OperatingSystem.MacOS) { - osExePath = macOSExePath; - osPreviewExePath = macOSPreviewExePath; - } else if (platformDetails.operatingSystem === OperatingSystem.Linux) { - osExePath = linuxExePath; - osPreviewExePath = fs.existsSync(linuxPreviewExePath) ? linuxPreviewExePath : snapPreviewExePath; + if (platformDetails.operatingSystem === OperatingSystem.Linux) { + exePaths = [ linuxExePath, snapExePath, linuxPreviewExePath, snapPreviewExePath ]; + } else { + exePaths = [ macOSExePath, macOSPreviewExePath ]; } - if ((osExePath === defaultExePath) && fs.existsSync(osPreviewExePath)) { - paths.push({ - versionName: "PowerShell Core Preview", - exePath: osPreviewExePath, - }); - } + exePaths.forEach((exePath) => { + if (fs.existsSync(exePath)) { + paths.push({ + versionName: "PowerShell Core" + (/-preview/.test(exePath) ? " Preview" : ""), + exePath, + }); + } + }); } - // When unit testing, we don't have session settings to test so skip reading this setting + // When unit testing, we don't have session settings available to test, so skip reading this setting if (sessionSettings) { // Add additional PowerShell paths as configured in settings for (const additionalPowerShellExePath of sessionSettings.powerShellAdditionalExePaths) {