提交 f57ac767 编写于 作者: S Sandeep Somavarapu

create workspace extension config service

上级 1fd7ee15
......@@ -6,7 +6,7 @@
import { IExtensionTipsService, IConfigBasedExtensionTip } from 'vs/platform/extensionManagement/common/extensionManagement';
import { ExtensionRecommendations, ExtensionRecommendation, PromptedExtensionRecommendations } from 'vs/workbench/contrib/extensions/browser/extensionRecommendations';
import { localize } from 'vs/nls';
import { ExtensionRecommendationReason } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { ExtensionRecommendationReason } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
import { IWorkspaceContextService, IWorkspaceFoldersChangeEvent } from 'vs/platform/workspace/common/workspace';
import { Emitter } from 'vs/base/common/event';
......
......@@ -12,7 +12,7 @@ import { isNonEmptyArray } from 'vs/base/common/arrays';
import { IWorkspaceTagsService } from 'vs/workbench/contrib/tags/common/workspaceTags';
import { isNumber } from 'vs/base/common/types';
import { ExtensionRecommendations, ExtensionRecommendation, PromptedExtensionRecommendations } from 'vs/workbench/contrib/extensions/browser/extensionRecommendations';
import { ExtensionRecommendationReason } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { ExtensionRecommendationReason } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
import { localize } from 'vs/nls';
type DynamicWorkspaceRecommendationsClassification = {
......
......@@ -10,7 +10,7 @@ import { timeout } from 'vs/base/common/async';
import { localize } from 'vs/nls';
import { optional } from 'vs/platform/instantiation/common/instantiation';
import { basename } from 'vs/base/common/path';
import { ExtensionRecommendationReason } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { ExtensionRecommendationReason } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
import { ITASExperimentService } from 'vs/workbench/services/experiment/common/experimentService';
type ExeExtensionRecommendationsClassification = {
......
......@@ -5,7 +5,7 @@
import { isNonEmptyArray } from 'vs/base/common/arrays';
import { ExtensionRecommendations, ExtensionRecommendation, PromptedExtensionRecommendations } from 'vs/workbench/contrib/extensions/browser/extensionRecommendations';
import { ExtensionRecommendationReason } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { ExtensionRecommendationReason } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
import { IExperimentService, ExperimentActionType, ExperimentState } from 'vs/workbench/contrib/experiments/common/experimentService';
export class ExperimentalRecommendations extends ExtensionRecommendations {
......
......@@ -19,7 +19,7 @@ import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { IExtensionRecommendationsService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IExtensionRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
import { IExtensionManifest, IKeyBinding, IView, IViewContainer, ExtensionType } from 'vs/platform/extensions/common/extensions';
import { ResolvedKeybinding, KeyMod, KeyCode } from 'vs/base/common/keyCodes';
import { ExtensionsInput } from 'vs/workbench/contrib/extensions/common/extensionsInput';
......
......@@ -9,7 +9,8 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { localize } from 'vs/nls';
import { SearchExtensionsAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
import { EnablementState, ExtensionRecommendationSource, IExtensionRecommendationReson, IWorkbenchExtensionEnablementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { EnablementState, IWorkbenchExtensionEnablementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { ExtensionRecommendationSource, IExtensionRecommendationReson } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
import { IExtensionsConfiguration, ConfigurationKey, IExtension, IExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/common/extensions';
import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
......
......@@ -5,7 +5,7 @@
import { Disposable } from 'vs/base/common/lifecycle';
import { IExtensionManagementService, IExtensionGalleryService, InstallOperation, DidInstallExtensionEvent } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IExtensionRecommendationsService, ExtensionRecommendationReason, RecommendationChangeNotification, IExtensionRecommendation, ExtensionRecommendationSource } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IExtensionRecommendationsService, ExtensionRecommendationReason, RecommendationChangeNotification, IExtensionRecommendation, ExtensionRecommendationSource } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
import { IStorageService, StorageScope, IWorkspaceStorageChangeEvent } from 'vs/platform/storage/common/storage';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ShowRecommendationsOnlyOnDemandKey } from 'vs/workbench/contrib/extensions/common/extensions';
......
......@@ -9,7 +9,8 @@ import { Registry } from 'vs/platform/registry/common/platform';
import { MenuRegistry, MenuId, registerAction2, Action2 } from 'vs/platform/actions/common/actions';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { ExtensionsLabel, ExtensionsLocalizedLabel, ExtensionsChannelId, IExtensionManagementService, IExtensionGalleryService, PreferencesLocalizedLabel } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IExtensionManagementServerService, IExtensionRecommendationsService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IExtensionRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IOutputChannelRegistry, Extensions as OutputExtensions } from 'vs/workbench/services/output/common/output';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
......
......@@ -12,10 +12,11 @@ import { Event } from 'vs/base/common/event';
import * as json from 'vs/base/common/json';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { dispose, Disposable } from 'vs/base/common/lifecycle';
import { IExtension, ExtensionState, IExtensionsWorkbenchService, VIEWLET_ID, IExtensionsViewPaneContainer, AutoUpdateConfigurationKey, IExtensionContainer, EXTENSIONS_CONFIG, TOGGLE_IGNORE_EXTENSION_ACTION_ID } from 'vs/workbench/contrib/extensions/common/extensions';
import { IExtension, ExtensionState, IExtensionsWorkbenchService, VIEWLET_ID, IExtensionsViewPaneContainer, AutoUpdateConfigurationKey, IExtensionContainer, TOGGLE_IGNORE_EXTENSION_ACTION_ID } from 'vs/workbench/contrib/extensions/common/extensions';
import { ExtensionsConfigurationInitialContent } from 'vs/workbench/contrib/extensions/common/extensionsFileTemplate';
import { IGalleryExtension, IExtensionGalleryService, INSTALL_ERROR_MALICIOUS, INSTALL_ERROR_INCOMPATIBLE, IGalleryExtensionVersion, ILocalExtension, INSTALL_ERROR_NOT_SUPPORTED } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionRecommendationsService, IExtensionsConfigContent, IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IExtensionRecommendationsService, IExtensionsConfigContent } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { ExtensionType, ExtensionIdentifier, IExtensionDescription, IExtensionManifest, isLanguagePackExtension } from 'vs/platform/extensions/common/extensions';
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
......@@ -60,6 +61,7 @@ import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/
import { Codicon } from 'vs/base/common/codicons';
import { IViewsService } from 'vs/workbench/common/views';
import { IActionViewItemOptions, ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
import { EXTENSIONS_CONFIG } from 'vs/workbench/services/extensionRecommendations/common/workspaceExtensionsConfig';
export function toExtensionDescription(local: ILocalExtension): IExtensionDescription {
return {
......
......@@ -9,7 +9,8 @@ import { Event, Emitter } from 'vs/base/common/event';
import { isPromiseCanceledError, getErrorMessage } from 'vs/base/common/errors';
import { PagedModel, IPagedModel, IPager, DelayedPagedModel } from 'vs/base/common/paging';
import { SortBy, SortOrder, IQueryOptions, IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IExtensionManagementServer, IExtensionManagementServerService, IExtensionRecommendationsService, IExtensionRecommendation, EnablementState } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IExtensionManagementServer, IExtensionManagementServerService, EnablementState } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IExtensionRecommendationsService, IExtensionRecommendation } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
......
......@@ -9,7 +9,8 @@ import { IExtension, IExtensionsWorkbenchService, IExtensionContainer } from 'vs
import { append, $ } from 'vs/base/browser/dom';
import * as platform from 'vs/base/common/platform';
import { localize } from 'vs/nls';
import { IExtensionRecommendationsService, IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IExtensionRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
import { ILabelService } from 'vs/platform/label/common/label';
import { extensionButtonProminentBackground, extensionButtonProminentForeground, ExtensionToolTipAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
import { IThemeService, IColorTheme } from 'vs/platform/theme/common/themeService';
......
......@@ -6,7 +6,8 @@
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { ExtensionRecommendations, ExtensionRecommendation, PromptedExtensionRecommendations } from 'vs/workbench/contrib/extensions/browser/extensionRecommendations';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { ExtensionRecommendationSource, ExtensionRecommendationReason, EnablementState } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { EnablementState } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { ExtensionRecommendationSource, ExtensionRecommendationReason } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
import { IExtensionsViewPaneContainer, IExtensionsWorkbenchService, IExtension } from 'vs/workbench/contrib/extensions/common/extensions';
import { CancellationToken } from 'vs/base/common/cancellation';
import { localize } from 'vs/nls';
......
......@@ -5,7 +5,7 @@
import { ExtensionRecommendations, ExtensionRecommendation, PromptedExtensionRecommendations } from 'vs/workbench/contrib/extensions/browser/extensionRecommendations';
import { IProductService } from 'vs/platform/product/common/productService';
import { ExtensionRecommendationReason } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { ExtensionRecommendationReason } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
export class KeymapRecommendations extends ExtensionRecommendations {
......
......@@ -4,18 +4,16 @@
*--------------------------------------------------------------------------------------------*/
import { EXTENSION_IDENTIFIER_PATTERN, IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IWorkspaceContextService, IWorkspaceFolder, IWorkspace, IWorkspaceFoldersChangeEvent } from 'vs/platform/workspace/common/workspace';
import { IFileService } from 'vs/platform/files/common/files';
import { distinct, flatten, coalesce } from 'vs/base/common/arrays';
import { IWorkspaceContextService, IWorkspaceFoldersChangeEvent } from 'vs/platform/workspace/common/workspace';
import { distinct, flatten } from 'vs/base/common/arrays';
import { ExtensionRecommendations, ExtensionRecommendation, PromptedExtensionRecommendations } from 'vs/workbench/contrib/extensions/browser/extensionRecommendations';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { IExtensionsConfigContent, ExtensionRecommendationSource, ExtensionRecommendationReason } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { parse } from 'vs/base/common/json';
import { EXTENSIONS_CONFIG } from 'vs/workbench/contrib/extensions/common/extensions';
import { IExtensionsConfigContent, ExtensionRecommendationReason } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
import { ILogService } from 'vs/platform/log/common/log';
import { CancellationToken } from 'vs/base/common/cancellation';
import { localize } from 'vs/nls';
import { Emitter } from 'vs/base/common/event';
import { IWorkpsaceExtensionsConfigService } from 'vs/workbench/services/extensionRecommendations/common/workspaceExtensionsConfig';
export class WorkspaceRecommendations extends ExtensionRecommendations {
......@@ -31,9 +29,9 @@ export class WorkspaceRecommendations extends ExtensionRecommendations {
constructor(
promptedExtensionRecommendations: PromptedExtensionRecommendations,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@IWorkpsaceExtensionsConfigService private readonly workpsaceExtensionsConfigService: IWorkpsaceExtensionsConfigService,
@IExtensionGalleryService private readonly galleryService: IExtensionGalleryService,
@ILogService private readonly logService: ILogService,
@IFileService private readonly fileService: IFileService,
@INotificationService private readonly notificationService: INotificationService,
) {
super(promptedExtensionRecommendations);
......@@ -49,26 +47,26 @@ export class WorkspaceRecommendations extends ExtensionRecommendations {
*/
private async fetch(): Promise<void> {
const extensionsConfigBySource = await this.fetchExtensionsConfigBySource();
const extensionsConfigs = await this.workpsaceExtensionsConfigService.getExtensionsConfigs();
const { invalidRecommendations, message } = await this.validateExtensions(extensionsConfigBySource.map(({ contents }) => contents));
const { invalidRecommendations, message } = await this.validateExtensions(extensionsConfigs);
if (invalidRecommendations.length) {
this.notificationService.warn(`The ${invalidRecommendations.length} extension(s) below, in workspace recommendations have issues:\n${message}`);
}
this._ignoredRecommendations = [];
for (const extensionsConfig of extensionsConfigBySource) {
for (const unwantedRecommendation of extensionsConfig.contents.unwantedRecommendations) {
for (const extensionsConfig of extensionsConfigs) {
for (const unwantedRecommendation of extensionsConfig.unwantedRecommendations) {
if (invalidRecommendations.indexOf(unwantedRecommendation) === -1) {
this._ignoredRecommendations.push(unwantedRecommendation);
}
}
for (const extensionId of extensionsConfig.contents.recommendations) {
for (const extensionId of extensionsConfig.recommendations) {
if (invalidRecommendations.indexOf(extensionId) === -1) {
this._recommendations.push({
extensionId,
source: extensionsConfig.source,
source: this.contextService.getWorkspace(),
reason: {
reasonId: ExtensionRecommendationReason.Workspace,
reasonText: localize('workspaceRecommendation', "This extension is recommended by users of the current workspace.")
......@@ -79,41 +77,6 @@ export class WorkspaceRecommendations extends ExtensionRecommendations {
}
}
private async fetchExtensionsConfigBySource(): Promise<{ contents: IExtensionsConfigContent, source: ExtensionRecommendationSource }[]> {
const workspace = this.contextService.getWorkspace();
const result = await Promise.all([
this.resolveWorkspaceExtensionConfig(workspace),
...workspace.folders.map(workspaceFolder => this.resolveWorkspaceFolderExtensionConfig(workspaceFolder))
]);
return coalesce(result);
}
private async resolveWorkspaceExtensionConfig(workspace: IWorkspace): Promise<{ contents: IExtensionsConfigContent, source: ExtensionRecommendationSource } | null> {
try {
if (workspace.configuration) {
const content = await this.fileService.readFile(workspace.configuration);
const extensionsConfigContent = <IExtensionsConfigContent | undefined>parse(content.value.toString())['extensions'];
const contents = this.parseExtensionConfig(extensionsConfigContent);
if (contents) {
return { contents, source: workspace };
}
}
} catch (e) { /* Ignore */ }
return null;
}
private async resolveWorkspaceFolderExtensionConfig(workspaceFolder: IWorkspaceFolder): Promise<{ contents: IExtensionsConfigContent, source: ExtensionRecommendationSource } | null> {
try {
const content = await this.fileService.readFile(workspaceFolder.toResource(EXTENSIONS_CONFIG));
const extensionsConfigContent = <IExtensionsConfigContent>parse(content.value.toString());
const contents = this.parseExtensionConfig(extensionsConfigContent);
if (contents) {
return { contents, source: workspaceFolder };
}
} catch (e) { /* ignore */ }
return null;
}
private async validateExtensions(contents: IExtensionsConfigContent[]): Promise<{ validRecommendations: string[], invalidRecommendations: string[], message: string }> {
const validExtensions: string[] = [];
......@@ -165,15 +128,5 @@ export class WorkspaceRecommendations extends ExtensionRecommendations {
}
}
private parseExtensionConfig(extensionsConfigContent: IExtensionsConfigContent | undefined): IExtensionsConfigContent | null {
if (extensionsConfigContent) {
return {
recommendations: distinct((extensionsConfigContent.recommendations || []).map(e => e.toLowerCase())),
unwantedRecommendations: distinct((extensionsConfigContent.unwantedRecommendations || []).map(e => e.toLowerCase()))
};
}
return null;
}
}
......@@ -17,8 +17,6 @@ import { IViewPaneContainer } from 'vs/workbench/common/views';
export const VIEWLET_ID = 'workbench.view.extensions';
export const EXTENSIONS_CONFIG = '.vscode/extensions.json';
export interface IExtensionsViewPaneContainer extends IViewPaneContainer {
search(text: string, refresh?: boolean): void;
}
......
......@@ -9,7 +9,8 @@ import { onUnexpectedError } from 'vs/base/common/errors';
import { Disposable } from 'vs/base/common/lifecycle';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IExtensionManagementService, ILocalExtension, IExtensionIdentifier, InstallOperation } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionRecommendationsService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IWorkbenchExtensionEnablementService, EnablementState } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IExtensionRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
......
......@@ -58,6 +58,7 @@ import { IWorkspaceTagsService } from 'vs/workbench/contrib/tags/common/workspac
import { IStorageKeysSyncRegistryService, StorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
import { ExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { IWorkpsaceExtensionsConfigService, WorkspaceExtensionsConfigService } from 'vs/workbench/services/extensionRecommendations/common/workspaceExtensionsConfig';
const mockExtensionGallery: IGalleryExtension[] = [
aGalleryExtension('MockExtension1', {
......@@ -301,6 +302,7 @@ suite('ExtensionRecommendationsService Test', () => {
const myWorkspace = testWorkspace(URI.from({ scheme: 'file', path: folderDir }));
workspaceService = new TestContextService(myWorkspace);
instantiationService.stub(IWorkspaceContextService, workspaceService);
instantiationService.stub(IWorkpsaceExtensionsConfigService, instantiationService.createInstance(WorkspaceExtensionsConfigService));
const fileService = new FileService(new NullLogService());
fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService()));
instantiationService.stub(IFileService, fileService);
......
......@@ -12,7 +12,8 @@ import {
IExtensionManagementService, IExtensionGalleryService, ILocalExtension, IGalleryExtension,
DidInstallExtensionEvent, DidUninstallExtensionEvent, InstallExtensionEvent, IExtensionIdentifier, InstallOperation, IExtensionTipsService, IGalleryMetadata
} from 'vs/platform/extensionManagement/common/extensionManagement';
import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer, IExtensionRecommendationsService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IExtensionRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
import { getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { TestExtensionEnablementService } from 'vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test';
import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService';
......
......@@ -13,7 +13,8 @@ import {
IExtensionManagementService, IExtensionGalleryService, ILocalExtension, IGalleryExtension, IQueryOptions,
DidInstallExtensionEvent, DidUninstallExtensionEvent, InstallExtensionEvent, IExtensionIdentifier, SortBy
} from 'vs/platform/extensionManagement/common/extensionManagement';
import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer, IExtensionRecommendationsService, ExtensionRecommendationReason, IExtensionRecommendation } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IExtensionRecommendationsService, ExtensionRecommendationReason, IExtensionRecommendation } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
import { getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { TestExtensionEnablementService } from 'vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test';
import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService';
......
......@@ -13,7 +13,8 @@ import {
IExtensionManagementService, IExtensionGalleryService, ILocalExtension, IGalleryExtension,
DidInstallExtensionEvent, DidUninstallExtensionEvent, InstallExtensionEvent, IGalleryExtensionAssets, IExtensionIdentifier, InstallOperation, IExtensionTipsService, IGalleryMetadata
} from 'vs/platform/extensionManagement/common/extensionManagement';
import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionRecommendationsService, IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IExtensionRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
import { getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { TestExtensionEnablementService } from 'vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test';
import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService';
......
......@@ -23,7 +23,8 @@ import { Schemas } from 'vs/base/common/network';
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
import { getInstalledExtensions, IExtensionStatus, onExtensionChanged, isKeymapExtension } from 'vs/workbench/contrib/extensions/common/extensionsUtils';
import { IExtensionManagementService, IExtensionGalleryService, ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionRecommendationsService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IWorkbenchExtensionEnablementService, EnablementState } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IExtensionRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
import { ILifecycleService, StartupKind } from 'vs/platform/lifecycle/common/lifecycle';
import { Disposable } from 'vs/base/common/lifecycle';
import { splitName } from 'vs/base/common/labels';
......
......@@ -38,7 +38,8 @@ import { isWindows, OS } from 'vs/base/common/platform';
import { IWebviewService, WebviewContentOptions, WebviewElement, WebviewExtensionDescription, WebviewIcons, WebviewOptions, WebviewOverlay } from 'vs/workbench/contrib/webview/browser/webview';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { AbstractTextFileService } from 'vs/workbench/services/textfile/browser/textFileService';
import { ExtensionRecommendationReason, IExtensionManagementServer, IExtensionManagementServerService, IExtensionRecommendation } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IExtensionManagementServer, IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { ExtensionRecommendationReason, IExtensionRecommendation } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations';
import { ITunnelProvider, ITunnelService, RemoteTunnel } from 'vs/platform/remote/common/tunnel';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { IManualSyncTask, IResourcePreview, ISyncResourceHandle, ISyncTask, IUserDataAutoSyncService, IUserDataSyncService, IUserDataSyncStore, IUserDataSyncStoreManagementService, SyncResource, SyncStatus, UserDataSyncStoreType } from 'vs/platform/userDataSync/common/userDataSync';
......
......@@ -5,11 +5,8 @@
import { Event } from 'vs/base/common/event';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { URI } from 'vs/base/common/uri';
import { IExtension, IScannedExtension, ExtensionType, ITranslatedScannedExtension } from 'vs/platform/extensions/common/extensions';
import { IExtensionManagementService, IGalleryExtension, IExtensionIdentifier } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IWorkspace, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { IStringDictionary } from 'vs/base/common/collections';
export const IExtensionManagementServerService = createDecorator<IExtensionManagementServerService>('extensionManagementServerService');
......@@ -88,63 +85,6 @@ export interface IWorkbenchExtensionEnablementService {
setEnablement(extensions: IExtension[], state: EnablementState): Promise<boolean[]>;
}
export interface IExtensionsConfigContent {
recommendations: string[];
unwantedRecommendations: string[];
}
export type RecommendationChangeNotification = {
extensionId: string,
isRecommended: boolean
};
export type DynamicRecommendation = 'dynamic';
export type ConfigRecommendation = 'config';
export type ExecutableRecommendation = 'executable';
export type CachedRecommendation = 'cached';
export type ApplicationRecommendation = 'application';
export type ExperimentalRecommendation = 'experimental';
export type ExtensionRecommendationSource = IWorkspace | IWorkspaceFolder | URI | DynamicRecommendation | ExecutableRecommendation | CachedRecommendation | ApplicationRecommendation | ExperimentalRecommendation | ConfigRecommendation;
export interface IExtensionRecommendation {
extensionId: string;
sources: ExtensionRecommendationSource[];
}
export const enum ExtensionRecommendationReason {
Workspace,
File,
Executable,
WorkspaceConfig,
DynamicWorkspace,
Experimental,
Application,
}
export interface IExtensionRecommendationReson {
reasonId: ExtensionRecommendationReason;
reasonText: string;
}
export const IExtensionRecommendationsService = createDecorator<IExtensionRecommendationsService>('extensionRecommendationsService');
export interface IExtensionRecommendationsService {
readonly _serviceBrand: undefined;
getAllRecommendationsWithReason(): IStringDictionary<IExtensionRecommendationReson>;
getImportantRecommendations(): Promise<IExtensionRecommendation[]>;
getOtherRecommendations(): Promise<IExtensionRecommendation[]>;
getFileBasedRecommendations(): IExtensionRecommendation[];
getExeBasedRecommendations(exe?: string): Promise<{ important: IExtensionRecommendation[], others: IExtensionRecommendation[] }>;
getConfigBasedRecommendations(): Promise<{ important: IExtensionRecommendation[], others: IExtensionRecommendation[] }>;
getWorkspaceRecommendations(): Promise<IExtensionRecommendation[]>;
getKeymapRecommendations(): IExtensionRecommendation[];
toggleIgnoredRecommendation(extensionId: string, shouldIgnore: boolean): void;
getIgnoredRecommendations(): ReadonlyArray<string>;
onRecommendationChange: Event<RecommendationChangeNotification>;
}
export const IWebExtensionsScannerService = createDecorator<IWebExtensionsScannerService>('IWebExtensionsScannerService');
export interface IWebExtensionsScannerService {
readonly _serviceBrand: undefined;
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Event } from 'vs/base/common/event';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { URI } from 'vs/base/common/uri';
import { IWorkspace, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { IStringDictionary } from 'vs/base/common/collections';
export interface IExtensionsConfigContent {
recommendations: string[];
unwantedRecommendations: string[];
}
export type RecommendationChangeNotification = {
extensionId: string,
isRecommended: boolean
};
export type DynamicRecommendation = 'dynamic';
export type ConfigRecommendation = 'config';
export type ExecutableRecommendation = 'executable';
export type CachedRecommendation = 'cached';
export type ApplicationRecommendation = 'application';
export type ExperimentalRecommendation = 'experimental';
export type ExtensionRecommendationSource = IWorkspace | IWorkspaceFolder | URI | DynamicRecommendation | ExecutableRecommendation | CachedRecommendation | ApplicationRecommendation | ExperimentalRecommendation | ConfigRecommendation;
export interface IExtensionRecommendation {
extensionId: string;
sources: ExtensionRecommendationSource[];
}
export const enum ExtensionRecommendationReason {
Workspace,
File,
Executable,
WorkspaceConfig,
DynamicWorkspace,
Experimental,
Application,
}
export interface IExtensionRecommendationReson {
reasonId: ExtensionRecommendationReason;
reasonText: string;
}
export const IExtensionRecommendationsService = createDecorator<IExtensionRecommendationsService>('extensionRecommendationsService');
export interface IExtensionRecommendationsService {
readonly _serviceBrand: undefined;
getAllRecommendationsWithReason(): IStringDictionary<IExtensionRecommendationReson>;
getImportantRecommendations(): Promise<IExtensionRecommendation[]>;
getOtherRecommendations(): Promise<IExtensionRecommendation[]>;
getFileBasedRecommendations(): IExtensionRecommendation[];
getExeBasedRecommendations(exe?: string): Promise<{ important: IExtensionRecommendation[], others: IExtensionRecommendation[] }>;
getConfigBasedRecommendations(): Promise<{ important: IExtensionRecommendation[], others: IExtensionRecommendation[] }>;
getWorkspaceRecommendations(): Promise<IExtensionRecommendation[]>;
getKeymapRecommendations(): IExtensionRecommendation[];
toggleIgnoredRecommendation(extensionId: string, shouldIgnore: boolean): void;
getIgnoredRecommendations(): ReadonlyArray<string>;
onRecommendationChange: Event<RecommendationChangeNotification>;
}
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { coalesce, distinct, flatten } from 'vs/base/common/arrays';
import { parse } from 'vs/base/common/json';
import { IFileService } from 'vs/platform/files/common/files';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IWorkspace, IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
export const EXTENSIONS_CONFIG = '.vscode/extensions.json';
export interface IExtensionsConfigContent {
recommendations: string[];
unwantedRecommendations: string[];
}
export const IWorkpsaceExtensionsConfigService = createDecorator<IWorkpsaceExtensionsConfigService>('IWorkpsaceExtensionsConfigService');
export interface IWorkpsaceExtensionsConfigService {
readonly _serviceBrand: undefined;
getExtensionsConfigs(): Promise<IExtensionsConfigContent[]>;
getUnwantedRecommendations(): Promise<string[]>;
}
export class WorkspaceExtensionsConfigService implements IWorkpsaceExtensionsConfigService {
declare readonly _serviceBrand: undefined;
constructor(
@IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService,
@IFileService private readonly fileService: IFileService,
) { }
async getExtensionsConfigs(): Promise<IExtensionsConfigContent[]> {
const workspace = this.workspaceContextService.getWorkspace();
const result = await Promise.all([
this.resolveWorkspaceExtensionConfig(workspace),
...workspace.folders.map(workspaceFolder => this.resolveWorkspaceFolderExtensionConfig(workspaceFolder))
]);
return coalesce(result);
}
async getUnwantedRecommendations(): Promise<string[]> {
const configs = await this.getExtensionsConfigs();
return distinct(flatten(configs.map(c => c.unwantedRecommendations)));
}
private async resolveWorkspaceExtensionConfig(workspace: IWorkspace): Promise<IExtensionsConfigContent | null> {
try {
if (workspace.configuration) {
const content = await this.fileService.readFile(workspace.configuration);
const extensionsConfigContent = <IExtensionsConfigContent | undefined>parse(content.value.toString())['extensions'];
return this.parseExtensionConfig(extensionsConfigContent);
}
} catch (e) { /* Ignore */ }
return null;
}
private async resolveWorkspaceFolderExtensionConfig(workspaceFolder: IWorkspaceFolder): Promise<IExtensionsConfigContent | null> {
try {
const content = await this.fileService.readFile(workspaceFolder.toResource(EXTENSIONS_CONFIG));
const extensionsConfigContent = <IExtensionsConfigContent>parse(content.value.toString());
return this.parseExtensionConfig(extensionsConfigContent);
} catch (e) { /* ignore */ }
return null;
}
private parseExtensionConfig(extensionsConfigContent: IExtensionsConfigContent | undefined): IExtensionsConfigContent | null {
if (extensionsConfigContent) {
return {
recommendations: distinct((extensionsConfigContent.recommendations || []).map(e => e.toLowerCase())),
unwantedRecommendations: distinct((extensionsConfigContent.unwantedRecommendations || []).map(e => e.toLowerCase()))
};
}
return null;
}
}
registerSingleton(IWorkpsaceExtensionsConfigService, WorkspaceExtensionsConfigService);
......@@ -75,6 +75,7 @@ import 'vs/workbench/services/label/common/labelService';
import 'vs/workbench/services/extensionManagement/common/webExtensionsScannerService';
import 'vs/workbench/services/extensionManagement/common/extensionEnablementService';
import 'vs/workbench/services/extensionManagement/browser/builtinExtensionsScannerService';
import 'vs/workbench/services/extensionRecommendations/common/workspaceExtensionsConfig';
import 'vs/workbench/services/notification/common/notificationService';
import 'vs/workbench/services/userDataSync/common/userDataSyncUtil';
import 'vs/workbench/services/remote/common/remoteExplorerService';
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册