Skip to content

Commit 3881831

Browse files
authored
Apply extension to all profiles (microsoft#187767)
Apply extension to all profiles microsoft#157492
1 parent 4bacd64 commit 3881831

File tree

5 files changed

+35
-4
lines changed

5 files changed

+35
-4
lines changed

src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,6 +1442,24 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi
14421442
}
14431443
});
14441444

1445+
this.registerExtensionAction({
1446+
id: 'workbench.extensions.action.toggleApplyToAllProfiles',
1447+
title: { value: localize('workbench.extensions.action.toggleApplyToAllProfiles', "Apply this Extension to all Profiles"), original: `Apply this Extension to all Profiles` },
1448+
toggled: ContextKeyExpr.has('isApplicationScopedExtension'),
1449+
menu: {
1450+
id: MenuId.ExtensionContext,
1451+
group: '2_configure',
1452+
when: ContextKeyExpr.and(ContextKeyExpr.equals('extensionStatus', 'installed'), ContextKeyExpr.has('isDefaultApplicationScopedExtension').negate()),
1453+
order: 4
1454+
},
1455+
run: async (accessor: ServicesAccessor, id: string) => {
1456+
const extension = this.extensionsWorkbenchService.local.find(e => areSameExtensions({ id }, e.identifier));
1457+
if (extension) {
1458+
return this.extensionsWorkbenchService.toggleApplyExtensionToAllProfiles(extension);
1459+
}
1460+
}
1461+
});
1462+
14451463
this.registerExtensionAction({
14461464
id: 'workbench.extensions.action.ignoreRecommendation',
14471465
title: { value: localize('workbench.extensions.action.ignoreRecommendation', "Ignore Recommendation"), original: `Ignore Recommendation` },

src/vs/workbench/contrib/extensions/browser/extensionsActions.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { IGalleryExtension, IExtensionGalleryService, ILocalExtension, InstallOp
1818
import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
1919
import { ExtensionRecommendationReason, IExtensionIgnoredRecommendationsService, IExtensionRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
2020
import { areSameExtensions, getExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
21-
import { ExtensionType, ExtensionIdentifier, IExtensionDescription, IExtensionManifest, isLanguagePackExtension, getWorkspaceSupportTypeMessage, TargetPlatform } from 'vs/platform/extensions/common/extensions';
21+
import { ExtensionType, ExtensionIdentifier, IExtensionDescription, IExtensionManifest, isLanguagePackExtension, getWorkspaceSupportTypeMessage, TargetPlatform, isApplicationScopedExtension } from 'vs/platform/extensions/common/extensions';
2222
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
2323
import { IFileService, IFileContent } from 'vs/platform/files/common/files';
2424
import { IWorkspaceContextService, WorkbenchState, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
@@ -1010,6 +1010,8 @@ async function getContextMenuActionsGroups(extension: IExtension | undefined | n
10101010
if (extension) {
10111011
cksOverlay.push(['extension', extension.identifier.id]);
10121012
cksOverlay.push(['isBuiltinExtension', extension.isBuiltin]);
1013+
cksOverlay.push(['isDefaultApplicationScopedExtension', extension.local && isApplicationScopedExtension(extension.local.manifest)]);
1014+
cksOverlay.push(['isApplicationScopedExtension', extension.local && extension.local.isApplicationScoped]);
10131015
cksOverlay.push(['extensionHasConfiguration', extension.local && !!extension.local.manifest.contributes && !!extension.local.manifest.contributes.configuration]);
10141016
cksOverlay.push(['extensionHasKeybindings', extension.local && !!extension.local.manifest.contributes && !!extension.local.manifest.contributes.keybindings]);
10151017
cksOverlay.push(['extensionHasCommands', extension.local && !!extension.local.manifest.contributes && !!extension.local.manifest.contributes?.commands]);
@@ -1179,6 +1181,8 @@ export class MenuItemExtensionAction extends ExtensionAction {
11791181
}
11801182
if (this.action.id === TOGGLE_IGNORE_EXTENSION_ACTION_ID) {
11811183
this.checked = !this.extensionsWorkbenchService.isExtensionIgnoredToSync(this.extension);
1184+
} else {
1185+
this.checked = this.action.checked;
11821186
}
11831187
}
11841188

src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import * as resources from 'vs/base/common/resources';
3434
import { CancellationToken } from 'vs/base/common/cancellation';
3535
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
3636
import { IFileService } from 'vs/platform/files/common/files';
37-
import { IExtensionManifest, ExtensionType, IExtension as IPlatformExtension, TargetPlatform, ExtensionIdentifier, IExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
37+
import { IExtensionManifest, ExtensionType, IExtension as IPlatformExtension, TargetPlatform, ExtensionIdentifier, IExtensionIdentifier, IExtensionDescription, isApplicationScopedExtension } from 'vs/platform/extensions/common/extensions';
3838
import { ILanguageService } from 'vs/editor/common/languages/language';
3939
import { IProductService } from 'vs/platform/product/common/productService';
4040
import { FileAccess } from 'vs/base/common/network';
@@ -50,6 +50,7 @@ import { getLocale } from 'vs/platform/languagePacks/common/languagePacks';
5050
import { ILocaleService } from 'vs/workbench/services/localization/common/locale';
5151
import { TelemetryTrustedValue } from 'vs/platform/telemetry/common/telemetryUtils';
5252
import { ILifecycleService, LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
53+
import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
5354

5455
interface IExtensionStateProvider<T> {
5556
(extension: Extension): T;
@@ -774,6 +775,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
774775
@ILocaleService private readonly localeService: ILocaleService,
775776
@ILifecycleService private readonly lifecycleService: ILifecycleService,
776777
@IFileService private readonly fileService: IFileService,
778+
@IUserDataProfilesService private readonly userDataProfilesService: IUserDataProfilesService,
777779
) {
778780
super();
779781
const preferPreReleasesValue = configurationService.getValue('_extensions.preferPreReleases');
@@ -1619,6 +1621,12 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
16191621
await this.userDataAutoSyncService.triggerSync(['IgnoredExtensionsUpdated'], false, false);
16201622
}
16211623

1624+
async toggleApplyExtensionToAllProfiles(extension: IExtension): Promise<void> {
1625+
if (extension.local && !isApplicationScopedExtension(extension.local.manifest)) {
1626+
await this.extensionManagementService.updateMetadata(extension.local, { isApplicationScoped: !extension.local.isApplicationScoped }, this.userDataProfilesService.defaultProfile.extensionsResource);
1627+
}
1628+
}
1629+
16221630
private isInstalledExtensionSynced(extension: ILocalExtension): boolean {
16231631
if (extension.isMachineScoped) {
16241632
return false;

src/vs/workbench/contrib/extensions/common/extensions.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ export interface IExtensionsWorkbenchService {
120120
// Sync APIs
121121
isExtensionIgnoredToSync(extension: IExtension): boolean;
122122
toggleExtensionIgnoredToSync(extension: IExtension): Promise<void>;
123+
toggleApplyExtensionToAllProfiles(extension: IExtension): Promise<void>;
123124
}
124125

125126
export const enum ExtensionEditorTab {

src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,10 @@ export class ExtensionManagementService extends Disposable implements IWorkbench
153153
return Promise.reject(`Invalid location ${extension.location.toString()}`);
154154
}
155155

156-
updateMetadata(extension: ILocalExtension, metadata: Partial<Metadata>): Promise<ILocalExtension> {
156+
updateMetadata(extension: ILocalExtension, metadata: Partial<Metadata>, profileLocation?: URI): Promise<ILocalExtension> {
157157
const server = this.getServer(extension);
158158
if (server) {
159-
return server.extensionManagementService.updateMetadata(extension, metadata);
159+
return server.extensionManagementService.updateMetadata(extension, metadata, profileLocation);
160160
}
161161
return Promise.reject(`Invalid location ${extension.location.toString()}`);
162162
}

0 commit comments

Comments
 (0)