提交 477cfc42 编写于 作者: S Sandeep Somavarapu

Implement #11573: engine property for version check otherwise fallback

上级 9bab7a5f
......@@ -105,6 +105,7 @@ export interface IExtensionIdentity {
export interface IGalleryExtensionProperties {
dependencies?: string[];
engine?: string;
}
export interface IGalleryExtensionAssets {
......@@ -132,6 +133,7 @@ export interface IGalleryExtension {
assets: IGalleryExtensionAssets;
properties: IGalleryExtensionProperties;
downloadHeaders: { [key: string]: string; };
isCompatible: boolean;
}
export interface IGalleryMetadata {
......
......@@ -20,7 +20,7 @@ import { IRequestOptions, IRequestContext, download, asJson } from 'vs/base/node
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import pkg from 'vs/platform/package';
import product from 'vs/platform/product';
import { isValidExtensionVersion } from 'vs/platform/extensions/node/extensionValidator';
import { isValidExtensionVersion, validateVersions } from 'vs/platform/extensions/node/extensionValidator';
import * as url from 'url';
interface IRawGalleryExtensionFile {
......@@ -102,7 +102,8 @@ const AssetType = {
};
const PropertyType = {
Dependency: 'Microsoft.VisualStudio.Code.ExtensionDependencies'
Dependency: 'Microsoft.VisualStudio.Code.ExtensionDependencies',
Engine: 'Microsoft.VisualStudio.Code.Engine'
};
interface ICriterium {
......@@ -197,6 +198,13 @@ function getDependencies(version: IRawGalleryExtensionVersion): string[] {
}
return [];
}
function getEngine(version: IRawGalleryExtensionVersion): string {
const values = version.properties ? version.properties.filter(p => p.key === PropertyType.Engine) : [];
if (values.length && values[0].value) {
return values[0].value;
}
return '';
}
function toExtension(galleryExtension: IRawGalleryExtension, extensionsGalleryUrl: string, downloadHeaders: { [key: string]: string; }): IGalleryExtension {
const [version] = galleryExtension.versions;
......@@ -236,9 +244,11 @@ function toExtension(galleryExtension: IRawGalleryExtension, extensionsGalleryUr
ratingCount: getStatistic(galleryExtension.statistics, 'ratingcount'),
assets,
properties: {
dependencies: getDependencies(version)
dependencies: getDependencies(version),
engine: getEngine(version)
},
downloadHeaders
downloadHeaders,
isCompatible: false
};
}
......@@ -384,7 +394,13 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
}
loadCompatibleVersion(extension: IGalleryExtension): TPromise<IGalleryExtension> {
// TODO:sandy: Check if the given version is compatible
if (extension.isCompatible) {
return TPromise.wrap(extension);
}
if (extension.assets.download && extension.properties.engine && validateVersions(pkg.version, extension.properties.engine, [])) {
extension.isCompatible = true;
return TPromise.wrap(extension);
}
const query = new Query()
.withFlags(Flags.IncludeVersions, Flags.IncludeFiles, Flags.IncludeVersionProperties)
.withPage(1, 1)
......@@ -400,7 +416,9 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
return this.getLastValidExtensionVersion(rawExtension, rawExtension.versions)
.then(rawVersion => {
extension.properties.dependencies = getDependencies(rawVersion);
extension.assets.download = `${ getAssetSource(rawVersion.files, AssetType.VSIX) }?install=true`;
extension.properties.engine = getEngine(rawVersion);
extension.assets.download = `${getAssetSource(rawVersion.files, AssetType.VSIX)}?install=true`;
extension.isCompatible = true;
return extension;
});
});
......@@ -408,7 +426,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
private loadDependencies(extensionNames: string[]): TPromise<IGalleryExtension[]> {
let query = new Query()
.withFlags(Flags.IncludeVersions, Flags.IncludeAssetUri, Flags.IncludeStatistics, Flags.IncludeFiles, Flags.IncludeVersionProperties)
.withFlags(Flags.IncludeLatestVersionOnly, Flags.IncludeAssetUri, Flags.IncludeStatistics, Flags.IncludeFiles, Flags.IncludeVersionProperties)
.withPage(1, extensionNames.length)
.withFilter(FilterType.Target, 'Microsoft.VisualStudio.Code')
.withAssetTypes(AssetType.Icon, AssetType.License, AssetType.Details, AssetType.Manifest, AssetType.VSIX);
......@@ -419,10 +437,12 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
.then(downloadHeaders => {
const dependencies = [];
const ids = [];
for (const galleryExtension of result.galleryExtensions) {
if (ids.indexOf(galleryExtension.extensionId) === -1) {
dependencies.push(toExtension(galleryExtension, this.extensionsGalleryUrl, downloadHeaders));
ids.push(galleryExtension.extensionId);
for (const rawExtension of result.galleryExtensions) {
if (ids.indexOf(rawExtension.extensionId) === -1) {
const galleryExtension = toExtension(rawExtension, this.extensionsGalleryUrl, downloadHeaders);
galleryExtension.isCompatible = galleryExtension.properties.engine && validateVersions(pkg.version, galleryExtension.properties.engine, []);
dependencies.push(galleryExtension);
ids.push(rawExtension.extensionId);
}
}
return dependencies;
......@@ -439,7 +459,6 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
return TPromise.wrap(result);
}
return this.loadDependencies(toGet)
.then(loadedDependencies => {
const dependenciesSet = new ArraySet<string>();
......@@ -474,6 +493,27 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
}
private getLastValidExtensionVersion(extension: IRawGalleryExtension, versions: IRawGalleryExtensionVersion[]): TPromise<IRawGalleryExtensionVersion> {
const version = this.getLastValidExtensionVersionFromProperties(versions);
if (version) {
return TPromise.wrap(version);
}
return this.getLastValidExtensionVersionReccursively(extension, versions);
}
private getLastValidExtensionVersionFromProperties(versions: IRawGalleryExtensionVersion[]): IRawGalleryExtensionVersion {
for (const version of versions) {
const engine = getEngine(version);
if (!engine) {
return null;
}
if (validateVersions(pkg.version, engine, [])) {
return version;
}
}
return null;
}
private getLastValidExtensionVersionReccursively(extension: IRawGalleryExtension, versions: IRawGalleryExtensionVersion[]): TPromise<IRawGalleryExtensionVersion> {
if (!versions.length) {
return TPromise.wrapError(new Error(localize('noCompatible', "Couldn't find a compatible version of {0} with this version of Code.", extension.displayName || extension.extensionName)));
}
......@@ -495,7 +535,8 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
if (!isValidExtensionVersion(pkg.version, desc, [])) {
return this.getLastValidExtensionVersion(extension, versions.slice(1));
}
version.properties = version.properties || [];
version.properties.push({ key: PropertyType.Engine, value: manifest.engines.vscode });
return version;
});
}
......
......@@ -194,9 +194,14 @@ export function isValidExtensionVersion(version: string, extensionDesc: IReduced
return true;
}
let desiredVersion = normalizeVersion(parseVersion(extensionDesc.engines.vscode));
return validateVersions(version, extensionDesc.engines.vscode, notices);
}
export function validateVersions(currentVersion: string, requestedVersion: string, notices: string[]): boolean {
let desiredVersion = normalizeVersion(parseVersion(requestedVersion));
if (!desiredVersion) {
notices.push(nls.localize('versionSyntax', "Could not parse `engines.vscode` value {0}. Please use, for example: ^0.10.0, ^1.2.3, ^0.11.0, ^0.10.x, etc.", extensionDesc.engines.vscode));
notices.push(nls.localize('versionSyntax', "Could not parse `engines.vscode` value {0}. Please use, for example: ^0.10.0, ^1.2.3, ^0.11.0, ^0.10.x, etc.", requestedVersion));
return false;
}
......@@ -206,19 +211,19 @@ export function isValidExtensionVersion(version: string, extensionDesc: IReduced
if (desiredVersion.majorBase === 0) {
// force that major and minor must be specific
if (!desiredVersion.majorMustEqual || !desiredVersion.minorMustEqual) {
notices.push(nls.localize('versionSpecificity1', "Version specified in `engines.vscode` ({0}) is not specific enough. For vscode versions before 1.0.0, please define at a minimum the major and minor desired version. E.g. ^0.10.0, 0.10.x, 0.11.0, etc.", extensionDesc.engines.vscode));
notices.push(nls.localize('versionSpecificity1', "Version specified in `engines.vscode` ({0}) is not specific enough. For vscode versions before 1.0.0, please define at a minimum the major and minor desired version. E.g. ^0.10.0, 0.10.x, 0.11.0, etc.", requestedVersion));
return false;
}
} else {
// force that major must be specific
if (!desiredVersion.majorMustEqual) {
notices.push(nls.localize('versionSpecificity2', "Version specified in `engines.vscode` ({0}) is not specific enough. For vscode versions after 1.0.0, please define at a minimum the major desired version. E.g. ^1.10.0, 1.10.x, 1.x.x, 2.x.x, etc.", extensionDesc.engines.vscode));
notices.push(nls.localize('versionSpecificity2', "Version specified in `engines.vscode` ({0}) is not specific enough. For vscode versions after 1.0.0, please define at a minimum the major desired version. E.g. ^1.10.0, 1.10.x, 1.x.x, 2.x.x, etc.", requestedVersion));
return false;
}
}
if (!isValidVersion(version, desiredVersion)) {
notices.push(nls.localize('versionMismatch', "Extension is not compatible with Code {0}. Extension requires: {1}.", version, extensionDesc.engines.vscode));
if (!isValidVersion(currentVersion, desiredVersion)) {
notices.push(nls.localize('versionMismatch', "Extension is not compatible with Code {0}. Extension requires: {1}.", currentVersion, requestedVersion));
return false;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册