Misc path clean-up

This commit is contained in:
Caelan Sayler
2022-05-25 16:06:30 +01:00
parent 9744ceec65
commit fb90550c1f
5 changed files with 49 additions and 61 deletions

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.Versioning;
using NuGet.Versioning;
using Squirrel.NuGet;
using Squirrel.SimpleSplat;
@@ -247,6 +248,7 @@ namespace Squirrel
/// An implementation for Windows which uses the Squirrel defaults and installs to
/// local app data.
/// </summary>
[SupportedOSPlatform("windows")]
public class AppDescWindows : AppDesc
{
/// <inheritdoc />
@@ -270,9 +272,8 @@ namespace Squirrel
/// <inheritdoc />
public override string AppTempDir => CreateSubDirIfDoesNotExist(PackagesDir, "SquirrelClowdTemp");
/// <inheritdoc />
public override string VersionStagingDir => CreateSubDirIfDoesNotExist(RootAppDir, "staging");
public override string VersionStagingDir => CreateSubDirIfDoesNotExist(PackagesDir, "staging");
/// <inheritdoc />
public override string CurrentVersionDir => CreateSubDirIfDoesNotExist(RootAppDir, "current");
@@ -295,7 +296,7 @@ namespace Squirrel
{
if (!SquirrelRuntimeInfo.IsWindows)
throw new NotSupportedException("Cannot instantiate AppDescWindows on a non-Windows system.");
if (!Directory.Exists(appDir) && createIfNotExist)
Directory.CreateDirectory(appDir);
@@ -303,26 +304,28 @@ namespace Squirrel
RootAppDir = appDir;
var updateExe = Path.Combine(appDir, "Update.exe");
var ver = GetLatestVersion();
UpdateExePath = updateExe;
IsUpdateExe = Utility.FullPathEquals(updateExe, SquirrelRuntimeInfo.EntryExePath);
if (File.Exists(updateExe) && ver != null) {
UpdateExePath = updateExe;
CurrentlyInstalledVersion = ver.Version;
}
}
internal AppDescWindows(string ourPath)
internal AppDescWindows(string ourExePath)
{
if (!SquirrelRuntimeInfo.IsWindows)
throw new NotSupportedException("Cannot instantiate AppDescWindows on a non-Windows system.");
var myDir = Path.GetDirectoryName(ourPath);
ourExePath = Path.GetFullPath(ourExePath);
var myDir = Path.GetDirectoryName(ourExePath);
// Am I update.exe at the application root?
if (ourPath != null &&
Path.GetFileName(ourPath).Equals("update.exe", StringComparison.InvariantCultureIgnoreCase) &&
ourPath.IndexOf("app-", StringComparison.InvariantCultureIgnoreCase) == -1 &&
ourPath.IndexOf("SquirrelClowdTemp", StringComparison.InvariantCultureIgnoreCase) == -1) {
UpdateExePath = ourPath;
if (ourExePath != null &&
Path.GetFileName(ourExePath).Equals("update.exe", StringComparison.InvariantCultureIgnoreCase) &&
ourExePath.IndexOf("app-", StringComparison.InvariantCultureIgnoreCase) == -1 &&
ourExePath.IndexOf("SquirrelClowdTemp", StringComparison.InvariantCultureIgnoreCase) == -1) {
UpdateExePath = ourExePath;
RootAppDir = myDir;
var ver = GetLatestVersion();
if (ver != null) {
@@ -360,6 +363,7 @@ namespace Squirrel
/// The default for OSX. All application files will remain in the '.app'.
/// All additional files (log, etc) will be placed in a temporary directory.
/// </summary>
[SupportedOSPlatform("osx")]
public class AppDescOsx : AppDesc
{
/// <inheritdoc />
@@ -403,7 +407,7 @@ namespace Squirrel
var ix = ourPath.IndexOf(".app/", StringComparison.InvariantCultureIgnoreCase);
if (ix < 0) return;
var appPath = ourPath.Substring(0, ix + 5);
var appPath = ourPath.Substring(0, ix + 4);
var contentsDir = Path.Combine(appPath, "Contents");
var updateExe = Path.Combine(contentsDir, "UpdateMac");
var info = GetVersionInfoFromDirectory(contentsDir);

View File

@@ -234,7 +234,7 @@ namespace Squirrel
.Where(x => x != null)
.ToArray();
return ret.Any(x => x == null) ? null : ret;
return ret.Any(x => x == null) ? new ReleaseEntry[0] : ret;
}
/// <summary>

View File

@@ -23,14 +23,13 @@ namespace Squirrel
if (_source == null)
throw new InvalidOperationException("Cannot check for updates if no update source / url was provided in the construction of UpdateManager.");
progress = progress ?? (_ => { });
var localReleases = Enumerable.Empty<ReleaseEntry>();
var stagingId = intention == UpdaterIntention.Install ? null : getOrCreateStagedUserId();
progress ??= (_ => { });
ReleaseEntry[] localReleases = new ReleaseEntry[0];
bool shouldInitialize = intention == UpdaterIntention.Install;
if (intention != UpdaterIntention.Install) {
try {
localReleases = Utility.LoadLocalReleases(_config.ReleasesFilePath);
localReleases = Utility.LoadLocalReleases(_config.ReleasesFilePath).ToArray();
} catch (Exception ex) {
// Something has gone pear-shaped, let's start from scratch
this.Log().WarnException("Failed to load local releases, starting from scratch", ex);
@@ -39,10 +38,12 @@ namespace Squirrel
}
if (shouldInitialize) initializeClientAppDirectory();
var stagingId = intention == UpdaterIntention.Install ? null : getOrCreateStagedUserId();
var latestLocalRelease = localReleases != null && localReleases.Count() > 0
? localReleases.MaxBy(v => v.Version).First() :
null;
var latestLocalRelease = localReleases.Count() > 0
? localReleases.MaxBy(v => v.Version).First()
: null;
progress(33);

View File

@@ -32,7 +32,7 @@ namespace Squirrel
public IUpdateSource Source => _source;
private readonly IUpdateSource _source;
private readonly AppDesc _config;
private readonly AppDesc _config = AppDesc.GetCurrentPlatform();
private readonly object _lockobj = new object();
private IDisposable _updateLock;
private bool _disposed;
@@ -44,7 +44,10 @@ namespace Squirrel
/// <param name="urlOrPath">
/// The URL or local directory that contains application update files (.nupkg and RELEASES)
/// </param>
public UpdateManager(string urlOrPath) : this(CreateSource(urlOrPath))
/// <param name="downloader">
/// A custom downloader to use when retrieving files from an HTTP source.
/// </param>
public UpdateManager(string urlOrPath, IFileDownloader downloader = null) : this(CreateSource(urlOrPath, downloader))
{
}
@@ -57,43 +60,16 @@ namespace Squirrel
/// a local directory (<see cref="SimpleFileSource"/>), a GitHub repository (<see cref="GithubSource"/>),
/// or a custom location.
/// </param>
public UpdateManager(IUpdateSource source) : this(source, null)
{
}
/// <summary>
/// Create a new instance of <see cref="UpdateManager"/> to check for and install updates.
/// Do not forget to dispose this class!
/// </summary>
/// <param name="source">
/// The source of your update packages. This can be a web server (<see cref="SimpleWebSource"/>),
/// a local directory (<see cref="SimpleFileSource"/>), a GitHub repository (<see cref="GithubSource"/>),
/// or a custom location.
/// </param>
/// <param name="config">
/// For configuring advanced / custom deployment scenarios. Should not be used unless
/// you know what you are doing.
/// </param>
public UpdateManager(IUpdateSource source, AppDesc config)
public UpdateManager(IUpdateSource source)
{
_source = source;
_config = config ?? AppDesc.GetCurrentPlatform();
}
internal UpdateManager(string urlOrPath, string appId)
: this(CreateSource(urlOrPath), new AppDescWindows(
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), appId), appId))
{
}
internal UpdateManager(string urlOrPath, string appId, string localAppData)
: this(CreateSource(urlOrPath), new AppDescWindows(Path.Combine(localAppData, appId), appId))
{
}
internal UpdateManager(string urlOrPath, string appId, string localAppData, IFileDownloader downloader)
: this(CreateSource(urlOrPath, downloader), new AppDescWindows(Path.Combine(localAppData, appId), appId))
[SupportedOSPlatform("windows")]
internal UpdateManager(string urlOrPath, string appId, string localAppData = null, IFileDownloader downloader = null)
{
_source = CreateSource(urlOrPath, downloader);
_config = new AppDescWindows(Path.Combine(localAppData ?? Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), appId), appId);
}
internal UpdateManager() { }
@@ -134,30 +110,36 @@ namespace Squirrel
var localVersions = _config.GetVersions();
var currentVersion = CurrentlyInstalledVersion();
updateInfo = await this.ErrorIfThrows(() => CheckForUpdate(ignoreDeltaUpdates, x => progress(x / 3)),
// 0 -> 10%
updateInfo = await this.ErrorIfThrows(() => CheckForUpdate(ignoreDeltaUpdates, x => progress(CalculateProgress(x, 0, 10))),
"Failed to check for updates").ConfigureAwait(false);
if (updateInfo == null || updateInfo.FutureReleaseEntry == null) {
this.Log().Info("No update available.");
progress(100);
return null;
}
if (currentVersion >= updateInfo.FutureReleaseEntry.Version) {
this.Log().Info($"Current version {currentVersion} is up to date with remote.");
progress(100);
return null;
}
if (localVersions.Any(v => v.Version == updateInfo.FutureReleaseEntry.Version)) {
this.Log().Info("Update available, it is already downloaded.");
progress(100);
return updateInfo.FutureReleaseEntry;
}
// 10 -> 50%
await this.ErrorIfThrows(() =>
DownloadReleases(updateInfo.ReleasesToApply, x => progress(x / 3 + 33)),
DownloadReleases(updateInfo.ReleasesToApply, x => progress(CalculateProgress(x, 10, 50))),
"Failed to download updates").ConfigureAwait(false);
// 50 -> 100%
await this.ErrorIfThrows(() =>
ApplyReleases(updateInfo, x => progress(x / 3 + 66)),
ApplyReleases(updateInfo, x => progress(CalculateProgress(x, 50, 100))),
"Failed to apply updates").ConfigureAwait(false);
if (SquirrelRuntimeInfo.IsWindows) {
@@ -165,14 +147,15 @@ namespace Squirrel
}
} catch {
if (ignoreDeltaUpdates == false) {
this.Log().Warn("Failed to apply delta updates. Retrying with full package.");
ignoreDeltaUpdates = true;
goto retry;
}
throw;
}
return updateInfo.ReleasesToApply.Any() ? updateInfo.ReleasesToApply.MaxBy(x => x.Version).Last() : default(ReleaseEntry);
progress(100);
return updateInfo.ReleasesToApply.Any() ? updateInfo.ReleasesToApply.MaxBy(x => x.Version).Last() : default;
}
/// <inheritdoc/>

View File

@@ -17,7 +17,7 @@ namespace Squirrel.Tests
{
class ApplyReleasesImpl : UpdateManager
{
public ApplyReleasesImpl(string rootDir, string appId) : base(null, new AppDescWindows(rootDir, appId))
public ApplyReleasesImpl(string rootDir, string appId) : base(rootDir, appId)
{
}