From 392f4b2af5279baf0ce586bcb3c81e49d5251240 Mon Sep 17 00:00:00 2001 From: Dhruv Manilawala Date: Wed, 3 Jul 2024 14:54:04 +0530 Subject: [PATCH] Better error message for unsupposed Ruff version --- src/common/server.ts | 62 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/common/server.ts b/src/common/server.ts index 5bdd86f..b928fca 100644 --- a/src/common/server.ts +++ b/src/common/server.ts @@ -1,4 +1,5 @@ import * as fsapi from "fs-extra"; +import * as vscode from "vscode"; import { Disposable, l10n, LanguageStatusSeverity, LogOutputChannel } from "vscode"; import { State } from "vscode-languageclient"; import { @@ -48,6 +49,54 @@ function executeCommand(command: string): Promise { }); } +type VersionInfo = { + major: number; + minor: number; + patch: number; +}; + +/** + * Convert a version object to a string. + */ +function versionToString(version: VersionInfo): string { + return `${version.major}.${version.minor}.${version.patch}`; +} + +/** + * The minimum version of the Ruff executable that supports the native server. + */ +const MINIMUM_RUFF_SERVER_VERSION: VersionInfo = { major: 0, minor: 3, patch: 5 }; + +/** + * Check if the given version of the Ruff executable supports the native server. + */ +function supportsNativeServer(version: VersionInfo): boolean { + if (version.major > MINIMUM_RUFF_SERVER_VERSION.major) { + return true; + } + if (version.major === MINIMUM_RUFF_SERVER_VERSION.major) { + if (version.minor > MINIMUM_RUFF_SERVER_VERSION.minor) { + return true; + } + if (version.minor === MINIMUM_RUFF_SERVER_VERSION.minor) { + if (version.patch >= MINIMUM_RUFF_SERVER_VERSION.patch) { + return true; + } + } + } + return false; +} + +/** + * Get the version of the Ruff executable at the given path. + */ +async function getRuffVersion(executable: string): Promise { + const stdout = await executeCommand(`${executable} --version`); + const version = stdout.trim().split(" ")[1]; + const [major, minor, patch] = version.split(".").map((x) => parseInt(x, 10)); + return { major, minor, patch }; +} + async function findRuffBinaryPath(settings: ISettings): Promise { // 'path' setting takes priority over everything. if (settings.path.length > 0) { @@ -103,6 +152,19 @@ async function createNativeServer( initializationOptions: IInitializationOptions, ): Promise { const ruffBinaryPath = await findRuffBinaryPath(settings); + const ruffVersion = await getRuffVersion(ruffBinaryPath); + + if (!supportsNativeServer(ruffVersion)) { + const message = `Native server requires Ruff ${versionToString( + MINIMUM_RUFF_SERVER_VERSION, + )}, but found ${versionToString(ruffVersion)} at ${ruffBinaryPath} instead`; + traceError(message); + await vscode.window.showErrorMessage(message); + return Promise.reject(); + } + + traceInfo(`Found Ruff ${versionToString(ruffVersion)} at ${ruffBinaryPath}`); + const ruffServerArgs = [RUFF_SERVER_SUBCOMMAND, ...RUFF_SERVER_REQUIRED_ARGS]; traceInfo(`Server run command: ${[ruffBinaryPath, ...ruffServerArgs].join(" ")}`);