Enforce vscode and ads version check when installing extensions (#4267)

* engine check when install extension

* gallery install/update and vsix install

* FIX COMMENTS

* Fix the detail not loading issue when version is invalid

* add more comments and adress PR comments

* add install telemetry for install from vsix scenario

* correct the name of the version property for telemetry
This commit is contained in:
Alan Ren
2019-03-07 13:04:50 -08:00
committed by GitHub
parent c8bde41451
commit 9e1f04e476
19 changed files with 143 additions and 73 deletions

View File

@@ -117,7 +117,7 @@ export interface IExtensionManifest {
publisher: string;
version: string;
// {{SQL CARBON EDIT}}
engines: { vscode: string; sqlops?: string };
engines: { vscode: string; azdata?: string };
displayName?: string;
description?: string;
main?: string;
@@ -141,6 +141,8 @@ export interface IGalleryExtensionProperties {
dependencies?: string[];
extensionPack?: string[];
engine?: string;
// {{SQL CARBON EDIT}}
azDataEngine?: string;
localizedLanguages?: string[];
}

View File

@@ -71,7 +71,9 @@ export function getLocalExtensionTelemetryData(extension: ILocalExtension): any
publisherId: extension.metadata ? extension.metadata.publisherId : null,
publisherName: extension.manifest.publisher,
publisherDisplayName: extension.metadata ? extension.metadata.publisherDisplayName : null,
dependencies: extension.manifest.extensionDependencies && extension.manifest.extensionDependencies.length > 0
dependencies: extension.manifest.extensionDependencies && extension.manifest.extensionDependencies.length > 0,
// {{SQL CARBON EDIT}}
extensionVersion: extension.manifest.version
};
}
@@ -99,6 +101,8 @@ export function getGalleryExtensionTelemetryData(extension: IGalleryExtension):
publisherName: extension.publisher,
publisherDisplayName: extension.publisherDisplayName,
dependencies: !!(extension.properties.dependencies && extension.properties.dependencies.length > 0),
// {{SQL CARBON EDIT}}
extensionVersion: extension.version,
...extension.telemetryData
};
}

View File

@@ -123,6 +123,8 @@ const PropertyType = {
Dependency: 'Microsoft.VisualStudio.Code.ExtensionDependencies',
ExtensionPack: 'Microsoft.VisualStudio.Code.ExtensionPack',
Engine: 'Microsoft.VisualStudio.Code.Engine',
// {{SQL CARBON EDIT}}
AzDataEngine: 'Microsoft.AzDataEngine',
LocalizedLanguages: 'Microsoft.VisualStudio.Code.LocalizedLanguages'
};
@@ -298,6 +300,12 @@ function getEngine(version: IRawGalleryExtensionVersion): string {
return (values.length > 0 && values[0].value) || '';
}
// {{SQL CARBON EDIT}}
function getAzureDataStudioEngine(version: IRawGalleryExtensionVersion): string {
const values = version.properties ? version.properties.filter(p => p.key === PropertyType.AzDataEngine) : [];
return (values.length > 0 && values[0].value) || '';
}
function getLocalizedLanguages(version: IRawGalleryExtensionVersion): string[] {
const values = version.properties ? version.properties.filter(p => p.key === PropertyType.LocalizedLanguages) : [];
const value = (values.length > 0 && values[0].value) || '';
@@ -343,6 +351,8 @@ function toExtension(galleryExtension: IRawGalleryExtension, version: IRawGaller
dependencies: getExtensions(version, PropertyType.Dependency),
extensionPack: getExtensions(version, PropertyType.ExtensionPack),
engine: getEngine(version),
// {{SQL CARBON EDIT}}
azDataEngine: getAzureDataStudioEngine(version),
localizedLanguages: getLocalizedLanguages(version)
},
/* __GDPR__FRAGMENT__
@@ -724,7 +734,12 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
}
loadCompatibleVersion(extension: IGalleryExtension, fromVersion: string = extension.version): Promise<IGalleryExtension> {
if (extension.version === fromVersion && extension.properties.engine && isEngineValid(extension.properties.engine)) {
// {{SQL CARBON EDIT}}
// Change to original version: removed the extension version validation
// Reason: This method is used to find the matching gallery extension for the locally installed extension,
// since we only have one entry for each extension (not in-scope to enable mutiple version support for now),
// if the new version of extension is not compatible, the extension won't be displayed properly.
if (extension.version === fromVersion) {
return Promise.resolve(extension);
}
const query = new Query()

View File

@@ -46,6 +46,9 @@ import { CancellationToken } from 'vs/base/common/cancellation';
import { getPathFromAmdModule } from 'vs/base/common/amd';
import { getManifest } from 'vs/platform/extensionManagement/node/extensionManagementUtil';
// {{SQL CARBON EDIT}
import product from 'vs/platform/node/product';
const ERROR_SCANNING_SYS_EXTENSIONS = 'scanningSystem';
const ERROR_SCANNING_USER_EXTENSIONS = 'scanningUser';
const INSTALL_ERROR_UNSET_UNINSTALLED = 'unsetUninstalled';
@@ -188,6 +191,9 @@ export class ExtensionManagementService extends Disposable implements IExtension
}
install(vsix: URI, type: LocalExtensionType = LocalExtensionType.User): Promise<IExtensionIdentifier> {
// {{SQL CARBON EDIT}}
let startTime = new Date().getTime();
this.logService.trace('ExtensionManagementService#install', vsix.toString());
return createCancelablePromise(token => {
return this.downloadVsix(vsix)
@@ -197,10 +203,11 @@ export class ExtensionManagementService extends Disposable implements IExtension
return getManifest(zipPath)
.then(manifest => {
const identifier = { id: getLocalExtensionIdFromManifest(manifest) };
// {{SQL CARBON EDIT - Remove VS Code version check}}
// if (manifest.engines && manifest.engines.vscode && !isEngineValid(manifest.engines.vscode)) {
// return Promise.reject(new Error(nls.localize('incompatible', "Unable to install extension '{0}' as it is not compatible with VS Code '{1}'.", identifier.id, pkg.version)));
// }
// {{SQL CARBON EDIT - Check VSCode and ADS version}}
if (manifest.engines && (!isEngineValid(manifest.engines.vscode, product.vscodeVersion)
|| (manifest.engines.azdata && !isEngineValid(manifest.engines.azdata, pkg.version)))) {
return Promise.reject(new Error(nls.localize('incompatible', "Unable to install version '{2}' of extension '{0}' as it is not compatible with Azure Data Studio '{1}'.", identifier.id, pkg.version, manifest.version)));
}
return this.removeIfExists(identifier.id)
.then(
() => {
@@ -216,10 +223,13 @@ export class ExtensionManagementService extends Disposable implements IExtension
// {{SQL CARBON EDIT}}
// Until there's a gallery for SQL Ops Studio, skip retrieving the metadata from the gallery
return this.installExtension({ zipPath, id: identifier.id, metadata: null }, type, token)
.then(
local => this._onDidInstallExtension.fire({ identifier, zipPath, local, operation: InstallOperation.Install }),
error => { this._onDidInstallExtension.fire({ identifier, zipPath, error, operation: InstallOperation.Install }); return Promise.reject(error); }
);
.then(
local => {
this.reportTelemetry(this.getTelemetryEvent(InstallOperation.Install), getLocalExtensionTelemetryData(local), new Date().getTime() - startTime, void 0);
this._onDidInstallExtension.fire({ identifier, zipPath, local, operation: InstallOperation.Install });
},
error => { this._onDidInstallExtension.fire({ identifier, zipPath, error, operation: InstallOperation.Install }); return Promise.reject(error); }
);
// return this.getMetadata(getGalleryExtensionId(manifest.publisher, manifest.name))
// .then(
// metadata => this.installFromZipPath(identifier, zipPath, metadata, type, token),