From 2ed8aeb56590bb0404cf3118e8f958b2370d9c3b Mon Sep 17 00:00:00 2001 From: Z Chen <13544267+zijchen@users.noreply.github.com> Date: Thu, 21 Oct 2021 13:48:52 -0700 Subject: [PATCH] Warning when .NET 6 SDK is detected (#17422) * Check for max supported version * Separate dialog for downgrade warning * Address PR comments * Use markdown link * Update warning message --- extensions/sql-database-projects/package.json | 4 ++ .../sql-database-projects/package.nls.json | 1 + .../src/common/constants.ts | 2 + .../src/tools/netcoreTool.ts | 54 +++++++++++++------ 4 files changed, 45 insertions(+), 16 deletions(-) diff --git a/extensions/sql-database-projects/package.json b/extensions/sql-database-projects/package.json index 0eeb85ad57..63d89f7eef 100644 --- a/extensions/sql-database-projects/package.json +++ b/extensions/sql-database-projects/package.json @@ -45,6 +45,10 @@ "type": "boolean", "description": "%sqlDatabaseProjects.netCoreDoNotAsk%" }, + "sqlDatabaseProjects.netCoreDowngradeDoNotShow": { + "type": "boolean", + "description": "%sqlDatabaseProjects.netCoreDowngradeDoNotShow%" + }, "sqlDatabaseProjects.nodejsDoNotAsk": { "type": "boolean", "description": "%sqlDatabaseProjects.nodejsDoNotAsk%" diff --git a/extensions/sql-database-projects/package.nls.json b/extensions/sql-database-projects/package.nls.json index f64571ad6d..f1482deb57 100644 --- a/extensions/sql-database-projects/package.nls.json +++ b/extensions/sql-database-projects/package.nls.json @@ -35,6 +35,7 @@ "sqlDatabaseProjects.Settings": "Database Projects", "sqlDatabaseProjects.netCoreInstallLocation": "Full path to .NET Core SDK on the machine.", "sqlDatabaseProjects.netCoreDoNotAsk": "Whether to prompt the user to install .NET Core when not detected.", + "sqlDatabaseProjects.netCoreDowngradeDoNotShow": "Whether to prompt the user to set .NET SDK version when a newer unsupported version is detected.", "sqlDatabaseProjects.nodejsDoNotAsk": "Whether to prompt the user to install Node.js when not detected.", "sqlDatabaseProjects.autorestSqlVersion": "Which version of Autorest.Sql to use from NPM. Latest will be used if not set.", "sqlDatabaseProjects.welcome": "No database projects currently open.\n[New Project](command:sqlDatabaseProjects.new)\n[Open Project](command:sqlDatabaseProjects.open)\n[Create Project From Database](command:sqlDatabaseProjects.importDatabase)", diff --git a/extensions/sql-database-projects/src/common/constants.ts b/extensions/sql-database-projects/src/common/constants.ts index 8229ec044c..6b4eb800d1 100644 --- a/extensions/sql-database-projects/src/common/constants.ts +++ b/extensions/sql-database-projects/src/common/constants.ts @@ -314,12 +314,14 @@ export const postDeployScriptFriendlyName = localize('postDeployScriptFriendlyNa export const NetCoreInstallationConfirmation: string = localize('sqlDatabaseProjects.NetCoreInstallationConfirmation', "The .NET Core SDK cannot be located. Project build will not work. Please install .NET Core SDK version 3.1 or update the .NET Core SDK location in settings if already installed."); export function NetCoreSupportedVersionInstallationConfirmation(installedVersion: string) { return localize('sqlDatabaseProjects.NetCoreSupportedVersionInstallationConfirmation', "Currently installed .NET Core SDK version is {0}, which is not supported. Project build will not work. Please install .NET Core SDK version 3.1 or update the .NET Core SDK supported version location in settings if already installed.", installedVersion); } +export function NetCoreVersionDowngradeConfirmation(installedVersion: string) { return localize('sqlDatabaseProjects.NetCoreVersionDowngradeConfirmation', "Installed .NET SDK version {0} is newer than the currently supported versions. Project build will not work. Please install .NET Core SDK version 3.1 and include a global.json in the project folder specifying the SDK version to use. [More Information](https://docs.microsoft.com/dotnet/core/versions/selection)", installedVersion); } export const UpdateNetCoreLocation: string = localize('sqlDatabaseProjects.UpdateNetCoreLocation', "Update Location"); export const projectsOutputChannel = localize('sqlDatabaseProjects.outputChannel', "Database Projects"); // Prompt buttons export const Install: string = localize('sqlDatabaseProjects.Install', "Install"); export const DoNotAskAgain: string = localize('sqlDatabaseProjects.doNotAskAgain', "Don't Ask Again"); +export const DoNotShowAgain: string = localize('sqlDatabaseProjects.doNotShowAgain', "Don't Show Again"); // SqlProj file XML names export const ItemGroup = 'ItemGroup'; diff --git a/extensions/sql-database-projects/src/tools/netcoreTool.ts b/extensions/sql-database-projects/src/tools/netcoreTool.ts index 5e57709084..ed51d12882 100644 --- a/extensions/sql-database-projects/src/tools/netcoreTool.ts +++ b/extensions/sql-database-projects/src/tools/netcoreTool.ts @@ -11,7 +11,7 @@ import * as semver from 'semver'; import { isNullOrUndefined } from 'util'; import * as vscode from 'vscode'; import * as nls from 'vscode-nls'; -import { DoNotAskAgain, Install, NetCoreInstallationConfirmation, NetCoreSupportedVersionInstallationConfirmation, UpdateNetCoreLocation } from '../common/constants'; +import { DoNotAskAgain, DoNotShowAgain, Install, NetCoreInstallationConfirmation, NetCoreSupportedVersionInstallationConfirmation, NetCoreVersionDowngradeConfirmation, UpdateNetCoreLocation } from '../common/constants'; import * as utils from '../common/utils'; import { ShellCommandOptions, ShellExecutionHelper } from './shellExecutionHelper'; const localize = nls.loadMessageBundle(); @@ -19,16 +19,19 @@ const localize = nls.loadMessageBundle(); export const DBProjectConfigurationKey: string = 'sqlDatabaseProjects'; export const NetCoreInstallLocationKey: string = 'netCoreSDKLocation'; export const NetCoreDoNotAskAgainKey: string = 'netCoreDoNotAsk'; +export const NetCoreDowngradeDoNotShowAgainKey: string = 'netCoreDowngradeDoNotShow'; export const NetCoreNonWindowsDefaultPath = '/usr/local/share'; export const winPlatform: string = 'win32'; export const macPlatform: string = 'darwin'; export const linuxPlatform: string = 'linux'; export const minSupportedNetCoreVersion: string = '3.1.0'; +export const maxSupportedNetCoreVersionCutoff: string = '6.0.0'; // un-set this to allow latest export const enum netCoreInstallState { netCoreNotPresent, netCoreVersionNotSupported, - netCoreVersionSupported + netCoreVersionSupported, + netCoreVersionTooHigh } const dotnet = os.platform() === 'win32' ? 'dotnet.exe' : 'dotnet'; @@ -46,8 +49,10 @@ export class NetCoreTool extends ShellExecutionHelper { */ public async findOrInstallNetCore(): Promise { if ((!this.isNetCoreInstallationPresent || !await this.isNetCoreVersionSupported())) { - if (vscode.workspace.getConfiguration(DBProjectConfigurationKey)[NetCoreDoNotAskAgainKey] !== true) { + if (this.netCoreInstallState === netCoreInstallState.netCoreVersionSupported && vscode.workspace.getConfiguration(DBProjectConfigurationKey)[NetCoreDoNotAskAgainKey] !== true) { void this.showInstallDialog(); // Removing await so that Build and extension load process doesn't wait on user input + } else if (this.netCoreInstallState === netCoreInstallState.netCoreVersionTooHigh && vscode.workspace.getConfiguration(DBProjectConfigurationKey)[NetCoreDowngradeDoNotShowAgainKey] !== true) { + void this.showDowngradeDialog(); } return false; } @@ -80,6 +85,15 @@ export class NetCoreTool extends ShellExecutionHelper { } } + public async showDowngradeDialog(): Promise { + const result = await vscode.window.showErrorMessage(NetCoreVersionDowngradeConfirmation(this.netCoreSdkInstalledVersion!), DoNotShowAgain); + + if (result === DoNotShowAgain) { + const config = vscode.workspace.getConfiguration(DBProjectConfigurationKey); + await config.update(NetCoreDowngradeDoNotShowAgainKey, true, vscode.ConfigurationTarget.Global); + } + } + private get isNetCoreInstallationPresent(): boolean { const netCoreInstallationPresent = (!isNullOrUndefined(this.netcoreInstallLocation) && fs.existsSync(this.netcoreInstallLocation)); if (!netCoreInstallationPresent) { @@ -122,8 +136,8 @@ export class NetCoreTool extends ShellExecutionHelper { } /** - * This function checks if the installed dotnet version is atleast minSupportedNetCoreVersion. - * Versions lower than minSupportedNetCoreVersion aren't supported for building projects. + * This function checks if the installed dotnet version is between minSupportedNetCoreVersion (inclusive) and maxSupportedNetCoreVersionCutoff (exclusive). + * When maxSupportedNetCoreVersionCutoff is not set, the latest dotnet version is assumed to be supported and only the min version is checked. * Returns: True if installed dotnet version is supported, false otherwise. * Undefined if dotnet isn't installed. */ @@ -131,7 +145,7 @@ export class NetCoreTool extends ShellExecutionHelper { try { const spawn = child_process.spawn; let child: child_process.ChildProcessWithoutNullStreams; - let isSupported: boolean | undefined = undefined; + let installState: netCoreInstallState = netCoreInstallState.netCoreVersionSupported; const stdoutBuffers: Buffer[] = []; child = spawn('dotnet --version', [], { @@ -145,10 +159,21 @@ export class NetCoreTool extends ShellExecutionHelper { this.netCoreSdkInstalledVersion = Buffer.concat(stdoutBuffers).toString('utf8').trim(); try { - if (semver.gte(this.netCoreSdkInstalledVersion, minSupportedNetCoreVersion)) { // Net core version greater than or equal to minSupportedNetCoreVersion are supported for Build - isSupported = true; + // minSupportedDotnetVersion <= supported version < maxSupportedDotnetVersion + if (semver.gte(this.netCoreSdkInstalledVersion, minSupportedNetCoreVersion)) { + // If maxSupportedNetCoreVersionCutoff is not set, the latest .NET version is allowed + if (maxSupportedNetCoreVersionCutoff) { + if (semver.lt(this.netCoreSdkInstalledVersion, maxSupportedNetCoreVersionCutoff)) { + installState = netCoreInstallState.netCoreVersionSupported; + } else { + installState = netCoreInstallState.netCoreVersionTooHigh; + } + } else { + installState = netCoreInstallState.netCoreVersionSupported; + } } else { - isSupported = false; + // .NET version is too low + installState = netCoreInstallState.netCoreVersionNotSupported; } resolve({ stdout: this.netCoreSdkInstalledVersion }); } catch (err) { @@ -163,13 +188,8 @@ export class NetCoreTool extends ShellExecutionHelper { }); }); - if (isSupported) { - this.netCoreInstallState = netCoreInstallState.netCoreVersionSupported; - } else { - this.netCoreInstallState = netCoreInstallState.netCoreVersionNotSupported; - } - - return isSupported; + this.netCoreInstallState = installState; + return installState === netCoreInstallState.netCoreVersionSupported; } catch (err) { console.log(err); this.netCoreInstallState = netCoreInstallState.netCoreNotPresent; @@ -185,6 +205,8 @@ export class NetCoreTool extends ShellExecutionHelper { if (!(await this.findOrInstallNetCore())) { if (this.netCoreInstallState === netCoreInstallState.netCoreNotPresent) { throw new DotNetError(NetCoreInstallationConfirmation); + } else if (this.netCoreInstallState === netCoreInstallState.netCoreVersionTooHigh && vscode.workspace.getConfiguration(DBProjectConfigurationKey)[NetCoreDowngradeDoNotShowAgainKey] === true) { + // Assume user has used global.json to override SDK version and proceed with build as is } else { throw new DotNetError(NetCoreSupportedVersionInstallationConfirmation(this.netCoreSdkInstalledVersion!)); }