diff --git a/src/platform.ts b/src/platform.ts index 360fea1613..74f2bb94df 100644 --- a/src/platform.ts +++ b/src/platform.ts @@ -26,6 +26,10 @@ const SnapPreviewExePath = "/snap/bin/pwsh-preview"; const MacOSExePath = "/usr/local/bin/pwsh"; const MacOSPreviewExePath = "/usr/local/bin/pwsh-preview"; +const MacOSHomebrewExePath = "/opt/homebrew/bin/pwsh"; +const MacOSHomebrewLTSExePath = "/opt/homebrew/bin/pwsh-lts"; +const MacOSHomebrewPreviewExePath = "/opt/homebrew/bin/pwsh-preview"; + export enum OperatingSystem { Unknown, Windows, @@ -169,6 +173,7 @@ export class PowerShellExeFinder { * Iterates through all the possible well-known PowerShell installations on a machine. * Returned values may not exist, but come with an .exists property * which will check whether the executable exists. + * TODO: We really need to define the order in which we search for stable/LTS/preview/daily */ private async *enumerateDefaultPowerShellInstallations(): AsyncIterable { // Find PSCore stable first @@ -183,10 +188,14 @@ export class PowerShellExeFinder { case OperatingSystem.Windows: // Windows may have a 32-bit pwsh.exe yield this.findPSCoreWindowsInstallation({ useAlternateBitness: true }); - // Also look for the MSIX/UWP installation yield await this.findPSCoreMsix(); + break; + case OperatingSystem.MacOS: + // On MacOS, find the Homebrew installations + yield this.findPSCoreHomebrewStable(); + yield this.findPSCoreHomebrewLTS(); break; } @@ -220,6 +229,11 @@ export class PowerShellExeFinder { yield this.findWinPS({ useAlternateBitness: true }); break; + + case OperatingSystem.MacOS: + // On MacOS, find the Homebrew preview + yield this.findPSCoreHomebrewPreview(); + break; } // Look for PSCore daily @@ -336,6 +350,8 @@ export class PowerShellExeFinder { * if ($Daily) { * $Destination = "${Destination}-daily" * } + * + * TODO: Remove this after the daily is officially no longer supported. */ private findPSCoreDaily(): IPossiblePowerShellExe | undefined { switch (this.platformDetails.operatingSystem) { @@ -359,6 +375,19 @@ export class PowerShellExeFinder { } } + // The Homebrew installations of PowerShell on Apple Silicon are no longer in the default PATH. + private findPSCoreHomebrewStable(): IPossiblePowerShellExe { + return new PossiblePowerShellExe(MacOSHomebrewExePath, "PowerShell (Homebrew)"); + } + + private findPSCoreHomebrewLTS(): IPossiblePowerShellExe { + return new PossiblePowerShellExe(MacOSHomebrewLTSExePath, "PowerShell LTS (Homebrew)"); + } + + private findPSCoreHomebrewPreview(): IPossiblePowerShellExe { + return new PossiblePowerShellExe(MacOSHomebrewPreviewExePath, "PowerShell Preview (Homebrew)"); + } + private findPSCoreDotnetGlobalTool(): IPossiblePowerShellExe { const exeName: string = this.platformDetails.operatingSystem === OperatingSystem.Windows ? "pwsh.exe" @@ -398,6 +427,7 @@ export class PowerShellExeFinder { return undefined; } + // TODO: Are snaps still a thing? private findPSCoreStableSnap(): IPossiblePowerShellExe { return new PossiblePowerShellExe(SnapExePath, "PowerShell Snap"); } diff --git a/test/core/platform.test.ts b/test/core/platform.test.ts index 0953379639..f5c22941cc 100644 --- a/test/core/platform.test.ts +++ b/test/core/platform.test.ts @@ -595,11 +595,26 @@ if (process.platform === "win32") { displayName: "PowerShell", supportsProperArguments: true }, + { + exePath: "/opt/homebrew/bin/pwsh", + displayName: "PowerShell (Homebrew)", + supportsProperArguments: true + }, + { + exePath: "/opt/homebrew/bin/pwsh-lts", + displayName: "PowerShell LTS (Homebrew)", + supportsProperArguments: true + }, { exePath: "/usr/local/bin/pwsh-preview", displayName: "PowerShell Preview", supportsProperArguments: true }, + { + exePath: "/opt/homebrew/bin/pwsh-preview", + displayName: "PowerShell Preview (Homebrew)", + supportsProperArguments: true + }, { exePath: path.join(pwshDailyDir, "pwsh"), displayName: "PowerShell Daily", @@ -611,6 +626,11 @@ if (process.platform === "win32") { "pwsh": "", "pwsh-preview": "", }, + "/opt/homebrew/bin/": { + "pwsh": "", + "pwsh-lts": "", + "pwsh-preview": "", + }, [pwshDailyDir]: { "pwsh": "" }