diff --git a/product.json b/product.json index 21bd7dbf..04814a7a 100644 --- a/product.json +++ b/product.json @@ -87,5 +87,118 @@ "linkProtectionTrustedDomains": [ "https://open-vsx.org" ], - "helpDocUrl":"https://gitee.com/openkylin/extensions-repo/blob/master/user-guide/%E7%9B%AE%E5%BD%95.md" + "helpDocUrl":"https://gitee.com/openkylin/extensions-repo/blob/master/user-guide/%E7%9B%AE%E5%BD%95.md", + "extensionsControlManifest":{ + "malicious": [], + "deprecated": { + "ms-ceintl.vscode-language-pack-zh-hans": { + "disallowInstall": true, + "extension": { + "id": "KylinIdeTeam.vscode-language-pack-zh-hans", + "displayName": "Chinese (Simplified) (简体中文) Language Pack for Kylin-Code" + } + }, + "zhanghua.vscodium-language-pack-zh-cn": { + "disallowInstall": true, + "extension": { + "id": "KylinIdeTeam.vscode-language-pack-zh-hans", + "displayName": "Chinese (Simplified) (简体中文) Language Pack for Kylin-Code" + } + } + }, + "search": [ + { + "query": "c", + "preferredResults": [ + "KylinIdeTeam.vscode-clangd", + "KylinIdeTeam.deadlock-detect" + ] + }, + { + "query": "c++", + "preferredResults": [ + "KylinIdeTeam.vscode-clangd", + "KylinIdeTeam.deadlock-detect" + ] + }, + { + "query": "java", + "preferredResults": [ + "KylinIdeTeam.vscode-java-pack", + "KylinIdeTeam.java", + "KylinIdeTeam.vscode-maven", + "KylinIdeTeam.vscode-gradle", + "KylinIdeTeam.vscode-java-dependency", + "KylinIdeTeam.vscode-java-debug", + "KylinIdeTeam.vscode-java-test" + ] + }, + { + "query": "go", + "preferredResults": [ + "KylinIdeTeam.go" + ] + }, + { + "query": "python", + "preferredResults": [ + "KylinIdeTeam.python" + ] + }, + { + "query": "js", + "preferredResults": [ + "KylinIDETeam.js-debug" + ] + }, + { + "query": "cmake", + "preferredResults": [ + "KylinIdeTeam.cmake-intellisence" + ] + }, + { + "query": "project", + "preferredResults": [ + "KylinIdeTeam.project-manager", + "KylinIdeTeam.vscode-java-dependency", + "KylinIdeTeam.vscode-maven" + ] + }, + { + "query": "debug", + "preferredResults": [ + "KylinIdeTeam.debug", + "KylinIDETeam.js-debug", + "KylinIdeTeam.vscode-java-debug", + "KylinIdeTeam.historydebug" + ] + }, + { + "query": "remote", + "preferredResults": [ + "xhafei.remote-dev" + ] + }, + { + "query": "depend", + "preferredResults": [ + "KylinIdeTeam.extension-dependency", + "KylinIdeTeam.vscode-java-dependency" + ] + }, + { + "query": "extension", + "preferredResults": [ + "KylinIdeTeam.extension-dependency" + ] + }, + { + "query": "extensions", + "preferredResults": [ + "KylinIdeTeam.offline-extensions-manager" + ] + } + ] + } } diff --git a/src/vs/base/common/product.ts b/src/vs/base/common/product.ts index cbea2c6b..07e80aac 100644 --- a/src/vs/base/common/product.ts +++ b/src/vs/base/common/product.ts @@ -30,6 +30,31 @@ export type ExtensionVirtualWorkspaceSupport = { readonly override?: boolean; }; + +export interface ISearchPrefferedResults { + readonly query?: string; + readonly preferredResults?: string[]; +} + +interface IExtensionsControlManifest { + malicious: string[]; + migrateToPreRelease?: IStringDictionary<{ + id: string; + displayName: string; + migrateStorage?: boolean; + engine?: string; + }>; + deprecated?: IStringDictionary; + search?: ISearchPrefferedResults[]; +} + export interface IProductConfiguration { readonly IDEVersion: string; readonly version: string; @@ -157,6 +182,8 @@ export interface IProductConfiguration { readonly 'configurationSync.store'?: ConfigurationSyncStore; readonly darwinUniversalAssetId?: string; + + readonly extensionsControlManifest: IExtensionsControlManifest; } export type ImportantExtensionTip = { name: string; languages?: string[]; pattern?: string; isExtensionPack?: boolean; whenNotInstalled?: string[] }; diff --git a/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts b/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts index 3b191c24..3824bd59 100644 --- a/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts +++ b/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts @@ -579,7 +579,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl return manifest; } catch (err) { this.logService.trace('ExtensionManagementService.refreshControlCache - failed to get extension control manifest'); - return { malicious: [], deprecated: {} }; + return { malicious: [], deprecated: {}, search: [] }; } } diff --git a/src/vs/platform/extensionManagement/common/extensionGalleryService.ts b/src/vs/platform/extensionManagement/common/extensionGalleryService.ts index 914b19bb..056b6e0b 100644 --- a/src/vs/platform/extensionManagement/common/extensionGalleryService.ts +++ b/src/vs/platform/extensionManagement/common/extensionGalleryService.ts @@ -16,7 +16,7 @@ import { URI } from 'vs/base/common/uri'; import { IRequestContext, IRequestOptions } from 'vs/base/parts/request/common/request'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { getFallbackTargetPlarforms, getTargetPlatform, IExtensionGalleryService, IExtensionIdentifier, IExtensionInfo, IGalleryExtension, IGalleryExtensionAsset, IGalleryExtensionAssets, IGalleryExtensionVersion, InstallOperation, IQueryOptions, IExtensionsControlManifest, isNotWebExtensionInWebTargetPlatform, isTargetPlatformCompatible, ITranslation, SortBy, SortOrder, StatisticType, toTargetPlatform, WEB_EXTENSION_TAG, IExtensionQueryOptions, IDeprecationInfo } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { getFallbackTargetPlarforms, getTargetPlatform, IExtensionGalleryService, IExtensionIdentifier, IExtensionInfo, IGalleryExtension, IGalleryExtensionAsset, IGalleryExtensionAssets, IGalleryExtensionVersion, InstallOperation, IQueryOptions, IExtensionsControlManifest, isNotWebExtensionInWebTargetPlatform, isTargetPlatformCompatible, ITranslation, SortBy, SortOrder, StatisticType, toTargetPlatform, WEB_EXTENSION_TAG, IExtensionQueryOptions, IDeprecationInfo, ISearchPrefferedResults } from 'vs/platform/extensionManagement/common/extensionManagement'; import { adoptToGalleryExtensionId, areSameExtensions, getGalleryExtensionId, getGalleryExtensionTelemetryData } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { IExtensionManifest, TargetPlatform } from 'vs/platform/extensions/common/extensions'; import { isEngineValid } from 'vs/platform/extensions/common/extensionValidator'; @@ -562,6 +562,7 @@ interface IRawExtensionsControlManifest { }; settings?: string[]; }>; + search?: ISearchPrefferedResults[]; } abstract class AbstractExtensionGalleryService implements IExtensionGalleryService { @@ -1181,23 +1182,10 @@ abstract class AbstractExtensionGalleryService implements IExtensionGalleryServi return engine; } - async getExtensionsControlManifest(): Promise { - if (!this.isEnabled()) { - throw new Error('No extension gallery service configured.'); - } - - if (!this.extensionsControlUrl) { - return { malicious: [], deprecated: {} }; - } - - const context = await this.requestService.request({ type: 'GET', url: this.extensionsControlUrl }, CancellationToken.None); - if (context.res.statusCode !== 200) { - throw new Error('Could not get extensions report.'); - } - - const result = await asJson(context); + async getExtensionsControlManifest1(result: IRawExtensionsControlManifest | null): Promise { const malicious: IExtensionIdentifier[] = []; const deprecated: IStringDictionary = {}; + const search: ISearchPrefferedResults[] = []; if (result) { for (const id of result.malicious) { malicious.push({ id }); @@ -1224,9 +1212,33 @@ abstract class AbstractExtensionGalleryService implements IExtensionGalleryServi } } } + if (result.search) { + for (const s of result.search) { + search.push(s); + } + } } - return { malicious, deprecated }; + return { malicious, deprecated, search }; + } + + async getExtensionsControlManifest(): Promise { + if (!this.isEnabled()) { + throw new Error('No extension gallery service configured.'); + } + + if (!this.extensionsControlUrl) { + let result: IRawExtensionsControlManifest = this.productService.extensionsControlManifest; + return this.getExtensionsControlManifest1(result); + } + + const context = await this.requestService.request({ type: 'GET', url: this.extensionsControlUrl }, CancellationToken.None); + if (context.res.statusCode !== 200) { + throw new Error('Could not get extensions report.'); + } + + const result = await asJson(context); + return this.getExtensionsControlManifest1(result); } } diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index fab22756..3c45c0de 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -294,9 +294,15 @@ export interface IDeprecationInfo { readonly settings?: readonly string[]; } +export interface ISearchPrefferedResults { + readonly query?: string; + readonly preferredResults?: string[]; +} + export interface IExtensionsControlManifest { readonly malicious: IExtensionIdentifier[]; readonly deprecated: IStringDictionary; + readonly search: ISearchPrefferedResults[]; } export const enum InstallOperation { diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts index 35820980..70430c2c 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts @@ -33,7 +33,7 @@ import { INotificationService, Severity } from 'vs/platform/notification/common/ import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPane'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { coalesce, distinct, flatten } from 'vs/base/common/arrays'; -import { IExperimentService, IExperiment, ExperimentActionType } from 'vs/workbench/contrib/experiments/common/experimentService'; +// import { IExperimentService, IExperiment, ExperimentActionType } from 'vs/workbench/contrib/experiments/common/experimentService'; import { alert } from 'vs/base/browser/ui/aria/aria'; import { IListContextMenuEvent } from 'vs/base/browser/ui/list/list'; import { CancellationToken } from 'vs/base/common/cancellation'; @@ -119,7 +119,7 @@ export class ExtensionsListView extends ViewPane { @ITelemetryService telemetryService: ITelemetryService, @IConfigurationService configurationService: IConfigurationService, @IWorkspaceContextService protected contextService: IWorkspaceContextService, - @IExperimentService private readonly experimentService: IExperimentService, + // @IExperimentService private readonly experimentService: IExperimentService, @IExtensionManagementServerService protected readonly extensionManagementServerService: IExtensionManagementServerService, @IExtensionManifestPropertiesService private readonly extensionManifestPropertiesService: IExtensionManifestPropertiesService, @IWorkbenchExtensionManagementService protected readonly extensionManagementService: IWorkbenchExtensionManagementService, @@ -655,9 +655,9 @@ export class ExtensionsListView extends ViewPane { return this.queryRecommendations(query, options, token); } - if (/\bcurated:([^\s]+)\b/.test(query.value)) { - return this.getCuratedModel(query, options, token); - } + // if (/\bcurated:([^\s]+)\b/.test(query.value)) { + // return this.getCuratedModel(query, options, token); + // } const text = query.value; @@ -672,12 +672,22 @@ export class ExtensionsListView extends ViewPane { options.text = text.substring(0, 350); options.source = 'searchText'; if (!hasUserDefinedSortOrder) { - const searchExperiments = await this.getSearchExperiments(); - for (const experiment of searchExperiments) { - if (experiment.action && text.toLowerCase() === experiment.action.properties['searchText'] && Array.isArray(experiment.action.properties['preferredResults'])) { - preferredResults = experiment.action.properties['preferredResults']; - options.source += `-experiment-${experiment.id}`; - break; + // const searchExperiments = await this.getSearchExperiments(); + // for (const experiment of searchExperiments) { + // if (experiment.action && text.toLowerCase() === experiment.action.properties['searchText'] && Array.isArray(experiment.action.properties['preferredResults'])) { + // preferredResults = experiment.action.properties['preferredResults']; + // options.source += `-experiment-${experiment.id}`; + // break; + // } + // } + const manifest = await this.extensionManagementService.getExtensionsControlManifest(); + const search = manifest.search; + if (Array.isArray(search)) { + for (const s of search) { + if (s.query && s.query.toLowerCase() === text.toLowerCase() && Array.isArray(s.preferredResults)) { + preferredResults = s.preferredResults; + break; + } } } } @@ -704,18 +714,18 @@ export class ExtensionsListView extends ViewPane { } - resetSearchExperiments() { ExtensionsListView.searchExperiments = undefined; } - private static searchExperiments: Promise | undefined; - private getSearchExperiments(): Promise { - if (!ExtensionsListView.searchExperiments) { - ExtensionsListView.searchExperiments = this.experimentService.getExperimentsByType(ExperimentActionType.ExtensionSearchResults) - .then(null, e => { - this.logService.error(e); - return []; - }); - } - return ExtensionsListView.searchExperiments; - } + // resetSearchExperiments() { ExtensionsListView.searchExperiments = undefined; } + // private static searchExperiments: Promise | undefined; + // private getSearchExperiments(): Promise { + // if (!ExtensionsListView.searchExperiments) { + // ExtensionsListView.searchExperiments = this.experimentService.getExperimentsByType(ExperimentActionType.ExtensionSearchResults) + // .then(null, e => { + // this.logService.error(e); + // return []; + // }); + // } + // return ExtensionsListView.searchExperiments; + // } private sortExtensions(extensions: IExtension[], options: IQueryOptions): IExtension[] { switch (options.sortBy) { @@ -736,19 +746,19 @@ export class ExtensionsListView extends ViewPane { return extensions; } - private async getCuratedModel(query: Query, options: IQueryOptions, token: CancellationToken): Promise> { - const value = query.value.replace(/curated:/g, '').trim(); - let ids = await this.experimentService.getCuratedExtensionsList(value); - if (Array.isArray(ids) && ids.length) { - ids = ids.map(id => id.toLowerCase()); - const extensions = await this.extensionsWorkbenchService.getExtensions(ids.map(id => ({ id })), { source: `curated:${value}` }, token); - // Sorts the firstPage of the pager in the same order as given array of extension ids - extensions.sort((a, b) => - ids.indexOf(a.identifier.id.toLowerCase()) < ids.indexOf(b.identifier.id.toLowerCase()) ? -1 : 1); - return this.getPagedModel(extensions); - } - return new PagedModel([]); - } + // private async getCuratedModel(query: Query, options: IQueryOptions, token: CancellationToken): Promise> { + // const value = query.value.replace(/curated:/g, '').trim(); + // let ids = await this.experimentService.getCuratedExtensionsList(value); + // if (Array.isArray(ids) && ids.length) { + // ids = ids.map(id => id.toLowerCase()); + // const extensions = await this.extensionsWorkbenchService.getExtensions(ids.map(id => ({ id })), { source: `curated:${value}` }, token); + // // Sorts the firstPage of the pager in the same order as given array of extension ids + // extensions.sort((a, b) => + // ids.indexOf(a.identifier.id.toLowerCase()) < ids.indexOf(b.identifier.id.toLowerCase()) ? -1 : 1); + // return this.getPagedModel(extensions); + // } + // return new PagedModel([]); + // } private isRecommendationsQuery(query: Query): boolean { return ExtensionsListView.isWorkspaceRecommendedExtensionsQuery(query.value) diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionRecommendationsService.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionRecommendationsService.test.ts index add1a477..dce76165 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionRecommendationsService.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionRecommendationsService.test.ts @@ -218,7 +218,7 @@ suite('ExtensionRecommendationsService Test', () => { onDidUninstallExtension: didUninstallEvent.event, async getInstalled() { return []; }, async canInstall() { return true; }, - async getExtensionsControlManifest() { return { malicious: [], deprecated: {} }; }, + async getExtensionsControlManifest() { return { malicious: [], deprecated: {}, search: [] }; }, async getTargetPlatform() { return getTargetPlatform(platform, arch); } }); instantiationService.stub(IExtensionService, >{ diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts index 6cbe2bd6..4436bde3 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts @@ -100,7 +100,7 @@ async function setupTest() { onUninstallExtension: uninstallEvent.event, onDidUninstallExtension: didUninstallEvent.event, async getInstalled() { return []; }, - async getExtensionsControlManifest() { return { malicious: [], deprecated: {} }; }, + async getExtensionsControlManifest() { return { malicious: [], deprecated: {}, search: [] }; }, async updateMetadata(local: ILocalExtension, metadata: IGalleryMetadata) { local.identifier.uuid = metadata.id; local.publisherDisplayName = metadata.publisherDisplayName; @@ -2434,7 +2434,7 @@ function createExtensionManagementService(installed: ILocalExtension[] = []): IE return local; }, async getTargetPlatform() { return getTargetPlatform(platform, arch); }, - async getExtensionsControlManifest() { return { malicious: [], deprecated: {} }; }, + async getExtensionsControlManifest() { return { malicious: [], deprecated: {}, search: [] }; }, }; } diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts index 1212a0ed..7e48143d 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts @@ -98,7 +98,7 @@ suite('ExtensionsListView Tests', () => { onDidUninstallExtension: didUninstallEvent.event, async getInstalled() { return []; }, async canInstall() { return true; }, - async getExtensionsControlManifest() { return { malicious: [], deprecated: {} }; }, + async getExtensionsControlManifest() { return { malicious: [], deprecated: {}, search: [] }; }, async getTargetPlatform() { return getTargetPlatform(platform, arch); } }); instantiationService.stub(IRemoteAgentService, RemoteAgentService); @@ -492,7 +492,7 @@ suite('ExtensionsListView Tests', () => { } }]); - testableView.resetSearchExperiments(); + // testableView.resetSearchExperiments(); testableView.dispose(); testableView = instantiationService.createInstance(ExtensionsListView, {}, {}); diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts index 77f2f39c..91717d95 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts @@ -95,7 +95,7 @@ suite('ExtensionsWorkbenchServiceTest', () => { onUninstallExtension: uninstallEvent.event, onDidUninstallExtension: didUninstallEvent.event, async getInstalled() { return []; }, - async getExtensionsControlManifest() { return { malicious: [], deprecated: {} }; }, + async getExtensionsControlManifest() { return { malicious: [], deprecated: {}, search: [] }; }, async updateMetadata(local: ILocalExtension, metadata: IGalleryMetadata) { local.identifier.uuid = metadata.id; local.publisherDisplayName = metadata.publisherDisplayName; @@ -1487,7 +1487,7 @@ suite('ExtensionsWorkbenchServiceTest', () => { return local; }, getTargetPlatform: async () => getTargetPlatform(platform, arch), - async getExtensionsControlManifest() { return { malicious: [], deprecated: {} }; }, + async getExtensionsControlManifest() { return { malicious: [], deprecated: {}, search: [] }; }, }; } }); diff --git a/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts b/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts index 46c26ac1..7d83d55e 100644 --- a/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts @@ -394,7 +394,7 @@ export class ExtensionManagementService extends Disposable implements IWorkbench if (this.extensionManagementServerService.webExtensionManagementServer) { return this.extensionManagementServerService.webExtensionManagementServer.extensionManagementService.getExtensionsControlManifest(); } - return Promise.resolve({ malicious: [], deprecated: {} }); + return Promise.resolve({ malicious: [], deprecated: {}, search: [] }); } private getServer(extension: ILocalExtension): IExtensionManagementServer | null {