diff --git a/extensions/resource-deployment/package.json b/extensions/resource-deployment/package.json index 2849b6f27a..c1340550e0 100644 --- a/extensions/resource-deployment/package.json +++ b/extensions/resource-deployment/package.json @@ -254,7 +254,8 @@ "name": "azure-cli" }, { - "name": "azdata" + "name": "azdata", + "version": "15.0.2070" } ], "when": "target=new-aks&&version=bdc2019" diff --git a/extensions/resource-deployment/src/interfaces.ts b/extensions/resource-deployment/src/interfaces.ts index 20804b6db2..2fc32b1e98 100644 --- a/extensions/resource-deployment/src/interfaces.ts +++ b/extensions/resource-deployment/src/interfaces.ts @@ -226,6 +226,7 @@ export const enum ToolStatus { } export interface ITool { + readonly status: ToolStatus; readonly isInstalling: boolean; readonly name: string; readonly displayName: string; @@ -245,6 +246,7 @@ export interface ITool { showOutputChannel(preserveFocus?: boolean): void; loadInformation(): Promise; install(): Promise; + isSameOrNewerThan(version: string): boolean; } export const enum BdcDeploymentType { diff --git a/extensions/resource-deployment/src/services/tools/toolBase.ts b/extensions/resource-deployment/src/services/tools/toolBase.ts index 99024fae08..154311a2d5 100644 --- a/extensions/resource-deployment/src/services/tools/toolBase.ts +++ b/extensions/resource-deployment/src/services/tools/toolBase.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { EOL } from 'os'; import { delimiter } from 'path'; -import { SemVer } from 'semver'; +import { SemVer, compare } from 'semver'; import * as vscode from 'vscode'; import * as nls from 'vscode-nls'; import { Command, ITool, OsType, ToolStatus, ToolType } from '../../interfaces'; @@ -63,11 +63,11 @@ export abstract class ToolBase implements ITool { return this._onDidUpdateData.event; } - protected get status(): ToolStatus { + get status(): ToolStatus { return this._status; } - protected set status(value: ToolStatus) { + set status(value: ToolStatus) { this._status = value; this._onDidUpdateData.fire(this); } @@ -270,6 +270,13 @@ export abstract class ToolBase implements ITool { } } + isSameOrNewerThan(version: string): boolean { + const currentVersion = new SemVer(this.fullVersion!); + const requiredVersion = new SemVer(version); + + return compare(currentVersion, requiredVersion) >= 0; + } + private _storagePathEnsured: boolean = false; private _status: ToolStatus = ToolStatus.NotInstalled; private _osType: OsType; diff --git a/extensions/resource-deployment/src/ui/resourceTypePickerDialog.ts b/extensions/resource-deployment/src/ui/resourceTypePickerDialog.ts index 03d25fd086..34c0dded10 100644 --- a/extensions/resource-deployment/src/ui/resourceTypePickerDialog.ts +++ b/extensions/resource-deployment/src/ui/resourceTypePickerDialog.ts @@ -5,7 +5,7 @@ import * as azdata from 'azdata'; import { EOL } from 'os'; import * as nls from 'vscode-nls'; -import { AgreementInfo, DeploymentProvider, ITool, ResourceType } from '../interfaces'; +import { AgreementInfo, DeploymentProvider, ITool, ResourceType, ToolStatus } from '../interfaces'; import { IResourceTypeService } from '../services/resourceTypeService'; import { IToolsService } from '../services/toolsService'; import { getErrorMessage, setEnvironmentVariablesForInstallPaths } from '../utils'; @@ -84,10 +84,14 @@ export class ResourceTypePickerDialog extends DialogBase { value: localize('deploymentDialog.toolVersionColumnHeader', "Version"), width: 100 }; + const minVersionColumn: azdata.TableColumn = { + value: localize('deploymentDialog.toolMinimumVersionColumnHeader', "Minimum Version"), + width: 100 + }; this._toolsTable = view.modelBuilder.table().withProperties({ data: [], - columns: [toolColumn, descriptionColumn, installStatusColumn, versionColumn], + columns: [toolColumn, descriptionColumn, installStatusColumn, versionColumn, minVersionColumn], width: tableWidth }).component(); @@ -222,6 +226,7 @@ export class ResourceTypePickerDialog extends DialogBase { return; } let autoInstallRequired = false; + let minVersionCheckFailed = false; const messages: string[] = []; this._toolsTable.data = toolRequirements.map(toolReq => { const tool = this.toolsService.getToolByName(toolReq.name)!; @@ -234,19 +239,24 @@ export class ResourceTypePickerDialog extends DialogBase { if (tool.statusDescription !== undefined) { console.warn(localize('deploymentDialog.DetailToolStatusDescription', "Additional status information for tool: '{0}' [ {1} ]. {2}", tool.name, tool.homePage, tool.statusDescription)); } - } + } else if (tool.status === ToolStatus.Installed && toolReq.version && !tool.isSameOrNewerThan(toolReq.version)) { + minVersionCheckFailed = true; + messages.push(localize('deploymentDialog.ToolDoesNotMeetVersionRequirement', "'{0}' [ {1} ] does not meet the minimum version requirement, please uninstall it and restart Azure Data Studio.", tool.displayName, tool.homePage)); - autoInstallRequired = tool.autoInstallRequired; - return [tool.displayName, tool.description, tool.displayStatus, tool.fullVersion || '']; + } + autoInstallRequired = autoInstallRequired || tool.autoInstallRequired; + return [tool.displayName, tool.description, tool.displayStatus, tool.fullVersion || '', toolReq.version || '']; }); this._installToolButton.hidden = !autoInstallRequired; this._dialogObject.okButton.enabled = messages.length === 0 && !autoInstallRequired; if (messages.length !== 0) { - messages.push(localize('deploymentDialog.VersionInformationDebugHint', "You will need to restart Azure Data Studio if the tools are installed by yourself after Azure Data Studio is launched to pick up the updated PATH environment variable. You may find additional details in the debug console by running the 'Toggle Developer Tools' command in the Azure Data Studio Command Palette.")); + if (!minVersionCheckFailed) { + messages.push(localize('deploymentDialog.VersionInformationDebugHint', "You will need to restart Azure Data Studio if the tools are installed by yourself after Azure Data Studio is launched to pick up the updated PATH environment variable. You may find additional details in the debug console by running the 'Toggle Developer Tools' command in the Azure Data Studio Command Palette.")); + } this._dialogObject.message = { level: azdata.window.MessageLevel.Error, - text: localize('deploymentDialog.ToolCheckFailed', "Some required tools are not installed."), + text: localize('deploymentDialog.ToolCheckFailed', "Some required tools are not installed or do not meet the minimum version requirement."), description: messages.join(EOL) }; } else if (autoInstallRequired) { @@ -295,7 +305,7 @@ export class ResourceTypePickerDialog extends DialogBase { public updateToolsDisplayTableData(tool: ITool) { this._toolsTable.data = this._toolsTable.data.map(rowData => { if (rowData[0] === tool.displayName) { - return [tool.displayName, tool.description, tool.displayStatus, tool.fullVersion || '']; + return [tool.displayName, tool.description, tool.displayStatus, tool.fullVersion || '', rowData[4]]; } else { return rowData; }