Skip to content

Commit

Permalink
#139015 refactor gallery service
Browse files Browse the repository at this point in the history
- unify apis in IExtensionGalleryService
  • Loading branch information
sandy081 committed Jan 17, 2022
1 parent 9f96093 commit fb26bec
Show file tree
Hide file tree
Showing 11 changed files with 53 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl
let compatibleExtension: IGalleryExtension | null = null;

if (fetchCompatibleVersion && extension.hasPreReleaseVersion && extension.properties.isPreReleaseVersion !== includePreRelease) {
compatibleExtension = await this.galleryService.getCompatibleExtension(extension.identifier, includePreRelease, targetPlatform);
compatibleExtension = (await this.galleryService.getExtensions([{ ...extension.identifier, preRelease: includePreRelease }], { targetPlatform, compatible: true }, CancellationToken.None))[0] || null;
}

if (!compatibleExtension && await this.galleryService.isExtensionCompatible(extension, includePreRelease, targetPlatform)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { URI } from 'vs/base/common/uri';
import { IHeaders, 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 { DefaultIconPath, getFallbackTargetPlarforms, getTargetPlatform, IExtensionGalleryService, IExtensionIdentifier, IExtensionIdentifierWithVersion, IGalleryExtension, IGalleryExtensionAsset, IGalleryExtensionAssets, IGalleryExtensionVersion, InstallOperation, IQueryOptions, IExtensionsControlManifest, isIExtensionIdentifier, isNotWebExtensionInWebTargetPlatform, isTargetPlatformCompatible, ITranslation, SortBy, SortOrder, StatisticType, TargetPlatform, toTargetPlatform, WEB_EXTENSION_TAG, IExtensionIdentifierWithPreRelease } from 'vs/platform/extensionManagement/common/extensionManagement';
import { DefaultIconPath, getFallbackTargetPlarforms, getTargetPlatform, IExtensionGalleryService, IExtensionIdentifier, IExtensionInfo, IGalleryExtension, IGalleryExtensionAsset, IGalleryExtensionAssets, IGalleryExtensionVersion, InstallOperation, IQueryOptions, IExtensionsControlManifest, isNotWebExtensionInWebTargetPlatform, isTargetPlatformCompatible, ITranslation, SortBy, SortOrder, StatisticType, TargetPlatform, toTargetPlatform, WEB_EXTENSION_TAG } from 'vs/platform/extensionManagement/common/extensionManagement';
import { adoptToGalleryExtensionId, areSameExtensions, getGalleryExtensionId, getGalleryExtensionTelemetryData } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { IExtensionManifest } from 'vs/platform/extensions/common/extensions';
import { isEngineValid } from 'vs/platform/extensions/common/extensionValidator';
Expand Down Expand Up @@ -278,8 +278,8 @@ type GalleryServiceAdditionalQueryEvent = {
interface IExtensionCriteria {
readonly targetPlatform: TargetPlatform;
readonly compatible: boolean;
readonly preRelease: boolean | IExtensionIdentifierWithPreRelease[];
readonly versions?: IExtensionIdentifierWithVersion[];
readonly preRelease: boolean | (IExtensionIdentifier & { preRelease: boolean })[];
readonly versions?: (IExtensionIdentifier & { version: string })[];
}

class Query {
Expand Down Expand Up @@ -562,65 +562,52 @@ abstract class AbstractExtensionGalleryService implements IExtensionGalleryServi
return !!this.extensionsGalleryUrl;
}

getExtensions(identifiers: ReadonlyArray<IExtensionIdentifier | IExtensionIdentifierWithVersion>, token: CancellationToken): Promise<IGalleryExtension[]>;
getExtensions(identifiers: ReadonlyArray<IExtensionIdentifier | IExtensionIdentifierWithVersion>, includePreRelease: boolean, token: CancellationToken): Promise<IGalleryExtension[]>;
async getExtensions(identifiers: ReadonlyArray<IExtensionIdentifier | IExtensionIdentifierWithVersion>, arg1: any, arg2?: any): Promise<IGalleryExtension[]> {
const preRelease = isBoolean(arg1) ? arg1 : false;
const token: CancellationToken = isBoolean(arg1) ? arg2 : arg1;
const versions: IExtensionIdentifierWithVersion[] = (identifiers as ReadonlyArray<IExtensionIdentifierWithVersion>).filter(identifier => !!identifier.version);
const query = new Query()
.withPage(1, identifiers.length)
.withFilter(FilterType.ExtensionName, ...identifiers.map(({ id }) => id.toLowerCase()));

const { extensions } = await this.queryGalleryExtensions(query, { targetPlatform: CURRENT_TARGET_PLATFORM, preRelease, versions, compatible: false }, token);
return extensions;
}

async getCompatibleExtensions(identifiers: ReadonlyArray<IExtensionIdentifierWithPreRelease>, targetPlatform: TargetPlatform): Promise<IGalleryExtension[]> {
const names: string[] = []; const ids: string[] = [];
for (const identifier of identifiers) {
if (identifier.uuid) {
ids.push(identifier.uuid);
getExtensions(extensionInfos: ReadonlyArray<IExtensionInfo>, token: CancellationToken): Promise<IGalleryExtension[]>;
getExtensions(extensionInfos: ReadonlyArray<IExtensionInfo>, options: { targetPlatform: TargetPlatform, compatible?: boolean }, token: CancellationToken): Promise<IGalleryExtension[]>;
async getExtensions(extensionInfos: ReadonlyArray<IExtensionInfo>, arg1: any, arg2?: any): Promise<IGalleryExtension[]> {
const options = CancellationToken.isCancellationToken(arg1) ? { targetPlatform: CURRENT_TARGET_PLATFORM } : arg1 as { targetPlatform: TargetPlatform, compatible?: boolean };
const token = CancellationToken.isCancellationToken(arg1) ? arg1 : arg2 as CancellationToken;
const names: string[] = []; const ids: string[] = [], preRelease: (IExtensionIdentifier & { preRelease: boolean })[] = [], versions: (IExtensionIdentifier & { version: string })[] = [];
for (const extensionInfo of extensionInfos) {
if (extensionInfo.uuid) {
ids.push(extensionInfo.uuid);
} else {
names.push(identifier.id.toLowerCase());
names.push(extensionInfo.id);
}
preRelease.push({ ...extensionInfo, preRelease: !!extensionInfo.preRelease });
if (extensionInfo.version) {
versions.push({ ...extensionInfo, version: extensionInfo.version });
}
}

if (!ids.length && !names.length) {
return [];
}

let query = new Query().withPage(1, identifiers.length);
let query = new Query().withPage(1, extensionInfos.length);
if (ids.length) {
query = query.withFilter(FilterType.ExtensionId, ...ids);
}
if (names.length) {
query = query.withFilter(FilterType.ExtensionName, ...names);
}

const { extensions } = await this.queryGalleryExtensions(query, { targetPlatform, compatible: true, preRelease: [...identifiers] }, CancellationToken.None);
const { extensions } = await this.queryGalleryExtensions(query, { targetPlatform: options.targetPlatform, preRelease, versions, compatible: !!options.compatible }, token);
return extensions;
}

async getCompatibleExtension(arg1: IExtensionIdentifier | IGalleryExtension, includePreRelease: boolean, targetPlatform: TargetPlatform): Promise<IGalleryExtension | null> {
const extension: IGalleryExtension | null = isIExtensionIdentifier(arg1) ? null : arg1;

if (extension) {
if (isNotWebExtensionInWebTargetPlatform(extension.allTargetPlatforms, targetPlatform)) {
return null;
}
if (await this.isExtensionCompatible(extension, includePreRelease, targetPlatform)) {
return extension;
}
const query = new Query()
.withFlags(Flags.IncludeVersions)
.withPage(1, 1)
.withFilter(FilterType.ExtensionId, extension.identifier.uuid);
const { extensions } = await this.queryGalleryExtensions(query, { targetPlatform, compatible: true, preRelease: includePreRelease }, CancellationToken.None);
return extensions[0] || null;
async getCompatibleExtension(extension: IGalleryExtension, includePreRelease: boolean, targetPlatform: TargetPlatform): Promise<IGalleryExtension | null> {
if (isNotWebExtensionInWebTargetPlatform(extension.allTargetPlatforms, targetPlatform)) {
return null;
}

const extensions = await this.getCompatibleExtensions([{ ...(<IExtensionIdentifier>arg1), preRelease: includePreRelease }], targetPlatform);
if (await this.isExtensionCompatible(extension, includePreRelease, targetPlatform)) {
return extension;
}
const query = new Query()
.withFlags(Flags.IncludeVersions)
.withPage(1, 1)
.withFilter(FilterType.ExtensionId, extension.identifier.uuid);
const { extensions } = await this.queryGalleryExtensions(query, { targetPlatform, compatible: true, preRelease: includePreRelease }, CancellationToken.None);
return extensions[0] || null;
}

Expand Down
23 changes: 8 additions & 15 deletions src/vs/platform/extensionManagement/common/extensionManagement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,14 +222,9 @@ export interface IExtensionIdentifier {
uuid?: string;
}

export interface IExtensionIdentifierWithVersion extends IExtensionIdentifier {
id: string;
uuid?: string;
version: string;
}

export interface IExtensionIdentifierWithPreRelease extends IExtensionIdentifier {
preRelease: boolean;
export interface IExtensionInfo extends IExtensionIdentifier {
version?: string;
preRelease?: boolean;
}

export interface IGalleryExtensionIdentifier extends IExtensionIdentifier {
Expand Down Expand Up @@ -340,20 +335,18 @@ export interface IExtensionGalleryService {
readonly _serviceBrand: undefined;
isEnabled(): boolean;
query(options: IQueryOptions, token: CancellationToken): Promise<IPager<IGalleryExtension>>;
getExtensions(identifiers: ReadonlyArray<IExtensionIdentifier | IExtensionIdentifierWithVersion>, token: CancellationToken): Promise<IGalleryExtension[]>;
getExtensions(identifiers: ReadonlyArray<IExtensionIdentifier | IExtensionIdentifierWithVersion>, includePreRelease: boolean, token: CancellationToken): Promise<IGalleryExtension[]>;
getExtensions(extensionInfos: ReadonlyArray<IExtensionInfo>, token: CancellationToken): Promise<IGalleryExtension[]>;
getExtensions(extensionInfos: ReadonlyArray<IExtensionInfo>, options: { targetPlatform: TargetPlatform, compatible?: boolean }, token: CancellationToken): Promise<IGalleryExtension[]>;
isExtensionCompatible(extension: IGalleryExtension, includePreRelease: boolean, targetPlatform: TargetPlatform): Promise<boolean>;
getCompatibleExtension(extension: IGalleryExtension, includePreRelease: boolean, targetPlatform: TargetPlatform): Promise<IGalleryExtension | null>;
getAllCompatibleVersions(extension: IGalleryExtension, includePreRelease: boolean, targetPlatform: TargetPlatform): Promise<IGalleryExtensionVersion[]>;
download(extension: IGalleryExtension, location: URI, operation: InstallOperation): Promise<void>;
reportStatistic(publisher: string, name: string, version: string, type: StatisticType): Promise<void>;
getReadme(extension: IGalleryExtension, token: CancellationToken): Promise<string>;
getManifest(extension: IGalleryExtension, token: CancellationToken): Promise<IExtensionManifest | null>;
getChangelog(extension: IGalleryExtension, token: CancellationToken): Promise<string>;
getCoreTranslation(extension: IGalleryExtension, languageId: string): Promise<ITranslation | null>;
getExtensionsControlManifest(): Promise<IExtensionsControlManifest>;
isExtensionCompatible(extension: IGalleryExtension, includePreRelease: boolean, targetPlatform: TargetPlatform): Promise<boolean>;
getCompatibleExtensions(identifiers: ReadonlyArray<IExtensionIdentifierWithPreRelease>, targetPlatform: TargetPlatform): Promise<IGalleryExtension[]>;
getCompatibleExtension(extension: IGalleryExtension, includePreRelease: boolean, targetPlatform: TargetPlatform): Promise<IGalleryExtension | null>;
getCompatibleExtension(id: IExtensionIdentifier, includePreRelease: boolean, targetPlatform: TargetPlatform): Promise<IGalleryExtension | null>;
getAllCompatibleVersions(extension: IGalleryExtension, includePreRelease: boolean, targetPlatform: TargetPlatform): Promise<IGalleryExtensionVersion[]>;
}

export interface InstallExtensionEvent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ export class ExtensionManagementCLIService implements IExtensionManagementCLISer

private async getGalleryExtensions(extensions: InstallExtensionInfo[]): Promise<Map<string, IGalleryExtension>> {
const galleryExtensions = new Map<string, IGalleryExtension>();
const result = await this.extensionGalleryService.getExtensions(extensions, extensions.some(e => e.installOptions.installPreReleaseVersion), CancellationToken.None);
const preRelease = extensions.some(e => e.installOptions.installPreReleaseVersion);
const result = await this.extensionGalleryService.getExtensions(extensions.map(e => ({...e, preRelease})), CancellationToken.None);
for (const extension of result) {
galleryExtensions.set(extension.identifier.id.toLowerCase(), extension);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/

import { compareIgnoreCase } from 'vs/base/common/strings';
import { IExtensionIdentifier, IExtensionIdentifierWithVersion, IGalleryExtension, ILocalExtension, IExtensionsControlManifest } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IExtensionIdentifier, IGalleryExtension, ILocalExtension, IExtensionsControlManifest } from 'vs/platform/extensionManagement/common/extensionManagement';
import { ExtensionIdentifier, IExtension } from 'vs/platform/extensions/common/extensions';

export function areSameExtensions(a: IExtensionIdentifier, b: IExtensionIdentifier): boolean {
Expand All @@ -17,7 +17,7 @@ export function areSameExtensions(a: IExtensionIdentifier, b: IExtensionIdentifi
return compareIgnoreCase(a.id, b.id) === 0;
}

export class ExtensionIdentifierWithVersion implements IExtensionIdentifierWithVersion {
export class ExtensionIdentifierWithVersion {

readonly id: string;
readonly uuid?: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { CancellationToken } from 'vs/base/common/cancellation';
import { IExtensionGalleryService, IExtensionManagementService, IGlobalExtensionEnablementService, InstallOperation } from 'vs/platform/extensionManagement/common/extensionManagement';
import { areSameExtensions, getExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { IExtensionStorageService } from 'vs/platform/extensionManagement/common/extensionStorage';
Expand Down Expand Up @@ -30,7 +31,7 @@ export async function migrateUnsupportedExtensions(extensionManagementService: I
continue;
}

const gallery = await galleryService.getCompatibleExtension({ id: preReleaseExtensionId }, true, await extensionManagementService.getTargetPlatform());
const gallery = (await galleryService.getExtensions([{ id: preReleaseExtensionId, preRelease: true }], { targetPlatform: await extensionManagementService.getTargetPlatform(), compatible: true }, CancellationToken.None))[0];
if (!gallery) {
logService.info(`Skipping migrating '${unsupportedExtension.identifier.id}' extension because, the comaptible target '${preReleaseExtensionId}' extension is not found`);
continue;
Expand Down
2 changes: 1 addition & 1 deletion src/vs/platform/userDataSync/common/extensionsSync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse
}

// User Extension Sync: Install/Update, Enablement & State
const extension = (await this.extensionGalleryService.getExtensions([e.identifier], !!e.preRelease, CancellationToken.None))[0];
const extension = (await this.extensionGalleryService.getExtensions([{ ...e.identifier, preRelease: e.preRelease }], CancellationToken.None))[0];

/* Update extension state only if
* extension is installed and version is same as synced version or
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2623,7 +2623,7 @@ export class InstallLocalExtensionsInRemoteAction extends AbstractInstallExtensi
const targetPlatform = await this.extensionManagementServerService.remoteExtensionManagementServer!.extensionManagementService.getTargetPlatform();
await Promises.settled(localExtensionsToInstall.map(async extension => {
if (this.extensionGalleryService.isEnabled()) {
const gallery = await this.extensionGalleryService.getCompatibleExtension(extension.identifier, !!extension.local?.preRelease, targetPlatform);
const gallery = (await this.extensionGalleryService.getExtensions([{ ...extension.identifier, preRelease: !!extension.local?.preRelease }], { targetPlatform, compatible: true }, CancellationToken.None))[0];
if (gallery) {
galleryExtensions.push(gallery);
return;
Expand Down Expand Up @@ -2672,7 +2672,7 @@ export class InstallRemoteExtensionsInLocalAction extends AbstractInstallExtensi
const targetPlatform = await this.extensionManagementServerService.localExtensionManagementServer!.extensionManagementService.getTargetPlatform();
await Promises.settled(extensions.map(async extension => {
if (this.extensionGalleryService.isEnabled()) {
const gallery = await this.extensionGalleryService.getCompatibleExtension(extension.identifier, !!extension.local?.preRelease, targetPlatform);
const gallery = (await this.extensionGalleryService.getExtensions([{ ...extension.identifier, preRelease: !!extension.local?.preRelease }], { targetPlatform, compatible: true }, CancellationToken.None))[0];
if (gallery) {
galleryExtensions.push(gallery);
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ class Extensions extends Disposable {

private async getCompatibleExtension(extensionOrIdentifier: IGalleryExtension | IExtensionIdentifier, includePreRelease: boolean): Promise<IGalleryExtension | null> {
if (isIExtensionIdentifier(extensionOrIdentifier)) {
return this.galleryService.getCompatibleExtension(extensionOrIdentifier, includePreRelease, await this.server.extensionManagementService.getTargetPlatform());
return (await this.galleryService.getExtensions([{ ...extensionOrIdentifier, preRelease: includePreRelease }], { targetPlatform: await this.server.extensionManagementService.getTargetPlatform(), compatible: true }, CancellationToken.None))[0] || null;
}
const extension = extensionOrIdentifier;
if (includePreRelease && extension.hasPreReleaseVersion && !extension.properties.isPreReleaseVersion) {
Expand Down Expand Up @@ -1023,7 +1023,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension

if (identifiers.length) {
const extensionsControlManifest = await this.extensionManagementService.getExtensionsControlManifest();
const galleryExtensions = await this.galleryService.getCompatibleExtensions(identifiers, targetPlatform);
const galleryExtensions = await this.galleryService.getExtensions(identifiers, { targetPlatform, compatible: true }, CancellationToken.None);
galleryExtensions.forEach(gallery => this.fromGallery(gallery, extensionsControlManifest));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ suite('ExtensionsWorkbenchServiceTest', () => {
instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local1, local2]);
instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery1));
instantiationService.stubPromise(IExtensionGalleryService, 'getCompatibleExtension', gallery1);
instantiationService.stubPromise(IExtensionGalleryService, 'getCompatibleExtensions', [gallery1]);
instantiationService.stubPromise(IExtensionGalleryService, 'getExtensions', [gallery1]);
testObject = await aWorkbenchService();
await testObject.queryLocal();

Expand Down Expand Up @@ -433,7 +433,7 @@ suite('ExtensionsWorkbenchServiceTest', () => {
const gallery = aGalleryExtension(local.manifest.name, { identifier: local.identifier });
instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery));
instantiationService.stubPromise(IExtensionGalleryService, 'getCompatibleExtension', gallery);
instantiationService.stubPromise(IExtensionGalleryService, 'getCompatibleExtensions', [gallery]);
instantiationService.stubPromise(IExtensionGalleryService, 'getExtensions', [gallery]);
testObject = await aWorkbenchService();
const target = testObject.local[0];

Expand Down
Loading

0 comments on commit fb26bec

Please sign in to comment.