From 992bd215704bbbc73a46bc40ce6b1cd83e3634e0 Mon Sep 17 00:00:00 2001 From: Ben Wallis Date: Fri, 28 Sep 2018 20:24:09 +0100 Subject: [PATCH] Fixed UpdateService which was erroneously using the local update manager instead of the GitHub update manager for several parts of the update process --- Filtration/Enums/UpdateSource.cs | 14 ++++ Filtration/Filtration.csproj | 1 + Filtration/Services/Bootstrapper.cs | 2 +- Filtration/Services/UpdateService.cs | 102 +++++++++++++++-------- Filtration/ViewModels/UpdateViewModel.cs | 52 ++++++------ 5 files changed, 108 insertions(+), 63 deletions(-) create mode 100644 Filtration/Enums/UpdateSource.cs diff --git a/Filtration/Enums/UpdateSource.cs b/Filtration/Enums/UpdateSource.cs new file mode 100644 index 0000000..73c63d4 --- /dev/null +++ b/Filtration/Enums/UpdateSource.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Filtration.Enums +{ + internal enum UpdateSource + { + GitHub, + Local + } +} diff --git a/Filtration/Filtration.csproj b/Filtration/Filtration.csproj index ad6f4ae..c23e09c 100644 --- a/Filtration/Filtration.csproj +++ b/Filtration/Filtration.csproj @@ -203,6 +203,7 @@ + diff --git a/Filtration/Services/Bootstrapper.cs b/Filtration/Services/Bootstrapper.cs index b79b58f..fbdf410 100644 --- a/Filtration/Services/Bootstrapper.cs +++ b/Filtration/Services/Bootstrapper.cs @@ -39,7 +39,7 @@ namespace Filtration.Services _mainWindow.Show(); - await _updateService.CheckForUpdates(); + await _updateService.CheckForUpdatesAsync(); } private void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e) diff --git a/Filtration/Services/UpdateService.cs b/Filtration/Services/UpdateService.cs index b41e092..120f628 100644 --- a/Filtration/Services/UpdateService.cs +++ b/Filtration/Services/UpdateService.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; +using Filtration.Enums; using Filtration.Properties; using NLog; using Squirrel; @@ -52,7 +53,7 @@ namespace Filtration.Services string LatestReleaseVersion { get; } - Task CheckForUpdates(); + Task CheckForUpdatesAsync(); Task DownloadUpdatesAsync(); @@ -63,13 +64,16 @@ namespace Filtration.Services internal class UpdateService : IUpdateService { - private readonly ISettingsService _settingsService; private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private const string _localUpdatePath = @"C:\Repos\Filtration\Releases"; + + private readonly ISettingsService _settingsService; + private readonly UpdateSource _updateSource = UpdateSource.GitHub; + private ReleaseEntry _latestRelease; private UpdateInfo _updates; - + private bool _downloadPrereleaseUpdates; private UpdateStatus _updateStatus; public UpdateService(ISettingsService settingsService) @@ -96,35 +100,42 @@ namespace Filtration.Services public string LatestReleaseVersion { get; private set; } - public async Task CheckForUpdates() + public async Task CheckForUpdatesAsync() { if (UpdateStatus != UpdateStatus.NoUpdateAvailable) { throw new InvalidOperationException(); } - Logger.Debug("Checking for update..."); UpdateStatus = UpdateStatus.CheckingForUpdate; try { - bool downloadPrereleaseUpdates; - downloadPrereleaseUpdates = Settings.Default.DownloadPrereleaseUpdates; + _downloadPrereleaseUpdates = Settings.Default.DownloadPrereleaseUpdates; #if DEBUG - downloadPrereleaseUpdates = true; + _downloadPrereleaseUpdates = true; #endif - using (var mgr = await UpdateManager.GitHubUpdateManager("https://github.com/ben-wallis/Filtration", prerelease: downloadPrereleaseUpdates)) + + async Task CheckForUpdatesAsync(IUpdateManager updateManager) { - _updates = await mgr.CheckForUpdate(progress: progress => UpdateProgressChanged?.Invoke(this, new UpdateProgressChangedEventArgs(progress))); + _updates = await updateManager.CheckForUpdate(progress: progress => UpdateProgressChanged?.Invoke(this, new UpdateProgressChangedEventArgs(progress))); } - // Local file update source for testing - //using (var mgr = new UpdateManager(_localUpdatePath)) - //{ - - // _updates = await mgr.CheckForUpdate(progress: progress => UpdateProgressChanged?.Invoke(this, new UpdateProgressChangedEventArgs(progress))); - //} + if (_updateSource == UpdateSource.GitHub) + { + using (var updateManager = await UpdateManager.GitHubUpdateManager("https://github.com/ben-wallis/Filtration", prerelease: _downloadPrereleaseUpdates)) + { + await CheckForUpdatesAsync(updateManager); + } + } + else + { + using (var updateManager = new UpdateManager(_localUpdatePath)) + { + await CheckForUpdatesAsync(updateManager); + } + } } catch (Exception e) { @@ -133,26 +144,13 @@ namespace Filtration.Services return; } - if (_updates.ReleasesToApply.Any()) { _latestRelease = _updates.ReleasesToApply.OrderBy(x => x.Version).Last(); LatestReleaseVersion = _latestRelease.Version.ToString(); - Logger.Debug($"Update found ({LatestReleaseVersion}), fetching release notes..."); - - try - { - var releaseNotes = _latestRelease.GetReleaseNotes(_localUpdatePath); - LatestReleaseNotes = ProcessReleaseNotes(releaseNotes); - } - catch (Exception e) - { - Logger.Error(e); - UpdateStatus = UpdateStatus.Error; - return; - } - + Logger.Debug($"Update found ({LatestReleaseVersion})"); + UpdateStatus = UpdateStatus.UpdateAvailable; } else @@ -162,7 +160,7 @@ namespace Filtration.Services } } - private string ProcessReleaseNotes(string rawReleaseNotes) + private static string ProcessReleaseNotes(string rawReleaseNotes) { var regex = new Regex(@"", RegexOptions.Singleline); var matches = regex.Match(rawReleaseNotes); @@ -184,11 +182,31 @@ namespace Filtration.Services UpdateStatus = UpdateStatus.Downloading; + async Task DownloadUpdatesAsync(IUpdateManager updateManager) + { + Logger.Debug("Downloading update..."); + await updateManager.DownloadReleases(_updates.ReleasesToApply, OnProgressChanged); + + Logger.Debug("Fetching release notes..."); + var releaseNotes = _updates.FetchReleaseNotes(); + LatestReleaseNotes = ProcessReleaseNotes(releaseNotes[_latestRelease]); + } + try { - using (var updateManager = new UpdateManager(_localUpdatePath)) + if (_updateSource == UpdateSource.GitHub) { - await updateManager.DownloadReleases(_updates.ReleasesToApply, OnProgressChanged); + using (var updateManager = await UpdateManager.GitHubUpdateManager("https://github.com/ben-wallis/Filtration", prerelease: _downloadPrereleaseUpdates)) + { + await DownloadUpdatesAsync(updateManager); + } + } + else + { + using (var updateManager = new UpdateManager(_localUpdatePath)) + { + await DownloadUpdatesAsync(updateManager); + } } } catch (Exception e) @@ -215,11 +233,22 @@ namespace Filtration.Services // wipes out user settings due to the application directory changing with each update _settingsService.BackupSettings(); + Logger.Debug("Applying update..."); try { - using (var updateManager = new UpdateManager(_localUpdatePath)) + if (_updateSource == UpdateSource.GitHub) { - await updateManager.ApplyReleases(_updates, OnProgressChanged); + using (var mgr = await UpdateManager.GitHubUpdateManager("https://github.com/ben-wallis/Filtration", prerelease: _downloadPrereleaseUpdates)) + { + await mgr.ApplyReleases(_updates, OnProgressChanged); + } + } + else + { + using (var updateManager = new UpdateManager(_localUpdatePath)) + { + await updateManager.ApplyReleases(_updates, OnProgressChanged); + } } } catch (Exception e) @@ -229,6 +258,7 @@ namespace Filtration.Services return; } + Logger.Debug("Update complete"); UpdateStatus = UpdateStatus.UpdateComplete; } diff --git a/Filtration/ViewModels/UpdateViewModel.cs b/Filtration/ViewModels/UpdateViewModel.cs index 6ae0edf..713908c 100644 --- a/Filtration/ViewModels/UpdateViewModel.cs +++ b/Filtration/ViewModels/UpdateViewModel.cs @@ -50,7 +50,7 @@ namespace Filtration.ViewModels updateService.UpdateProgressChanged += UpdateServiceOnUpdateProgressChanged; updateService.UpdateStatusChanged += UpdateServiceOnUpdateStatusChanged; - + HideUpdateWindowCommand = new RelayCommand(OnHideUpdateWindowCommand, () => UpdateStatus == UpdateStatus.UpdateAvailable || UpdateStatus == UpdateStatus.Error); NextStepCommand = new RelayCommand(async () => await OnNextStepCommandAsync(), () => NextStepCommandEnabled); @@ -100,39 +100,39 @@ namespace Filtration.ViewModels } private bool NextStepCommandEnabled => UpdateStatus == UpdateStatus.UpdateAvailable || UpdateStatus == UpdateStatus.ReadyToApplyUpdate || UpdateStatus == UpdateStatus.UpdateComplete; - + private async Task OnNextStepCommandAsync() { switch (UpdateStatus) { case UpdateStatus.UpdateAvailable: - { - await _updateService.DownloadUpdatesAsync(); - break; - } + { + await _updateService.DownloadUpdatesAsync(); + break; + } case UpdateStatus.ReadyToApplyUpdate: - { - if (!_updateTabShown) { - // When the update has downloaded and is ready to apply, clicking the button - // closes the update popup and shows the update tab. - _avalonDockWorkspaceViewModel.AddDocument(this); - Visible = false; - _updateTabShown = true; - NextStepButtonText = "Update"; - } - else - { - await _updateService.ApplyUpdatesAsync(); - } + if (!_updateTabShown) + { + // When the update has downloaded and is ready to apply, clicking the button + // closes the update popup and shows the update tab. + _avalonDockWorkspaceViewModel.AddDocument(this); + Visible = false; + _updateTabShown = true; + NextStepButtonText = "Update"; + } + else + { + await _updateService.ApplyUpdatesAsync(); + } - break; - } + break; + } case UpdateStatus.UpdateComplete: - { - _updateService.RestartAfterUpdate(); - break; - } + { + _updateService.RestartAfterUpdate(); + break; + } } } @@ -144,7 +144,6 @@ namespace Filtration.ViewModels { Visible = true; NextStepButtonText = "Download"; - RaisePropertyChanged(nameof(ReleaseNotes)); RaisePropertyChanged(nameof(Version)); break; } @@ -156,6 +155,7 @@ namespace Filtration.ViewModels } case UpdateStatus.ReadyToApplyUpdate: { + RaisePropertyChanged(nameof(ReleaseNotes)); NextStepButtonText = "Update Ready"; break; }