From c5164be809d5e4a26307107fa995b445cf7e63cb Mon Sep 17 00:00:00 2001 From: will-v-pi <108662275+will-v-pi@users.noreply.github.com> Date: Tue, 24 Sep 2024 16:49:06 +0100 Subject: [PATCH] Add git version check before using system git (#93) --- src/utils/gitUtil.mts | 53 ++++++++++++++++++++++++++++++---- src/utils/requirementsUtil.mts | 18 ++++++++++++ 2 files changed, 65 insertions(+), 6 deletions(-) diff --git a/src/utils/gitUtil.mts b/src/utils/gitUtil.mts index ed5f2ba..b073471 100644 --- a/src/utils/gitUtil.mts +++ b/src/utils/gitUtil.mts @@ -7,9 +7,31 @@ import { SettingsKey, HOME_VAR } from "../settings.mjs"; import { homedir } from "os"; import which from "which"; import { window } from "vscode"; +import { compareGe } from "./semverUtil.mjs"; export const execAsync = promisify(exec); +export const MIN_GIT_VERSION="2.28.0"; + +export async function checkGitVersion(gitExecutable: string): + Promise<[boolean, string]> +{ + const versionCommand = + `${ + process.env.ComSpec === "powershell.exe" ? "&" : "" + }"${gitExecutable}" version`; + const ret = await execAsync(versionCommand) + const regex = /git version (\d+\.\d+(\.\d+)*)/; + const match = regex.exec(ret.stdout); + if (match && match[1]) { + const gitVersion = match[1]; + + return [compareGe(gitVersion, MIN_GIT_VERSION), gitVersion]; + } else { + return [false, "unknown"]; + } +} + /** * Get installed version of git, and install it if it isn't already */ @@ -19,6 +41,14 @@ export async function getGit(settings: Settings): Promise { .getString(SettingsKey.gitPath) ?.replace(HOME_VAR, homedir().replaceAll("\\", "/")) || "git"; let gitPath = await which(gitExecutable, { nothrow: true }); + let gitVersion: string | undefined; + if (gitPath !== null) { + const versionRet = await checkGitVersion(gitPath); + if (!versionRet[0]) { + gitPath = null; + } + gitVersion = versionRet[1]; + } if (gitPath === null) { // if git is not in path then checkForInstallationRequirements // maye downloaded it, so reload @@ -27,12 +57,23 @@ export async function getGit(settings: Settings): Promise { .getString(SettingsKey.gitPath) ?.replace(HOME_VAR, homedir().replaceAll("\\", "/")); if (gitExecutable === null || gitExecutable === undefined) { - Logger.log("Error: Git not found."); - - await window.showErrorMessage( - "Git not found. Please install and add to PATH or " + - "set the path to the git executable in global settings." - ); + if (gitVersion !== undefined) { + Logger.log(`Error: Found Git version ${gitVersion} - ` + + `requires ${MIN_GIT_VERSION}.`); + + await window.showErrorMessage( + `Found Git version ${gitVersion}, but requires ${MIN_GIT_VERSION}. ` + + "Please install and add to PATH or " + + "set the path to the git executable in global settings." + ); + } else { + Logger.log("Error: Git not found."); + + await window.showErrorMessage( + "Git not found. Please install and add to PATH or " + + "set the path to the git executable in global settings." + ); + } return undefined; } else { diff --git a/src/utils/requirementsUtil.mts b/src/utils/requirementsUtil.mts index 02f873d..80820b0 100644 --- a/src/utils/requirementsUtil.mts +++ b/src/utils/requirementsUtil.mts @@ -5,6 +5,7 @@ import { SettingsKey, HOME_VAR } from "../settings.mjs"; import { homedir } from "os"; import { downloadGit } from "./downloadGit.mjs"; import Logger, { LoggerSource } from "../logger.mjs"; +import { checkGitVersion, MIN_GIT_VERSION } from "./gitUtil.mjs"; /** * Shows an error message that the requirements for development are not met @@ -37,6 +38,12 @@ export async function checkForGit(settings: Settings): Promise { const git: string | null = await which(gitExe, { nothrow: true }); let isGitInstalled = git !== null; + let gitVersion: string | undefined; + if (git !== null) { + const ret = await checkGitVersion(git); + isGitInstalled = ret[0]; + gitVersion = ret[1]; + } if (!isGitInstalled) { // try to install const gitDownloaded: string | undefined = await downloadGit(); @@ -45,6 +52,17 @@ export async function checkForGit(settings: Settings): Promise { // if git is downloaded set custom git path await settings.updateGlobal(SettingsKey.gitPath, gitDownloaded); isGitInstalled = true; + } else if (gitVersion !== undefined) { + Logger.error( + LoggerSource.requirements, + "Installed Git is too old and a new version could not be downloaded." + ); + void window.showErrorMessage( + "The installation of the Pico SDK requires Git " + + `version ${MIN_GIT_VERSION} or higher ` + + "to be installed and available in the PATH - " + + `you have version ${gitVersion}.` + ); } else { Logger.error( LoggerSource.requirements,