@@ -32,7 +32,7 @@ import {
32
32
Metadata , InstallVSIXOptions
33
33
} from 'vs/platform/extensionManagement/common/extensionManagement' ;
34
34
import { areSameExtensions , computeTargetPlatform , ExtensionKey , getGalleryExtensionId , groupByExtension } from 'vs/platform/extensionManagement/common/extensionManagementUtil' ;
35
- import { IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService' ;
35
+ import { IExtensionsProfileScannerService , IScannedProfileExtension } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService' ;
36
36
import { IExtensionsScannerService , IScannedExtension , ScanOptions } from 'vs/platform/extensionManagement/common/extensionsScannerService' ;
37
37
import { ExtensionsDownloader } from 'vs/platform/extensionManagement/node/extensionDownloader' ;
38
38
import { ExtensionsLifecycle } from 'vs/platform/extensionManagement/node/extensionLifecycle' ;
@@ -71,9 +71,6 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi
71
71
private readonly manifestCache : ExtensionsManifestCache ;
72
72
private readonly extensionsDownloader : ExtensionsDownloader ;
73
73
74
- private readonly _onDidUpdateExtensionMetadata = this . _register ( new Emitter < ILocalExtension > ( ) ) ;
75
- override readonly onDidUpdateExtensionMetadata = this . _onDidUpdateExtensionMetadata . event ;
76
-
77
74
private readonly installGalleryExtensionsTasks = new Map < string , InstallGalleryExtensionTask > ( ) ;
78
75
79
76
constructor (
@@ -87,10 +84,10 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi
87
84
@IInstantiationService instantiationService : IInstantiationService ,
88
85
@IFileService private readonly fileService : IFileService ,
89
86
@IProductService productService : IProductService ,
90
- @IUriIdentityService private readonly uriIdentityService : IUriIdentityService ,
87
+ @IUriIdentityService uriIdentityService : IUriIdentityService ,
91
88
@IUserDataProfilesService userDataProfilesService : IUserDataProfilesService
92
89
) {
93
- super ( galleryService , telemetryService , logService , productService , userDataProfilesService ) ;
90
+ super ( galleryService , telemetryService , uriIdentityService , logService , productService , userDataProfilesService ) ;
94
91
const extensionLifecycle = this . _register ( instantiationService . createInstance ( ExtensionsLifecycle ) ) ;
95
92
this . extensionsScanner = this . _register ( instantiationService . createInstance ( ExtensionsScanner , extension => extensionLifecycle . postUninstall ( extension ) ) ) ;
96
93
this . manifestCache = this . _register ( new ExtensionsManifestCache ( userDataProfilesService , fileService , uriIdentityService , this , this . logService ) ) ;
@@ -227,6 +224,10 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi
227
224
return this . installFromGallery ( galleryExtension ) ;
228
225
}
229
226
227
+ protected copyExtension ( extension : ILocalExtension , fromProfileLocation : URI , toProfileLocation : URI , metadata : Partial < Metadata > ) : Promise < ILocalExtension > {
228
+ return this . extensionsScanner . copyExtension ( extension , fromProfileLocation , toProfileLocation , metadata ) ;
229
+ }
230
+
230
231
copyExtensions ( fromProfileLocation : URI , toProfileLocation : URI ) : Promise < void > {
231
232
return this . extensionsScanner . copyExtensions ( fromProfileLocation , toProfileLocation ) ;
232
233
}
@@ -531,20 +532,25 @@ export class ExtensionsScanner extends Disposable {
531
532
532
533
async scanMetadata ( local : ILocalExtension , profileLocation ?: URI ) : Promise < Metadata | undefined > {
533
534
if ( profileLocation ) {
534
- const extensions = await this . extensionsProfileScannerService . scanProfileExtensions ( profileLocation ) ;
535
- return extensions . find ( e => areSameExtensions ( e . identifier , local . identifier ) ) ?. metadata ;
535
+ const extension = await this . getScannedExtension ( local , profileLocation ) ;
536
+ return extension ?. metadata ;
536
537
} else {
537
538
return this . extensionsScannerService . scanMetadata ( local . location ) ;
538
539
}
539
540
}
540
541
542
+ private async getScannedExtension ( local : ILocalExtension , profileLocation : URI ) : Promise < IScannedProfileExtension | undefined > {
543
+ const extensions = await this . extensionsProfileScannerService . scanProfileExtensions ( profileLocation ) ;
544
+ return extensions . find ( e => areSameExtensions ( e . identifier , local . identifier ) ) ;
545
+ }
546
+
541
547
async updateMetadata ( local : ILocalExtension , metadata : Partial < Metadata > , profileLocation ?: URI ) : Promise < ILocalExtension > {
542
548
if ( profileLocation ) {
543
549
await this . extensionsProfileScannerService . updateMetadata ( [ [ local , metadata ] ] , profileLocation ) ;
544
550
} else {
545
551
await this . extensionsScannerService . updateMetadata ( local . location , metadata ) ;
546
552
}
547
- return this . scanLocalExtension ( local . location , local . type ) ;
553
+ return this . scanLocalExtension ( local . location , local . type , profileLocation ) ;
548
554
}
549
555
550
556
getUninstalledExtensions ( ) : Promise < IStringDictionary < boolean > > {
@@ -573,6 +579,20 @@ export class ExtensionsScanner extends Disposable {
573
579
await this . withUninstalledExtensions ( uninstalled => delete uninstalled [ ExtensionKey . create ( extension ) . toString ( ) ] ) ;
574
580
}
575
581
582
+ async copyExtension ( extension : ILocalExtension , fromProfileLocation : URI , toProfileLocation : URI , metadata : Partial < Metadata > ) : Promise < ILocalExtension > {
583
+ const source = await this . getScannedExtension ( extension , fromProfileLocation ) ;
584
+ const target = await this . getScannedExtension ( extension , toProfileLocation ) ;
585
+ metadata = { ...source ?. metadata , ...metadata } ;
586
+
587
+ if ( target ) {
588
+ await this . extensionsProfileScannerService . updateMetadata ( [ [ extension , { ...target . metadata , ...metadata } ] ] , toProfileLocation ) ;
589
+ } else {
590
+ await this . extensionsProfileScannerService . addExtensionsToProfile ( [ [ extension , metadata ] ] , toProfileLocation ) ;
591
+ }
592
+
593
+ return this . scanLocalExtension ( extension . location , extension . type , toProfileLocation ) ;
594
+ }
595
+
576
596
async copyExtensions ( fromProfileLocation : URI , toProfileLocation : URI ) : Promise < void > {
577
597
const fromExtensions = await this . scanExtensions ( ExtensionType . User , fromProfileLocation ) ;
578
598
const extensions : [ ILocalExtension , Metadata | undefined ] [ ] = await Promise . all ( fromExtensions
@@ -633,10 +653,18 @@ export class ExtensionsScanner extends Disposable {
633
653
}
634
654
}
635
655
636
- private async scanLocalExtension ( location : URI , type : ExtensionType ) : Promise < ILocalExtension > {
637
- const scannedExtension = await this . extensionsScannerService . scanExistingExtension ( location , type , { includeInvalid : true } ) ;
638
- if ( scannedExtension ) {
639
- return this . toLocalExtension ( scannedExtension ) ;
656
+ private async scanLocalExtension ( location : URI , type : ExtensionType , profileLocation ?: URI ) : Promise < ILocalExtension > {
657
+ if ( profileLocation ) {
658
+ const scannedExtensions = await this . extensionsScannerService . scanUserExtensions ( { profileLocation } ) ;
659
+ const scannedExtension = scannedExtensions . find ( e => this . uriIdentityService . extUri . isEqual ( e . location , location ) ) ;
660
+ if ( scannedExtension ) {
661
+ return this . toLocalExtension ( scannedExtension ) ;
662
+ }
663
+ } else {
664
+ const scannedExtension = await this . extensionsScannerService . scanExistingExtension ( location , type , { includeInvalid : true } ) ;
665
+ if ( scannedExtension ) {
666
+ return this . toLocalExtension ( scannedExtension ) ;
667
+ }
640
668
}
641
669
throw new Error ( nls . localize ( 'cannot read' , "Cannot read the extension from {0}" , location . path ) ) ;
642
670
}
0 commit comments