@@ -7,6 +7,7 @@ import { isWindows } from '../../../../common/utils/platformUtils';
77import { ShellScriptEditState , ShellSetupState , ShellStartupScriptProvider } from '../startupProvider' ;
88import { runCommand } from '../utils' ;
99
10+ import assert from 'assert' ;
1011import { getGlobalPersistentState } from '../../../../common/persistentState' ;
1112import { ShellConstants } from '../../../common/shellConstants' ;
1213import { hasStartupCode , insertStartupCode , removeStartupCode } from '../common/editUtils' ;
@@ -185,130 +186,134 @@ async function removePowerShellStartup(shell: string, profile: string): Promise<
185186 }
186187}
187188
188- export class PowerShellClassicStartupProvider implements ShellStartupScriptProvider {
189- public readonly name : string = 'PowerShell5' ;
190- public readonly shellType : string = 'powershell' ;
191- private _isInstalled : boolean | undefined ;
189+ type PowerShellType = 'powershell' | 'pwsh' ;
192190
193- private async checkInstallation ( ) : Promise < boolean > {
194- if ( this . _isInstalled === undefined ) {
195- this . _isInstalled = await isPowerShellInstalled ( 'powershell' ) ;
196- }
197- return this . _isInstalled ;
198- }
199- async isSetup ( ) : Promise < ShellSetupState > {
200- const isInstalled = await this . checkInstallation ( ) ;
201- if ( ! isInstalled ) {
202- return ShellSetupState . NotInstalled ;
203- }
191+ export class PwshStartupProvider implements ShellStartupScriptProvider {
192+ public readonly name : string = 'PowerShell' ;
193+ public readonly shellType : string = ShellConstants . PWSH ;
204194
205- try {
206- const profile = await getProfileForShell ( 'powershell' ) ;
207- const isSetup = await isPowerShellStartupSetup ( 'powershell' , profile ) ;
208- return isSetup ? ShellSetupState . Setup : ShellSetupState . NotSetup ;
209- } catch ( err ) {
210- traceError ( 'Failed to check if PowerShell startup is setup' , err ) ;
211- }
212- return ShellSetupState . NotSetup ;
195+ private _isPwshInstalled : boolean | undefined ;
196+ private _isPs5Installed : boolean | undefined ;
197+ private _supportedShells : PowerShellType [ ] ;
198+
199+ constructor ( supportedShells : PowerShellType [ ] ) {
200+ assert ( supportedShells . length > 0 , 'At least one PowerShell shell must be supported' ) ;
201+ this . _supportedShells = supportedShells ;
213202 }
214203
215- async setupScripts ( ) : Promise < ShellScriptEditState > {
216- const isInstalled = await this . checkInstallation ( ) ;
217- if ( ! isInstalled ) {
218- return ShellScriptEditState . NotInstalled ;
219- }
204+ private async checkInstallations ( ) : Promise < Map < PowerShellType , boolean > > {
205+ const results = new Map < PowerShellType , boolean > ( ) ;
220206
221- try {
222- const profile = await getProfileForShell ( 'powershell' ) ;
223- const success = await setupPowerShellStartup ( 'powershell' , profile ) ;
224- return success ? ShellScriptEditState . Edited : ShellScriptEditState . NotEdited ;
225- } catch ( err ) {
226- traceError ( 'Failed to setup PowerShell startup' , err ) ;
227- }
228- return ShellScriptEditState . NotEdited ;
207+ await Promise . all (
208+ this . _supportedShells . map ( async ( shell ) => {
209+ if ( shell === 'pwsh' && this . _isPwshInstalled !== undefined ) {
210+ results . set ( shell , this . _isPwshInstalled ) ;
211+ } else if ( shell === 'powershell' && this . _isPs5Installed !== undefined ) {
212+ results . set ( shell , this . _isPs5Installed ) ;
213+ } else {
214+ const isInstalled = await isPowerShellInstalled ( shell ) ;
215+ if ( shell === 'pwsh' ) {
216+ this . _isPwshInstalled = isInstalled ;
217+ } else {
218+ this . _isPs5Installed = isInstalled ;
219+ }
220+ results . set ( shell , isInstalled ) ;
221+ }
222+ } ) ,
223+ ) ;
224+
225+ return results ;
229226 }
230227
231- async teardownScripts ( ) : Promise < ShellScriptEditState > {
232- const isInstalled = await this . checkInstallation ( ) ;
233- if ( ! isInstalled ) {
234- return ShellScriptEditState . NotInstalled ;
235- }
228+ async isSetup ( ) : Promise < ShellSetupState > {
229+ const installations = await this . checkInstallations ( ) ;
236230
237- try {
238- const profile = await getProfileForShell ( 'powershell' ) ;
239- const success = await removePowerShellStartup ( 'powershell' , profile ) ;
240- return success ? ShellScriptEditState . Edited : ShellScriptEditState . NotEdited ;
241- } catch ( err ) {
242- traceError ( 'Failed to remove PowerShell startup' , err ) ;
231+ if ( Array . from ( installations . values ( ) ) . every ( ( installed ) => ! installed ) ) {
232+ return ShellSetupState . NotInstalled ;
243233 }
244- return ShellScriptEditState . NotEdited ;
245- }
246- async clearCache ( ) : Promise < void > {
247- await clearPwshCache ( 'powershell' ) ;
248- }
249- }
250-
251- export class PwshStartupProvider implements ShellStartupScriptProvider {
252- public readonly name : string = 'PowerShell' ;
253- public readonly shellType : string = ShellConstants . PWSH ;
254234
255- private _isInstalled : boolean | undefined ;
235+ const results : ShellSetupState [ ] = [ ] ;
236+ for ( const [ shell , installed ] of installations . entries ( ) ) {
237+ if ( ! installed ) {
238+ continue ;
239+ }
256240
257- private async checkInstallation ( ) : Promise < boolean > {
258- if ( this . _isInstalled === undefined ) {
259- this . _isInstalled = await isPowerShellInstalled ( 'pwsh' ) ;
241+ try {
242+ const profile = await getProfileForShell ( shell ) ;
243+ const isSetup = await isPowerShellStartupSetup ( shell , profile ) ;
244+ results . push ( isSetup ? ShellSetupState . Setup : ShellSetupState . NotSetup ) ;
245+ } catch ( err ) {
246+ traceError ( `Failed to check if ${ shell } startup is setup` , err ) ;
247+ results . push ( ShellSetupState . NotSetup ) ;
248+ }
260249 }
261- return this . _isInstalled ;
262- }
263250
264- async isSetup ( ) : Promise < ShellSetupState > {
265- const isInstalled = await this . checkInstallation ( ) ;
266- if ( ! isInstalled ) {
267- return ShellSetupState . NotInstalled ;
251+ if ( results . includes ( ShellSetupState . NotSetup ) ) {
252+ return ShellSetupState . NotSetup ;
268253 }
269254
270- try {
271- const profile = await getProfileForShell ( 'pwsh' ) ;
272- const isSetup = await isPowerShellStartupSetup ( 'pwsh' , profile ) ;
273- return isSetup ? ShellSetupState . Setup : ShellSetupState . NotSetup ;
274- } catch ( err ) {
275- traceError ( 'Failed to check if PowerShell startup is setup' , err ) ;
276- }
277- return ShellSetupState . NotSetup ;
255+ return ShellSetupState . Setup ;
278256 }
279257
280258 async setupScripts ( ) : Promise < ShellScriptEditState > {
281- const isInstalled = await this . checkInstallation ( ) ;
282- if ( ! isInstalled ) {
259+ const installations = await this . checkInstallations ( ) ;
260+
261+ if ( Array . from ( installations . values ( ) ) . every ( ( installed ) => ! installed ) ) {
283262 return ShellScriptEditState . NotInstalled ;
284263 }
285264
286- try {
287- const profile = await getProfileForShell ( 'pwsh' ) ;
288- const success = await setupPowerShellStartup ( 'pwsh' , profile ) ;
289- return success ? ShellScriptEditState . Edited : ShellScriptEditState . NotEdited ;
290- } catch ( err ) {
291- traceError ( 'Failed to setup PowerShell startup' , err ) ;
265+ const anyEdited = [ ] ;
266+ for ( const [ shell , installed ] of installations . entries ( ) ) {
267+ if ( ! installed ) {
268+ continue ;
269+ }
270+
271+ try {
272+ const profile = await getProfileForShell ( shell ) ;
273+ const success = await setupPowerShellStartup ( shell , profile ) ;
274+ anyEdited . push ( success ? ShellScriptEditState . Edited : ShellScriptEditState . NotEdited ) ;
275+ } catch ( err ) {
276+ traceError ( `Failed to setup ${ shell } startup` , err ) ;
277+ }
292278 }
293- return ShellScriptEditState . NotEdited ;
279+ return anyEdited . every ( ( state ) => state === ShellScriptEditState . Edited )
280+ ? ShellScriptEditState . Edited
281+ : ShellScriptEditState . NotEdited ;
294282 }
295283
296284 async teardownScripts ( ) : Promise < ShellScriptEditState > {
297- const isInstalled = await this . checkInstallation ( ) ;
298- if ( ! isInstalled ) {
285+ const installations = await this . checkInstallations ( ) ;
286+
287+ if ( Array . from ( installations . values ( ) ) . every ( ( installed ) => ! installed ) ) {
299288 return ShellScriptEditState . NotInstalled ;
300289 }
301290
302- try {
303- const profile = await getProfileForShell ( 'pwsh' ) ;
304- const success = await removePowerShellStartup ( 'pwsh' , profile ) ;
305- return success ? ShellScriptEditState . Edited : ShellScriptEditState . NotEdited ;
306- } catch ( err ) {
307- traceError ( 'Failed to remove PowerShell startup' , err ) ;
291+ const anyEdited = [ ] ;
292+ for ( const [ shell , installed ] of installations . entries ( ) ) {
293+ if ( ! installed ) {
294+ continue ;
295+ }
296+
297+ try {
298+ const profile = await getProfileForShell ( shell ) ;
299+ const success = await removePowerShellStartup ( shell , profile ) ;
300+ anyEdited . push ( success ? ShellScriptEditState . Edited : ShellScriptEditState . NotEdited ) ;
301+ } catch ( err ) {
302+ traceError ( `Failed to remove ${ shell } startup` , err ) ;
303+ }
308304 }
309- return ShellScriptEditState . NotEdited ;
305+ return anyEdited . every ( ( state ) => state === ShellScriptEditState . Edited )
306+ ? ShellScriptEditState . Edited
307+ : ShellScriptEditState . NotEdited ;
310308 }
309+
311310 async clearCache ( ) : Promise < void > {
312- await clearPwshCache ( 'pwsh' ) ;
311+ for ( const shell of this . _supportedShells ) {
312+ await clearPwshCache ( shell ) ;
313+ }
314+
315+ // Reset installation check cache as well
316+ this . _isPwshInstalled = undefined ;
317+ this . _isPs5Installed = undefined ;
313318 }
314319}
0 commit comments