Skip to content

Commit

Permalink
Added UpdaterWindow
Browse files Browse the repository at this point in the history
  • Loading branch information
iXab3r committed Nov 9, 2021
1 parent 5a7e2bc commit 8198d56
Show file tree
Hide file tree
Showing 43 changed files with 1,341 additions and 295 deletions.
55 changes: 16 additions & 39 deletions PoeEye/PoeShared.Squirrel/Core/CheckForUpdateImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.Net;
using System.Text;
using System.Threading.Tasks;
using log4net;
using PoeShared.Scaffolding;
using PoeShared.Logging;
using PoeShared.Squirrel.Scaffolding;
Expand All @@ -28,22 +27,23 @@ public CheckForUpdateImpl(
this.urlDownloader = urlDownloader;
this.rootAppDirectory = rootAppDirectory;
}

public async Task<IPoeUpdateInfo> CheckForUpdate(
string localReleaseFile,
string updateUrlOrPath,
bool ignoreDeltaUpdates = false,
Action<int> progress = null)
Action<int> progressCallback = null)
{
progress ??= _ => { };
progressCallback ??= _ => { };

var localReleases = Array.Empty<ReleaseEntry>();
IReadOnlyCollection<ReleaseEntry> localReleases;
var stagingId = GetOrCreateStagedUserId();

var shouldInitialize = false;
bool shouldInitialize;
try
{
localReleases = Utility.LoadLocalReleases(localReleaseFile).ToArray();
shouldInitialize = false;
}
catch (Exception ex)
{
Expand All @@ -56,35 +56,36 @@ public async Task<IPoeUpdateInfo> CheckForUpdate(
{
Log.Warn("Failed to load local releases, starting from scratch", ex);
}
localReleases = ArraySegment<ReleaseEntry>.Empty;
shouldInitialize = true;
}

if (shouldInitialize)
{
Log.Debug("Initializing client app directory");
await InitializeClientAppDirectory();
}


var latestLocalRelease = localReleases.Any()
? localReleases.MaxBy(x => x.Version).First()
: default;

var isRemoteRepository = Utility.IsHttpUrl(updateUrlOrPath);

// Fetch the remote RELEASES file, whether it's a local dir or an
string releaseFile;
if (isRemoteRepository)
if (Utility.IsHttpUrl(updateUrlOrPath))
{
Log.Debug($"Loading releases from remote path {updateUrlOrPath}");
releaseFile = await LoadRemoteReleases(updateUrlOrPath, urlDownloader, latestLocalRelease);
}
else
{
Log.Debug($"Loading releases from local path {updateUrlOrPath}");
releaseFile = await LoadLocalReleases(updateUrlOrPath);
}
progress(33);
progressCallback(33);

var parsedReleases = ReleaseEntry.ParseReleaseFileAndApplyStaging(releaseFile, stagingId).ToArray();
progress(55);
progressCallback(55);

if (!parsedReleases.Any())
{
Expand All @@ -101,7 +102,7 @@ public async Task<IPoeUpdateInfo> CheckForUpdate(

var result = DetermineUpdateInfo(localReleases, parsedReleases, ignoreDeltaUpdates);

progress(100);
progressCallback(100);
return result;
}

Expand Down Expand Up @@ -203,7 +204,7 @@ private async Task InitializeClientAppDirectory()
Directory.CreateDirectory(pkgDir);
}

private IPoeUpdateInfo DetermineUpdateInfo(
public IPoeUpdateInfo DetermineUpdateInfo(
IReadOnlyCollection<IReleaseEntry> localReleases,
IReadOnlyCollection<IReleaseEntry> remoteReleases,
bool ignoreDeltaUpdates)
Expand All @@ -221,39 +222,15 @@ private IPoeUpdateInfo DetermineUpdateInfo(
IReadOnlyCollection<IReleaseEntry> remoteReleases)
{
var packageDirectory = Utility.PackageDirectoryForAppDir(rootAppDirectory);
localReleases ??= Array.Empty<ReleaseEntry>();

if (remoteReleases == null || remoteReleases.Count == 0)
{
Log.Warn("Release information couldn't be determined due to remote corrupt RELEASES file");
throw new Exception("Corrupted remote RELEASES file");
}

var latestFullRelease = Utility.FindCurrentVersion(remoteReleases);
var currentRelease = Utility.FindCurrentVersion(localReleases);

if (latestFullRelease == currentRelease)
{
Log.Info("No updates, remote and local are the same");
return PoeUpdateInfo.Create(currentRelease, new[] {latestFullRelease}, packageDirectory);
}

var latestLocal =
localReleases.Any() ? localReleases.OrderByDescending(x => x.Version).FirstOrDefault() : default;
if (latestLocal == null)
{
Log.Warn("First run or local directory is corrupt, starting from scratch");
return PoeUpdateInfo.Create(null, new[] {latestFullRelease}, packageDirectory);
}

var latestRemote = remoteReleases.OrderByDescending(x => x.Version).First();
if (latestRemote.Version < latestLocal.Version)
{
Log.Warn($"Local release {latestLocal.DumpToTextRaw()} is greater than remote release {latestRemote.DumpToTextRaw()}");
return PoeUpdateInfo.Create(currentRelease, new[] {latestFullRelease}, packageDirectory);
}

return PoeUpdateInfo.Create(currentRelease, remoteReleases, packageDirectory);
return PoeUpdateInfo.Create(currentRelease, localReleases, remoteReleases, packageDirectory);
}

private Guid? GetOrCreateStagedUserId()
Expand Down
6 changes: 5 additions & 1 deletion PoeEye/PoeShared.Squirrel/Core/IPoeUpdateInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ public interface IPoeUpdateInfo
{
public IReleaseEntry CurrentlyInstalledVersion { get; }

public IReleaseEntry FutureReleaseEntry { get; }
public IReadOnlyCollection<IReleaseEntry> LocalReleases { get; }

public IReadOnlyCollection<IReleaseEntry> RemoteReleases { get; }

public IReleaseEntry FutureReleaseEntry { get; }

public IReadOnlyCollection<IReleaseEntry> ReleasesToApply { get; }

Expand Down
51 changes: 33 additions & 18 deletions PoeEye/PoeShared.Squirrel/Core/PoeUpdateInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,54 +9,69 @@ namespace PoeShared.Squirrel.Core
{
internal sealed class PoeUpdateInfo : IPoeUpdateInfo
{
public IReleaseEntry CurrentlyInstalledVersion { get; }

public IReleaseEntry FutureReleaseEntry { get; }

public IReadOnlyCollection<IReleaseEntry> ReleasesToApply { get; }

public bool IsDelta { get; }

public string PackageDirectory { get; }

private PoeUpdateInfo(
IReleaseEntry currentlyInstalledVersion,
IReadOnlyCollection<IReleaseEntry> localReleases,
IReadOnlyCollection<IReleaseEntry> remoteReleases,
IReadOnlyCollection<IReleaseEntry> releasesToApply,
string packageDirectory)
{

CurrentlyInstalledVersion = currentlyInstalledVersion;
ReleasesToApply = releasesToApply;
ReleasesToApply = releasesToApply ?? throw new ArgumentNullException(nameof(releasesToApply));
LocalReleases = localReleases ?? throw new ArgumentNullException(nameof(localReleases));
RemoteReleases = remoteReleases ?? throw new ArgumentNullException(nameof(remoteReleases));
FutureReleaseEntry = releasesToApply.Any() ? ReleasesToApply.OrderByDescending(x => x.Version).FirstOrDefault() : CurrentlyInstalledVersion;
PackageDirectory = packageDirectory;
IsDelta = releasesToApply.Any(x => x.IsDelta);
}

public IReleaseEntry CurrentlyInstalledVersion { get; }

public IReadOnlyCollection<IReleaseEntry> LocalReleases { get; }

public IReadOnlyCollection<IReleaseEntry> RemoteReleases { get; }

public IReleaseEntry FutureReleaseEntry { get; }

public IReadOnlyCollection<IReleaseEntry> ReleasesToApply { get; }

public bool IsDelta { get; }

public string PackageDirectory { get; }

public static IPoeUpdateInfo Create(
IReleaseEntry currentVersion,
IReadOnlyCollection<IReleaseEntry> availableReleases,
IReadOnlyCollection<IReleaseEntry> localReleases,
IReadOnlyCollection<IReleaseEntry> remoteReleases,
string packageDirectory)
{
var latestFullRelease = availableReleases.Where(x => !x.IsDelta).OrderByDescending(x => x.Version).FirstOrDefault() ?? throw new Exception("There should always be at least one full release");
var latestFullRelease = remoteReleases.Where(x => !x.IsDelta).OrderByDescending(x => x.Version).FirstOrDefault() ?? throw new Exception("There should always be at least one full release");
if (currentVersion == null)
{
// local version is not installed - downloading latest full version
return new PoeUpdateInfo(null, new[] { latestFullRelease }, packageDirectory);
return new PoeUpdateInfo(null, localReleases, remoteReleases, new[] { latestFullRelease }, packageDirectory);
}

if (currentVersion.Version >= latestFullRelease.Version)
{
// installed version is greater than remote
return new PoeUpdateInfo(currentVersion, Array.Empty<IReleaseEntry>(), packageDirectory);
return new PoeUpdateInfo(currentVersion, localReleases, remoteReleases, Array.Empty<IReleaseEntry>(), packageDirectory);
}

var source = availableReleases.Where(x => x.Version > currentVersion.Version).OrderBy(v => v.Version).ToArray();
var source = remoteReleases.Where(x => x.Version > currentVersion.Version).OrderBy(v => v.Version).ToArray();
var totalDeltaReleasesSize = source.Where(x => x.IsDelta).Sum(x => x.Filesize);
if (totalDeltaReleasesSize > 0L && totalDeltaReleasesSize < latestFullRelease.Filesize)
{
// applying delta-updates
return new PoeUpdateInfo(currentVersion, source.Where(x => x.IsDelta).ToArray(), packageDirectory);
return new PoeUpdateInfo(currentVersion, localReleases, remoteReleases, source.Where(x => x.IsDelta).ToArray(), packageDirectory);
}
return new PoeUpdateInfo(currentVersion, new[] { latestFullRelease }, packageDirectory);
return new PoeUpdateInfo(currentVersion, localReleases, remoteReleases, new[] { latestFullRelease }, packageDirectory);
}

public override string ToString()
{
return $"UpdateInfo {{ isDelta:{IsDelta}, current: {CurrentlyInstalledVersion}, releasesToApply: {ReleasesToApply.Count} }}";
}
}
}
11 changes: 10 additions & 1 deletion PoeEye/PoeShared.Squirrel/Core/PoeUpdateManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
using JetBrains.Annotations;
using log4net;
using Microsoft.Win32;
using NuGet;
Expand All @@ -34,7 +35,6 @@ public PoeUpdateManager(
string applicationName = null,
string rootDirectory = null)
{
Guard.ArgumentIsTrue(!string.IsNullOrEmpty(urlOrPath), nameof(urlOrPath));
Guard.ArgumentIsTrue(!string.IsNullOrEmpty(urlOrPath), "!string.IsNullOrEmpty(urlOrPath)");
Guard.ArgumentIsTrue(!string.IsNullOrEmpty(applicationName), "!string.IsNullOrEmpty(applicationName)");

Expand All @@ -51,6 +51,15 @@ public PoeUpdateManager(

public bool IsInstalledApp => Assembly.GetExecutingAssembly().Location.StartsWith(RootAppDirectory, StringComparison.OrdinalIgnoreCase);

public async Task<IPoeUpdateInfo> PrepareUpdate(
bool ignoreDeltaUpdates,
IReadOnlyCollection<IReleaseEntry> localReleases,
IReadOnlyCollection<IReleaseEntry> remoteReleases)
{
var checkForUpdate = new CheckForUpdateImpl(urlDownloader, RootAppDirectory);
return checkForUpdate.DetermineUpdateInfo(localReleases, remoteReleases, ignoreDeltaUpdates);
}

public async Task<IPoeUpdateInfo> CheckForUpdate(bool ignoreDeltaUpdates, Action<int> progress = null)
{
using var sw = new BenchmarkTimer($"Checking for updates, ignore delta: {ignoreDeltaUpdates}", Log);
Expand Down
Loading

0 comments on commit 8198d56

Please sign in to comment.