@@ -32,7 +32,7 @@ import {
3232 Metadata , InstallVSIXOptions
3333} from 'vs/platform/extensionManagement/common/extensionManagement' ;
3434import { 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' ;
3636import { IExtensionsScannerService , IScannedExtension , ScanOptions } from 'vs/platform/extensionManagement/common/extensionsScannerService' ;
3737import { ExtensionsDownloader } from 'vs/platform/extensionManagement/node/extensionDownloader' ;
3838import { ExtensionsLifecycle } from 'vs/platform/extensionManagement/node/extensionLifecycle' ;
@@ -71,9 +71,6 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi
7171 private readonly manifestCache : ExtensionsManifestCache ;
7272 private readonly extensionsDownloader : ExtensionsDownloader ;
7373
74- private readonly _onDidUpdateExtensionMetadata = this . _register ( new Emitter < ILocalExtension > ( ) ) ;
75- override readonly onDidUpdateExtensionMetadata = this . _onDidUpdateExtensionMetadata . event ;
76-
7774 private readonly installGalleryExtensionsTasks = new Map < string , InstallGalleryExtensionTask > ( ) ;
7875
7976 constructor (
@@ -87,10 +84,10 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi
8784 @IInstantiationService instantiationService : IInstantiationService ,
8885 @IFileService private readonly fileService : IFileService ,
8986 @IProductService productService : IProductService ,
90- @IUriIdentityService private readonly uriIdentityService : IUriIdentityService ,
87+ @IUriIdentityService uriIdentityService : IUriIdentityService ,
9188 @IUserDataProfilesService userDataProfilesService : IUserDataProfilesService
9289 ) {
93- super ( galleryService , telemetryService , logService , productService , userDataProfilesService ) ;
90+ super ( galleryService , telemetryService , uriIdentityService , logService , productService , userDataProfilesService ) ;
9491 const extensionLifecycle = this . _register ( instantiationService . createInstance ( ExtensionsLifecycle ) ) ;
9592 this . extensionsScanner = this . _register ( instantiationService . createInstance ( ExtensionsScanner , extension => extensionLifecycle . postUninstall ( extension ) ) ) ;
9693 this . manifestCache = this . _register ( new ExtensionsManifestCache ( userDataProfilesService , fileService , uriIdentityService , this , this . logService ) ) ;
@@ -227,6 +224,10 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi
227224 return this . installFromGallery ( galleryExtension ) ;
228225 }
229226
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+
230231 copyExtensions ( fromProfileLocation : URI , toProfileLocation : URI ) : Promise < void > {
231232 return this . extensionsScanner . copyExtensions ( fromProfileLocation , toProfileLocation ) ;
232233 }
@@ -531,20 +532,25 @@ export class ExtensionsScanner extends Disposable {
531532
532533 async scanMetadata ( local : ILocalExtension , profileLocation ?: URI ) : Promise < Metadata | undefined > {
533534 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 ;
536537 } else {
537538 return this . extensionsScannerService . scanMetadata ( local . location ) ;
538539 }
539540 }
540541
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+
541547 async updateMetadata ( local : ILocalExtension , metadata : Partial < Metadata > , profileLocation ?: URI ) : Promise < ILocalExtension > {
542548 if ( profileLocation ) {
543549 await this . extensionsProfileScannerService . updateMetadata ( [ [ local , metadata ] ] , profileLocation ) ;
544550 } else {
545551 await this . extensionsScannerService . updateMetadata ( local . location , metadata ) ;
546552 }
547- return this . scanLocalExtension ( local . location , local . type ) ;
553+ return this . scanLocalExtension ( local . location , local . type , profileLocation ) ;
548554 }
549555
550556 getUninstalledExtensions ( ) : Promise < IStringDictionary < boolean > > {
@@ -573,6 +579,20 @@ export class ExtensionsScanner extends Disposable {
573579 await this . withUninstalledExtensions ( uninstalled => delete uninstalled [ ExtensionKey . create ( extension ) . toString ( ) ] ) ;
574580 }
575581
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+
576596 async copyExtensions ( fromProfileLocation : URI , toProfileLocation : URI ) : Promise < void > {
577597 const fromExtensions = await this . scanExtensions ( ExtensionType . User , fromProfileLocation ) ;
578598 const extensions : [ ILocalExtension , Metadata | undefined ] [ ] = await Promise . all ( fromExtensions
@@ -633,10 +653,18 @@ export class ExtensionsScanner extends Disposable {
633653 }
634654 }
635655
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+ }
640668 }
641669 throw new Error ( nls . localize ( 'cannot read' , "Cannot read the extension from {0}" , location . path ) ) ;
642670 }
0 commit comments