Skip to content

Commit

Permalink
proposed support for proposed api versioning (#216719)
Browse files Browse the repository at this point in the history
  • Loading branch information
sandy081 authored Jun 20, 2024
1 parent d7792c1 commit 62fbb97
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 17 deletions.
1 change: 1 addition & 0 deletions src/vs/base/common/product.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ export interface IProductConfiguration {
readonly extensionPointExtensionKind?: { readonly [extensionPointId: string]: ('ui' | 'workspace' | 'web')[] };
readonly extensionSyncedKeys?: { readonly [extensionId: string]: string[] };

readonly extensionsEnabledWithApiProposalVersion?: string[];
readonly extensionEnabledApiProposals?: { readonly [extensionId: string]: string[] };
readonly extensionUntrustedWorkspaceSupport?: { readonly [extensionId: string]: ExtensionUntrustedWorkspaceSupport };
readonly extensionVirtualWorkspacesSupport?: { readonly [extensionId: string]: ExtensionVirtualWorkspaceSupport };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,7 @@ abstract class AbstractExtensionGalleryService implements IExtensionGalleryServi
private readonly extensionsControlUrl: string | undefined;

private readonly commonHeadersPromise: Promise<IStringDictionary<string>>;
private readonly extensionsEnabledWithApiProposalVersion: string[];

constructor(
storageService: IStorageService | undefined,
Expand All @@ -614,6 +615,7 @@ abstract class AbstractExtensionGalleryService implements IExtensionGalleryServi
this.extensionsGalleryUrl = isPPEEnabled ? config.servicePPEUrl : config?.serviceUrl;
this.extensionsGallerySearchUrl = isPPEEnabled ? undefined : config?.searchUrl;
this.extensionsControlUrl = config?.controlUrl;
this.extensionsEnabledWithApiProposalVersion = productService.extensionsEnabledWithApiProposalVersion?.map(id => id.toLowerCase()) ?? [];
this.commonHeadersPromise = resolveMarketplaceHeaders(
productService.version,
productService,
Expand Down Expand Up @@ -717,13 +719,23 @@ abstract class AbstractExtensionGalleryService implements IExtensionGalleryServi
return false;
}

if (!areApiProposalsCompatible(extension.properties.enabledApiProposals ?? [])) {
if (!this.areApiProposalsCompatible(extension.identifier, extension.properties.enabledApiProposals)) {
return false;
}

return true;
}

private areApiProposalsCompatible(extensionIdentifier: IExtensionIdentifier, enabledApiProposals: string[] | undefined): boolean {
if (!enabledApiProposals) {
return true;
}
if (!this.extensionsEnabledWithApiProposalVersion.includes(extensionIdentifier.id.toLowerCase())) {
return true;
}
return areApiProposalsCompatible(enabledApiProposals);
}

private async isValidVersion(extension: string, rawGalleryExtensionVersion: IRawGalleryExtensionVersion, versionType: 'release' | 'prerelease' | 'any', compatible: boolean, allTargetPlatforms: TargetPlatform[], targetPlatform: TargetPlatform, productVersion: IProductVersion = { version: this.productService.version, date: this.productService.date }): Promise<boolean> {
if (!isTargetPlatformCompatible(getTargetPlatformForExtensionVersion(rawGalleryExtensionVersion), allTargetPlatforms, targetPlatform)) {
return false;
Expand Down Expand Up @@ -933,15 +945,15 @@ abstract class AbstractExtensionGalleryService implements IExtensionGalleryServi
}
// Allow any version if includePreRelease flag is set otherwise only release versions are allowed
if (await this.isValidVersion(
getGalleryExtensionId(rawGalleryExtension.publisher.publisherName, rawGalleryExtension.extensionName),
extensionIdentifier.id,
rawGalleryExtensionVersion,
includePreRelease ? 'any' : 'release',
criteria.compatible,
allTargetPlatforms,
criteria.targetPlatform,
criteria.productVersion)
) {
if (criteria.compatible && !areApiProposalsCompatible(getEnabledApiProposals(rawGalleryExtensionVersion))) {
if (criteria.compatible && !this.areApiProposalsCompatible(extensionIdentifier, getEnabledApiProposals(rawGalleryExtensionVersion))) {
return null;
}
return toExtension(rawGalleryExtension, rawGalleryExtensionVersion, allTargetPlatforms, queryContext);
Expand Down Expand Up @@ -1196,7 +1208,7 @@ abstract class AbstractExtensionGalleryService implements IExtensionGalleryServi
true,
allTargetPlatforms,
targetPlatform))
&& areApiProposalsCompatible(getEnabledApiProposals(version))
&& this.areApiProposalsCompatible(extensionIdentifier, getEnabledApiProposals(version))
) {
validVersions.push(version);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -554,14 +554,18 @@ type NlsConfiguration = {

class ExtensionsScanner extends Disposable {

private readonly extensionsEnabledWithApiProposalVersion: string[];

constructor(
private readonly obsoleteFile: URI,
@IExtensionsProfileScannerService protected readonly extensionsProfileScannerService: IExtensionsProfileScannerService,
@IUriIdentityService protected readonly uriIdentityService: IUriIdentityService,
@IFileService protected readonly fileService: IFileService,
@IProductService productService: IProductService,
@ILogService protected readonly logService: ILogService
) {
super();
this.extensionsEnabledWithApiProposalVersion = productService.extensionsEnabledWithApiProposalVersion?.map(id => id.toLowerCase()) ?? [];
}

async scanExtensions(input: ExtensionScannerInput): Promise<IRelaxedScannedExtension[]> {
Expand Down Expand Up @@ -653,6 +657,9 @@ class ExtensionsScanner extends Disposable {
const type = metadata?.isSystem ? ExtensionType.System : input.type;
const isBuiltin = type === ExtensionType.System || !!metadata?.isBuiltin;
manifest = await this.translateManifest(input.location, manifest, ExtensionScannerInput.createNlsConfiguration(input));
if (manifest.enabledApiProposals && !this.extensionsEnabledWithApiProposalVersion?.includes(id.toLowerCase())) {
manifest.enabledApiProposals = parseEnabledApiProposalNames([...manifest.enabledApiProposals]);
}
const extension: IRelaxedScannedExtension = {
type,
identifier,
Expand Down Expand Up @@ -689,7 +696,7 @@ class ExtensionsScanner extends Disposable {
return extension;
}

async scanExtensionManifest(extensionLocation: URI): Promise<IScannedExtensionManifest | null> {
private async scanExtensionManifest(extensionLocation: URI): Promise<IScannedExtensionManifest | null> {
const manifestLocation = joinPath(extensionLocation, 'package.json');
let content;
try {
Expand Down Expand Up @@ -878,9 +885,10 @@ class CachedExtensionsScanner extends ExtensionsScanner {
@IExtensionsProfileScannerService extensionsProfileScannerService: IExtensionsProfileScannerService,
@IUriIdentityService uriIdentityService: IUriIdentityService,
@IFileService fileService: IFileService,
@IProductService productService: IProductService,
@ILogService logService: ILogService
) {
super(obsoleteFile, extensionsProfileScannerService, uriIdentityService, fileService, logService);
super(obsoleteFile, extensionsProfileScannerService, uriIdentityService, fileService, productService, logService);
}

override async scanExtensions(input: ExtensionScannerInput): Promise<IRelaxedScannedExtension[]> {
Expand Down Expand Up @@ -983,7 +991,6 @@ export function toExtensionDescription(extension: IScannedExtension, isUnderDeve
targetPlatform: extension.targetPlatform,
publisherDisplayName: extension.publisherDisplayName,
...extension.manifest,
enabledApiProposals: extension.manifest.enabledApiProposals ? parseEnabledApiProposalNames([...extension.manifest.enabledApiProposals]) : undefined,
};
}

Expand Down
6 changes: 2 additions & 4 deletions src/vs/platform/extensions/common/extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ export class ExtensionIdentifierMap<T> {
}
}

interface IRelaxedExtensionDescription extends IRelaxedExtensionManifest {
export interface IRelaxedExtensionDescription extends IRelaxedExtensionManifest {
id?: string;
identifier: ExtensionIdentifier;
uuid?: string;
Expand All @@ -470,9 +470,7 @@ interface IRelaxedExtensionDescription extends IRelaxedExtensionManifest {
extensionLocation: URI;
}

export type IExtensionDescription = Readonly<IRelaxedExtensionDescription> & {
enabledApiProposals: string[] | undefined; // This needs to be updated while validating & updating the proposals.
};
export type IExtensionDescription = Readonly<IRelaxedExtensionDescription>;

export function isApplicationScopedExtension(manifest: IExtensionManifest): boolean {
return isLanguagePackExtension(manifest);
Expand Down
8 changes: 3 additions & 5 deletions src/vs/workbench/services/extensions/common/extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { URI } from 'vs/base/common/uri';
import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc';
import { getExtensionId, getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { ImplicitActivationEvents } from 'vs/platform/extensionManagement/common/implicitActivationEvents';
import { ExtensionIdentifier, ExtensionIdentifierMap, ExtensionIdentifierSet, ExtensionType, IExtension, IExtensionContributions, IExtensionDescription, parseEnabledApiProposalNames, TargetPlatform } from 'vs/platform/extensions/common/extensions';
import { ExtensionIdentifier, ExtensionIdentifierMap, ExtensionIdentifierSet, ExtensionType, IExtension, IExtensionContributions, IExtensionDescription, TargetPlatform } from 'vs/platform/extensions/common/extensions';
import { ApiProposalName } from 'vs/platform/extensions/common/extensionsApiProposals';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IV8Profile } from 'vs/platform/profiling/common/profiling';
Expand All @@ -28,8 +28,7 @@ export const nullExtensionDescription = Object.freeze<IExtensionDescription>({
isBuiltin: false,
targetPlatform: TargetPlatform.UNDEFINED,
isUserBuiltin: false,
isUnderDevelopment: false,
enabledApiProposals: undefined,
isUnderDevelopment: false
});

export type WebWorkerExtHostConfigValue = boolean | 'auto';
Expand Down Expand Up @@ -570,8 +569,7 @@ export function toExtensionDescription(extension: IExtension, isUnderDevelopment
uuid: extension.identifier.uuid,
targetPlatform: extension.targetPlatform,
publisherDisplayName: extension.publisherDisplayName,
...extension.manifest,
enabledApiProposals: extension.manifest.enabledApiProposals ? parseEnabledApiProposalNames([...extension.manifest.enabledApiProposals]) : undefined,
...extension.manifest
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { Registry } from 'vs/platform/registry/common/platform';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { Extensions, IExtensionFeatureMarkdownRenderer, IExtensionFeaturesRegistry, IRenderedData } from 'vs/workbench/services/extensionManagement/common/extensionFeatures';
import { IMarkdownString, MarkdownString } from 'vs/base/common/htmlContent';
import { Mutable } from 'vs/base/common/types';

export class ExtensionsProposedApi {

Expand Down Expand Up @@ -60,7 +61,7 @@ export class ExtensionsProposedApi {
}
}

private doUpdateEnabledApiProposals(extension: IExtensionDescription): void {
private doUpdateEnabledApiProposals(extension: Mutable<IExtensionDescription>): void {

const key = ExtensionIdentifier.toKey(extension.identifier);

Expand Down

0 comments on commit 62fbb97

Please sign in to comment.