1- import { Disposable , Uri } from 'vscode' ;
1+ import { Disposable , l10n , Uri } from 'vscode' ;
22import { EnvironmentManagers , PythonProjectManager } from '../../internal.api' ;
33import { createDeferred , Deferred } from '../../common/utils/deferred' ;
44import { allExtensions } from '../../common/extension.apis' ;
5- import { traceError } from '../../common/logging' ;
5+ import { traceError , traceInfo } from '../../common/logging' ;
66import { showErrorMessage } from '../../common/window.apis' ;
77import { getDefaultEnvManagerSetting , getDefaultPkgManagerSetting } from '../settings/settingHelpers' ;
8+ import { WorkbenchStrings } from '../../common/localize' ;
9+ import { installExtension } from '../../common/workbenchCommands' ;
810
911interface ManagerReady extends Disposable {
1012 waitForEnvManager ( uris ?: Uri [ ] ) : Promise < void > ;
13+ waitForEnvManagerId ( managerIds : string [ ] ) : Promise < void > ;
14+ waitForAllEnvManagers ( ) : Promise < void > ;
1115 waitForPkgManager ( uris ?: Uri [ ] ) : Promise < void > ;
16+ waitForPkgManagerId ( managerIds : string [ ] ) : Promise < void > ;
17+ }
18+
19+ function getExtensionId ( managerId : string ) : string | undefined {
20+ // format <extension-id>:<manager-name>
21+ const regex = / ^ ( .* ) : ( [ a - z A - Z 0 - 9 - _ ] * ) $ / ;
22+ const parts = regex . exec ( managerId ) ;
23+ return parts ? parts [ 1 ] : undefined ;
1224}
1325
1426class ManagerReadyImpl implements ManagerReady {
@@ -44,10 +56,30 @@ class ManagerReadyImpl implements ManagerReady {
4456 const installed = allExtensions ( ) . some ( ( ext ) => managerId . startsWith ( `${ ext . id } :` ) ) ;
4557 if ( ! installed && ! this . checked . has ( managerId ) ) {
4658 this . checked . add ( managerId ) ;
47- traceError ( `Extension for manager ${ managerId } is not installed.` ) ;
48- showErrorMessage ( `Extension for manager ${ managerId } is not installed.` ) ;
59+ const extId = getExtensionId ( managerId ) ;
60+ setImmediate ( async ( ) => {
61+ if ( extId ) {
62+ traceError ( `Extension for manager ${ extId } is not installed.` ) ;
63+ const result = await showErrorMessage (
64+ l10n . t ( `Extension for {0} is not installed or enabled for this workspace.` , extId ) ,
65+ WorkbenchStrings . installExtension ,
66+ ) ;
67+ if ( result === WorkbenchStrings . installExtension ) {
68+ traceInfo ( `Installing extension: ${ extId } ` ) ;
69+ try {
70+ await installExtension ( extId ) ;
71+ traceInfo ( `Extension ${ extId } installed.` ) ;
72+ } catch ( err ) {
73+ traceError ( `Failed to install extension: ${ extId } ` , err ) ;
74+ }
75+ }
76+ } else {
77+ showErrorMessage (
78+ l10n . t ( `Extension for {0} is not installed or enabled for this workspace.` , managerId ) ,
79+ ) ;
80+ }
81+ } ) ;
4982 }
50- return installed ;
5183 }
5284
5385 public dispose ( ) : void {
@@ -81,8 +113,28 @@ class ManagerReadyImpl implements ManagerReady {
81113 }
82114 }
83115
84- ids . forEach ( ( managerId ) => this . checkExtension ( managerId ) ) ;
85- await Promise . all ( Array . from ( ids ) . map ( ( managerId ) => this . _waitForEnvManager ( managerId ) ) ) ;
116+ await this . waitForEnvManagerId ( Array . from ( ids ) ) ;
117+ }
118+
119+ public async waitForEnvManagerId ( managerIds : string [ ] ) : Promise < void > {
120+ managerIds . forEach ( ( managerId ) => this . checkExtension ( managerId ) ) ;
121+ await Promise . all ( managerIds . map ( ( managerId ) => this . _waitForEnvManager ( managerId ) ) ) ;
122+ }
123+
124+ public async waitForAllEnvManagers ( ) : Promise < void > {
125+ const ids : Set < string > = new Set ( ) ;
126+ this . pm . getProjects ( ) . forEach ( ( project ) => {
127+ const m = getDefaultEnvManagerSetting ( this . pm , project . uri ) ;
128+ if ( m && ! ids . has ( m ) ) {
129+ ids . add ( m ) ;
130+ }
131+ } ) ;
132+
133+ const m = getDefaultEnvManagerSetting ( this . pm , undefined ) ;
134+ if ( m ) {
135+ ids . add ( m ) ;
136+ }
137+ await this . waitForEnvManagerId ( Array . from ( ids ) ) ;
86138 }
87139
88140 private _waitForPkgManager ( managerId : string ) : Promise < void > {
@@ -111,12 +163,11 @@ class ManagerReadyImpl implements ManagerReady {
111163 }
112164 }
113165
114- ids . forEach ( ( managerId ) => this . checkExtension ( managerId ) ) ;
115- await Promise . all (
116- Array . from ( ids ) . map ( ( managerId ) => {
117- return this . _waitForPkgManager ( managerId ) ;
118- } ) ,
119- ) ;
166+ await this . waitForPkgManagerId ( Array . from ( ids ) ) ;
167+ }
168+ public async waitForPkgManagerId ( managerIds : string [ ] ) : Promise < void > {
169+ managerIds . forEach ( ( managerId ) => this . checkExtension ( managerId ) ) ;
170+ await Promise . all ( managerIds . map ( ( managerId ) => this . _waitForPkgManager ( managerId ) ) ) ;
120171 }
121172}
122173
@@ -134,7 +185,22 @@ export async function waitForEnvManager(uris?: Uri[]): Promise<void> {
134185 return mr . waitForEnvManager ( uris ) ;
135186}
136187
188+ export async function waitForEnvManagerId ( managerIds : string [ ] ) : Promise < void > {
189+ const mr = await _deferred . promise ;
190+ return mr . waitForEnvManagerId ( managerIds ) ;
191+ }
192+
193+ export async function waitForAllEnvManagers ( ) : Promise < void > {
194+ const mr = await _deferred . promise ;
195+ return mr . waitForAllEnvManagers ( ) ;
196+ }
197+
137198export async function waitForPkgManager ( uris ?: Uri [ ] ) : Promise < void > {
138199 const mr = await _deferred . promise ;
139200 return mr . waitForPkgManager ( uris ) ;
140201}
202+
203+ export async function waitForPkgManagerId ( managerIds : string [ ] ) : Promise < void > {
204+ const mr = await _deferred . promise ;
205+ return mr . waitForPkgManagerId ( managerIds ) ;
206+ }
0 commit comments