@@ -18,6 +18,8 @@ import { areSameExtensions } from 'vs/platform/extensionManagement/common/extens
1818import { localize } from 'vs/nls' ;
1919import { isUIExtension } from 'vs/workbench/services/extensions/node/extensionsUtil' ;
2020import { registerSingleton } from 'vs/platform/instantiation/common/extensions' ;
21+ import { isNonEmptyArray } from 'vs/base/common/arrays' ;
22+ import { values } from 'vs/base/common/map' ;
2123
2224export class MultiExtensionManagementService extends Disposable implements IExtensionManagementService {
2325
@@ -145,7 +147,7 @@ export class MultiExtensionManagementService extends Disposable implements IExte
145147 // Install only on remote server
146148 const promise = this . extensionManagementServerService . remoteExtensionManagementServer . extensionManagementService . install ( vsix ) ;
147149 // Install UI Dependencies on local server
148- await this . installUIDependencies ( manifest ) ;
150+ await this . installUIDependenciesAndPackedExtensions ( manifest ) ;
149151 return promise ;
150152 }
151153 return this . extensionManagementServerService . localExtensionManagementServer . extensionManagementService . install ( vsix ) ;
@@ -165,8 +167,8 @@ export class MultiExtensionManagementService extends Disposable implements IExte
165167 }
166168 // Install only on remote server
167169 const promise = this . extensionManagementServerService . remoteExtensionManagementServer . extensionManagementService . installFromGallery ( gallery ) ;
168- // Install UI Dependencies on local server
169- await this . installUIDependencies ( manifest ) ;
170+ // Install UI dependencies and packed extensions on local server
171+ await this . installUIDependenciesAndPackedExtensions ( manifest ) ;
170172 return promise ;
171173 } else {
172174 return Promise . reject ( localize ( 'Manifest is not found' , "Installing Extension {0} failed: Manifest is not found." , gallery . displayName || gallery . name ) ) ;
@@ -175,18 +177,11 @@ export class MultiExtensionManagementService extends Disposable implements IExte
175177 return this . extensionManagementServerService . localExtensionManagementServer . extensionManagementService . installFromGallery ( gallery ) ;
176178 }
177179
178- private async installUIDependencies ( manifest : IExtensionManifest ) : Promise < void > {
179- if ( manifest . extensionDependencies && manifest . extensionDependencies . length ) {
180- const dependencies = await this . extensionGalleryService . loadAllDependencies ( manifest . extensionDependencies . map ( id => ( { id } ) ) , CancellationToken . None ) ;
181- if ( dependencies . length ) {
182- await Promise . all ( dependencies . map ( async d => {
183- const manifest = await this . extensionGalleryService . getManifest ( d , CancellationToken . None ) ;
184- if ( manifest && isUIExtension ( manifest , this . configurationService ) ) {
185- await this . extensionManagementServerService . localExtensionManagementServer . extensionManagementService . installFromGallery ( d ) ;
186- }
187- } ) ) ;
188- }
189- }
180+ private async installUIDependenciesAndPackedExtensions ( manifest : IExtensionManifest ) : Promise < void > {
181+ const uiExtensions = await this . getAllUIDependenciesAndPackedExtensions ( manifest , CancellationToken . None ) ;
182+ const installed = await this . extensionManagementServerService . localExtensionManagementServer . extensionManagementService . getInstalled ( ) ;
183+ const toInstall = uiExtensions . filter ( e => installed . every ( i => ! areSameExtensions ( i . identifier , e . identifier ) ) ) ;
184+ await Promise . all ( toInstall . map ( d => this . extensionManagementServerService . localExtensionManagementServer . extensionManagementService . installFromGallery ( d ) ) ) ;
190185 }
191186
192187 getExtensionsReport ( ) : Promise < IReportedExtension [ ] > {
@@ -196,6 +191,49 @@ export class MultiExtensionManagementService extends Disposable implements IExte
196191 private getServer ( extension : ILocalExtension ) : IExtensionManagementServer | null {
197192 return this . extensionManagementServerService . getExtensionManagementServer ( extension . location ) ;
198193 }
194+
195+ private async getAllUIDependenciesAndPackedExtensions ( manifest : IExtensionManifest , token : CancellationToken ) : Promise < IGalleryExtension [ ] > {
196+ const result = new Map < string , IGalleryExtension > ( ) ;
197+ const extensions = [ ...( manifest . extensionPack || [ ] ) , ...( manifest . extensionDependencies || [ ] ) ] ;
198+ await this . getAllUIDependenciesAndPackedExtensionsRecursively ( extensions , result , token ) ;
199+ return values ( result ) ;
200+ }
201+
202+ private async getAllUIDependenciesAndPackedExtensionsRecursively ( toGet : string [ ] , result : Map < string , IGalleryExtension > , token : CancellationToken ) : Promise < void > {
203+ if ( toGet . length === 0 ) {
204+ return Promise . resolve ( ) ;
205+ }
206+
207+ const extensions = ( await this . extensionGalleryService . query ( { names : toGet , pageSize : toGet . length } , token ) ) . firstPage ;
208+ const manifests = await Promise . all ( extensions . map ( e => this . extensionGalleryService . getManifest ( e , token ) ) ) ;
209+ const uiExtensionsManifests : IExtensionManifest [ ] = [ ] ;
210+ for ( let idx = 0 ; idx < extensions . length ; idx ++ ) {
211+ const extension = extensions [ idx ] ;
212+ const manifest = manifests [ idx ] ;
213+ if ( manifest && isUIExtension ( manifest , this . configurationService ) ) {
214+ result . set ( extension . identifier . id . toLowerCase ( ) , extension ) ;
215+ uiExtensionsManifests . push ( manifest ) ;
216+ }
217+ }
218+ toGet = [ ] ;
219+ for ( const uiExtensionManifest of uiExtensionsManifests ) {
220+ if ( isNonEmptyArray ( uiExtensionManifest . extensionDependencies ) ) {
221+ for ( const id of uiExtensionManifest . extensionDependencies ) {
222+ if ( ! result . has ( id . toLowerCase ( ) ) ) {
223+ toGet . push ( id ) ;
224+ }
225+ }
226+ }
227+ if ( isNonEmptyArray ( uiExtensionManifest . extensionPack ) ) {
228+ for ( const id of uiExtensionManifest . extensionPack ) {
229+ if ( ! result . has ( id . toLowerCase ( ) ) ) {
230+ toGet . push ( id ) ;
231+ }
232+ }
233+ }
234+ }
235+ return this . getAllUIDependenciesAndPackedExtensionsRecursively ( toGet , result , token ) ;
236+ }
199237}
200238
201239registerSingleton ( IExtensionManagementService , MultiExtensionManagementService ) ;
0 commit comments