From d19c7a3fc3a9cdb9d007a95bd7e46ad3e5a7f106 Mon Sep 17 00:00:00 2001 From: That_One_Nerd Date: Mon, 1 Apr 2024 09:41:04 -0400 Subject: [PATCH] Made a little progress with the update checker. Don't really feel like working on it right now. --- Base/Forms/GraphForm.cs | 48 +++++++++++++++++--- Base/Helpers/UpdaterHelper.cs | 83 +++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 6 deletions(-) create mode 100644 Base/Helpers/UpdaterHelper.cs diff --git a/Base/Forms/GraphForm.cs b/Base/Forms/GraphForm.cs index e71004d..c6227f5 100644 --- a/Base/Forms/GraphForm.cs +++ b/Base/Forms/GraphForm.cs @@ -1,4 +1,5 @@ using Graphing.Abstract; +using Graphing.Helpers; using Graphing.Parts; using System; using System.Collections.Generic; @@ -516,7 +517,7 @@ public partial class GraphForm : Form shifter.Show(); } - private async void RunUpdateChecker() + private static async void RunUpdateChecker() { try { @@ -537,6 +538,8 @@ public partial class GraphForm : Form Version curVersion = Version.Parse(Assembly.GetAssembly(typeof(GraphForm))!.FullName!.Split(',')[1].Trim()[8..^2]); Version newVersion = Version.Parse(latest["tag_name"]!.GetValue()); + curVersion = Version.Parse("1.0.0"); + if (newVersion > curVersion) { // Updates are required. @@ -546,12 +549,45 @@ public partial class GraphForm : Form if (button == DialogResult.No) return; - ProcessStartInfo website = new() + string? project = UpdaterHelper.GetProjectPath(); + if (project is null) { - FileName = latest["html_url"]!.GetValue(), - UseShellExecute = true - }; - Process.Start(website); + MessageBox.Show("Cannot find project root. You'll likely have to update manually.", + "Error running automatic updates.", MessageBoxButtons.OK, + MessageBoxIcon.Error); + return; + } + + if (await UpdaterHelper.UsingNugetPackage(project)) + { + Console.WriteLine($"Attempting to update via the NuGet Package Manager."); + bool status = await UpdaterHelper.UpdateProjectByNuget(latest["tag_name"]!.GetValue(), project); + if (!status) + { + MessageBox.Show("Failed to update with the NuGet Package Manager. " + + "You'll likely have to update manually.", + "Error running automatic updates.", MessageBoxButtons.OK, + MessageBoxIcon.Error); + return; + } + } + else + { + Console.WriteLine($"Attempting to update via a GitHub asset download."); + bool status = await UpdaterHelper.UpdateProjectByGitHub(latest["tag_name"]!.GetValue(), project); + if (status) + { + MessageBox.Show("Update ready. Restart the project to complete the update."); + } + else + { + MessageBox.Show("Failed to update with an automatic download. " + + "You'll likely have to update manually.", + "Error running automatic updates.", MessageBoxButtons.OK, + MessageBoxIcon.Error); + return; + } + } } else { diff --git a/Base/Helpers/UpdaterHelper.cs b/Base/Helpers/UpdaterHelper.cs new file mode 100644 index 0000000..b8c6fda --- /dev/null +++ b/Base/Helpers/UpdaterHelper.cs @@ -0,0 +1,83 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace Graphing.Helpers; + +internal static class UpdaterHelper +{ + public static async Task UsingNugetPackage(string? project = null) + { + project ??= GetProjectPath(); + + Process packageListProc = new(); + packageListProc.StartInfo.FileName = "dotnet"; + packageListProc.StartInfo.Arguments = "list package"; + packageListProc.StartInfo.WorkingDirectory = Path.GetDirectoryName(project); + + packageListProc.StartInfo.UseShellExecute = false; + packageListProc.StartInfo.RedirectStandardOutput = true; + + StringBuilder contentBuilder = new(); + packageListProc.OutputDataReceived += (o, e) => contentBuilder.AppendLine(e.Data); + + packageListProc.Start(); + packageListProc.BeginOutputReadLine(); + await packageListProc.WaitForExitAsync(); + + string content = contentBuilder.ToString(); + return content.Contains($"ThatOneNerd.Graphing"); + } + public static async Task UpdateProjectByNuget(string version, string? project = null) + { + project ??= GetProjectPath(); + + Process updateProc = new(); + updateProc.StartInfo.FileName = "dotnet"; + updateProc.StartInfo.Arguments = $"add package ThatOneNerd.Graphing --version {version}"; + updateProc.StartInfo.WorkingDirectory = Path.GetDirectoryName(project); + + updateProc.StartInfo.UseShellExecute = false; + updateProc.StartInfo.RedirectStandardError = true; + + StringBuilder errorBuilder = new(); + updateProc.ErrorDataReceived += (o, e) => errorBuilder.AppendLine(e.Data); + + updateProc.Start(); + updateProc.BeginErrorReadLine(); + await updateProc.WaitForExitAsync(); + + // Could be shrunk but it makes it less clear. If there's any data written to + // the error stream, it did not succeed. + if (errorBuilder.Length > 0) return false; // Error. + else return true; // Success. + } + public static async Task UpdateProjectByGitHub(string version, string? project = null) + { + // TODO + return false; + } + + public static string? GetProjectPath() + { + Assembly? entryAsm = Assembly.GetEntryAssembly(); + if (entryAsm is null) return null; + + string? directory = Path.GetDirectoryName(entryAsm.Location); + while (directory is not null) + { + string[] files = Directory.GetFiles(directory); + string? project = files.FirstOrDefault(x => x.EndsWith(".csproj") || + x.EndsWith(".sln")); + if (project is not null) return project; + + directory = Path.GetDirectoryName(directory); + } + + return null; + } +}