From 6bd3d62556ca319cb7e10bbd8a389bba7c7d7c10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sim=C3=B5es?= Date: Thu, 11 May 2023 18:08:54 +0100 Subject: [PATCH] Add check to current nanoclr version before attempting update --- source/TestAdapter/NanoCLRHelper.cs | 144 ++++++++++++++---- .../nanoFramework.TestAdapter.csproj | 9 +- source/TestAdapter/packages.lock.json | 13 +- 3 files changed, 131 insertions(+), 35 deletions(-) diff --git a/source/TestAdapter/NanoCLRHelper.cs b/source/TestAdapter/NanoCLRHelper.cs index 3ecdd54..1d05c8c 100644 --- a/source/TestAdapter/NanoCLRHelper.cs +++ b/source/TestAdapter/NanoCLRHelper.cs @@ -6,9 +6,12 @@ using CliWrap; using CliWrap.Buffered; using nanoFramework.TestPlatform.TestAdapter; +using Newtonsoft.Json; using System; using System.Text.RegularExpressions; using System.Threading; +using System.ComponentModel; +using System.Net; namespace nanoFramework.TestAdapter { @@ -25,50 +28,134 @@ public static bool InstallNanoClr(LogMessenger logger) "Install/upate nanoclr tool", Settings.LoggingLevel.Verbose); - var cmd = Cli.Wrap("dotnet") - .WithArguments("tool update -g nanoclr") + // get installed tool version (if installed) + var cmd = Cli.Wrap("nanoclr") + .WithArguments("--help") .WithValidation(CommandResultValidation.None); - // setup cancellation token with a timeout of 1 minute - using (var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1))) + bool performInstallUpdate = false; + + // setup cancellation token with a timeout of 10 seconds + using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); + + try { var cliResult = cmd.ExecuteBufferedAsync(cts.Token).Task.Result; if (cliResult.ExitCode == 0) { - // this will be either (on update): - // Tool 'nanoclr' was successfully updated from version '1.0.205' to version '1.0.208'. - // or (update becoming reinstall with same version, if there is no new version): - // Tool 'nanoclr' was reinstalled with the latest stable version (version '1.0.208'). - var regexResult = Regex.Match(cliResult.StandardOutput, @"((?>version ')(?'version'\d+\.\d+\.\d+)(?>'))"); + var regexResult = Regex.Match(cliResult.StandardOutput, @"(?'version'\d+\.\d+\.\d+)", RegexOptions.RightToLeft); if (regexResult.Success) { - logger.LogMessage($"Install/update successful. Running v{regexResult.Groups["version"].Value}", - Settings.LoggingLevel.Verbose); + logger.LogMessage($"Running nanoclr v{regexResult.Groups["version"].Value}", Settings.LoggingLevel.Verbose); + + // compose version + Version installedVersion = new Version(regexResult.Groups[1].Value); NanoClrIsInstalled = true; + string responseContent = null; + + // check latest version + using (System.Net.WebClient client = new WebClient()) + { + try + { + // Set the user agent string to identify the client. + client.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"); + + // Set any additional headers, if needed. + client.Headers.Add("Content-Type", "application/json"); + + // Set the URL to request. + string url = "https://api.nuget.org/v3-flatcontainer/nanoclr/index.json"; + + // Make the HTTP request and retrieve the response. + responseContent = client.DownloadString(url); + } + catch (WebException e) + { + // Handle any exceptions that occurred during the request. + Console.WriteLine(e.Message); + } + } + + var package = JsonConvert.DeserializeObject(responseContent); + Version latestPackageVersion = new Version(package.Versions[package.Versions.Length - 1]); + + // check if we are running the latest one + if (latestPackageVersion > installedVersion) + { + // need to update + performInstallUpdate = true; + } + else + { + logger.LogMessage($"No need to update. Running v{latestPackageVersion}", + Settings.LoggingLevel.Verbose); + } } else { - logger.LogPanicMessage($"*** Failed to install/update nanoclr. {cliResult.StandardOutput}."); - - NanoClrIsInstalled = false; + // something wrong with the output, can't proceed + logger.LogPanicMessage("Failed to parse current nanoCLR CLI version!"); } } - else + } + catch (Win32Exception) + { + // nanoclr doesn't seem to be installed + performInstallUpdate = true; + NanoClrIsInstalled = false; + } + + if (performInstallUpdate) + { + cmd = Cli.Wrap("dotnet") + .WithArguments("tool update -g nanoclr") + .WithValidation(CommandResultValidation.None); + + // setup cancellation token with a timeout of 1 minute + using (var cts1 = new CancellationTokenSource(TimeSpan.FromMinutes(1))) { - logger.LogPanicMessage( - $"Failed to install/update nanoclr. Exit code {cliResult.ExitCode}." - + Environment.NewLine - + Environment.NewLine - + "****************************************" - + Environment.NewLine - + "*** WON'T BE ABLE TO RUN UNITS TESTS ***" - + Environment.NewLine - + "****************************************"); - - NanoClrIsInstalled = false; + var cliResult = cmd.ExecuteBufferedAsync(cts1.Token).Task.Result; + + if (cliResult.ExitCode == 0) + { + // this will be either (on update): + // Tool 'nanoclr' was successfully updated from version '1.0.205' to version '1.0.208'. + // or (update becoming reinstall with same version, if there is no new version): + // Tool 'nanoclr' was reinstalled with the latest stable version (version '1.0.208'). + var regexResult = Regex.Match(cliResult.StandardOutput, @"((?>version ')(?'version'\d+\.\d+\.\d+)(?>'))"); + + if (regexResult.Success) + { + logger.LogMessage($"Install/update successful. Running v{regexResult.Groups["version"].Value}", + Settings.LoggingLevel.Verbose); + + NanoClrIsInstalled = true; + } + else + { + logger.LogPanicMessage($"*** Failed to install/update nanoclr. {cliResult.StandardOutput}."); + + NanoClrIsInstalled = false; + } + } + else + { + logger.LogPanicMessage( + $"Failed to install/update nanoclr. Exit code {cliResult.ExitCode}." + + Environment.NewLine + + Environment.NewLine + + "****************************************" + + Environment.NewLine + + "*** WON'T BE ABLE TO RUN UNITS TESTS ***" + + Environment.NewLine + + "****************************************"); + + NanoClrIsInstalled = false; + } } } @@ -126,5 +213,10 @@ public static void UpdateNanoCLRInstance( } } } + internal class NuGetPackage + { + public string[] Versions { get; set; } + } + } } diff --git a/source/TestAdapter/nanoFramework.TestAdapter.csproj b/source/TestAdapter/nanoFramework.TestAdapter.csproj index 4025192..9fe9fb3 100644 --- a/source/TestAdapter/nanoFramework.TestAdapter.csproj +++ b/source/TestAdapter/nanoFramework.TestAdapter.csproj @@ -5,8 +5,10 @@ true key.snk true - true true + true + true + 8.0 true @@ -19,12 +21,9 @@ 3.6.128 all - + - - - diff --git a/source/TestAdapter/packages.lock.json b/source/TestAdapter/packages.lock.json index 6e5fef2..c417224 100644 --- a/source/TestAdapter/packages.lock.json +++ b/source/TestAdapter/packages.lock.json @@ -54,11 +54,11 @@ "resolved": "3.6.128", "contentHash": "zeA+Ho3XlPgt6P9MRALlkEvfOOzDQdNseV0xia/nSfC1lSrl0+gizlWyixaHvSYUw2ru7pBIKnK451bYOjPRjA==" }, - "System.Runtime.CompilerServices.Unsafe": { + "Newtonsoft.Json": { "type": "Direct", - "requested": "[6.0.0, )", - "resolved": "6.0.0", - "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + "requested": "[13.0.3, )", + "resolved": "13.0.3", + "contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==" }, "Fody": { "type": "Transitive", @@ -177,6 +177,11 @@ "System.Collections.Immutable": "5.0.0" } }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, "System.Security.AccessControl": { "type": "Transitive", "resolved": "5.0.0",