rework prechecks to return a precheckresult
This commit is contained in:
parent
af11a12cac
commit
d269d674ad
@ -32,7 +32,7 @@ public class InstallController
|
|||||||
{
|
{
|
||||||
var result = await check.RunCheck();
|
var result = await check.RunCheck();
|
||||||
|
|
||||||
Log.Information($"PreCheck: {check.Name} ({(check.IsRequired ? "Required" : "Optional")}) -> {(result.Succeeded ? "Passed" : "Failed")}");
|
Log.Information($"PreCheck: {check.Name} ({(check.IsRequired ? "Required" : "Optional")}) -> {(result.Succeeded ? "Passed" : "Failed")}\nDetail: {check.PreCheckDetails.ReplaceLineEndings(" ")}");
|
||||||
|
|
||||||
if (check.IsRequired)
|
if (check.IsRequired)
|
||||||
{
|
{
|
||||||
|
@ -1,29 +1,38 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Serilog;
|
|
||||||
|
|
||||||
namespace SPTInstaller.Helpers;
|
namespace SPTInstaller.Helpers;
|
||||||
|
|
||||||
public static class DirectorySizeHelper
|
public static class DirectorySizeHelper
|
||||||
{
|
{
|
||||||
public static bool CheckAvailableSize(string eftSourceDirPath, string installTargetDirPath)
|
// SizeSuffix implementation found here:
|
||||||
|
// https://stackoverflow.com/a/14488941
|
||||||
|
static readonly string[] SizeSuffixes =
|
||||||
|
{ "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
|
||||||
|
public static string SizeSuffix(Int64 value, int decimalPlaces = 1)
|
||||||
{
|
{
|
||||||
try
|
if (decimalPlaces < 0) { throw new ArgumentOutOfRangeException("decimalPlaces"); }
|
||||||
|
if (value < 0) { return "-" + SizeSuffix(-value, decimalPlaces); }
|
||||||
|
if (value == 0) { return string.Format("{0:n" + decimalPlaces + "} bytes", 0); }
|
||||||
|
|
||||||
|
// mag is 0 for bytes, 1 for KB, 2, for MB, etc.
|
||||||
|
int mag = (int)Math.Log(value, 1024);
|
||||||
|
|
||||||
|
// 1L << (mag * 10) == 2 ^ (10 * mag)
|
||||||
|
// [i.e. the number of bytes in the unit corresponding to mag]
|
||||||
|
decimal adjustedSize = (decimal)value / (1L << (mag * 10));
|
||||||
|
|
||||||
|
// make adjustment when the value is large enough that
|
||||||
|
// it would round up to 1000 or more
|
||||||
|
if (Math.Round(adjustedSize, decimalPlaces) >= 1000)
|
||||||
{
|
{
|
||||||
var eftSourceDirectoryInfo = new DirectoryInfo(eftSourceDirPath);
|
mag += 1;
|
||||||
var installTargetDirectoryInfo = new DirectoryInfo(installTargetDirPath);
|
adjustedSize /= 1024;
|
||||||
|
|
||||||
var eftSourceDirSize = GetSizeOfDirectory(eftSourceDirectoryInfo);
|
|
||||||
var availableSize = DriveInfo.GetDrives().FirstOrDefault(d => d.Name.ToLower() == installTargetDirectoryInfo.Root.Name.ToLower())?.AvailableFreeSpace ?? 0;
|
|
||||||
|
|
||||||
return eftSourceDirSize < availableSize;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Error(ex, "Error while checking available size");
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static long GetSizeOfDirectory(DirectoryInfo sourceDir) => sourceDir.EnumerateFiles("*", SearchOption.AllDirectories).Sum(fi => fi.Length);
|
return string.Format("{0:n" + decimalPlaces + "} {1}",
|
||||||
|
adjustedSize,
|
||||||
|
SizeSuffixes[mag]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long GetSizeOfDirectory(DirectoryInfo sourceDir) => sourceDir.EnumerateFiles("*", SearchOption.AllDirectories).Sum(fi => fi.Length);
|
||||||
}
|
}
|
@ -12,5 +12,7 @@ public interface IPreCheck
|
|||||||
|
|
||||||
public bool Passed { get; }
|
public bool Passed { get; }
|
||||||
|
|
||||||
|
public string PreCheckDetails { get; }
|
||||||
|
|
||||||
public Task<IResult> RunCheck();
|
public Task<IResult> RunCheck();
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using SPTInstaller.Interfaces;
|
using SPTInstaller.Interfaces;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Input;
|
||||||
|
|
||||||
namespace SPTInstaller.Models;
|
namespace SPTInstaller.Models;
|
||||||
|
|
||||||
@ -48,6 +49,34 @@ public abstract class PreCheckBase : ReactiveObject, IPreCheck
|
|||||||
set => this.RaiseAndSetIfChanged(ref _isRunning, value);
|
set => this.RaiseAndSetIfChanged(ref _isRunning, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string _preCheckDetails;
|
||||||
|
public string PreCheckDetails
|
||||||
|
{
|
||||||
|
get => _preCheckDetails;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _preCheckDetails, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool _actionButtonIsVisible;
|
||||||
|
public bool ActionButtonIsVisible
|
||||||
|
{
|
||||||
|
get => _actionButtonIsVisible;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _actionButtonIsVisible, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string _actionButtonText;
|
||||||
|
public string ActionButtonText
|
||||||
|
{
|
||||||
|
get => _actionButtonText;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _actionButtonText, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ICommand _actionButtonCommand;
|
||||||
|
public ICommand ActionButtonCommand
|
||||||
|
{
|
||||||
|
get => _actionButtonCommand;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _actionButtonCommand, value);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Base class for pre-checks to run before installation
|
/// Base class for pre-checks to run before installation
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -63,12 +92,23 @@ public abstract class PreCheckBase : ReactiveObject, IPreCheck
|
|||||||
public async Task<IResult> RunCheck()
|
public async Task<IResult> RunCheck()
|
||||||
{
|
{
|
||||||
IsRunning = true;
|
IsRunning = true;
|
||||||
Passed = await CheckOperation();
|
|
||||||
|
var result = await CheckOperation();
|
||||||
|
Passed = result.Succeeded;
|
||||||
|
|
||||||
|
PreCheckDetails = !string.IsNullOrWhiteSpace(result.Message)
|
||||||
|
? result.Message
|
||||||
|
: (result.Succeeded ? "Pre-Check succeeded, but no details were provided" : "Pre-Check failed, but no details were provided");
|
||||||
|
|
||||||
|
ActionButtonText = result.ActionButtonText;
|
||||||
|
ActionButtonCommand = result.ButtonPressedCommand;
|
||||||
|
ActionButtonIsVisible = result.ActionButtonIsVisible;
|
||||||
|
|
||||||
IsRunning = false;
|
IsRunning = false;
|
||||||
IsPending = false;
|
IsPending = false;
|
||||||
|
|
||||||
return Passed ? Result.FromSuccess() : Result.FromError($"PreCheck Failed: {Name}");
|
return Passed ? Result.FromSuccess() : Result.FromError($"PreCheck Failed: {Name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Task<bool> CheckOperation();
|
public abstract Task<PreCheckResult> CheckOperation();
|
||||||
}
|
}
|
37
SPTInstaller/Models/PreCheckResult.cs
Normal file
37
SPTInstaller/Models/PreCheckResult.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using ReactiveUI;
|
||||||
|
using SPTInstaller.Interfaces;
|
||||||
|
using System.Windows.Input;
|
||||||
|
|
||||||
|
namespace SPTInstaller.Models;
|
||||||
|
public class PreCheckResult : IResult
|
||||||
|
{
|
||||||
|
public bool Succeeded { get; private set; }
|
||||||
|
|
||||||
|
public string Message { get; private set; }
|
||||||
|
|
||||||
|
public bool ActionButtonIsVisible { get; private set; }
|
||||||
|
|
||||||
|
public string ActionButtonText { get; private set; }
|
||||||
|
|
||||||
|
public ICommand ButtonPressedCommand { get; private set; }
|
||||||
|
|
||||||
|
protected PreCheckResult(string message, bool succeeded, string actionButtonText, Action? buttonPressedAction)
|
||||||
|
{
|
||||||
|
Message = message;
|
||||||
|
Succeeded = succeeded;
|
||||||
|
|
||||||
|
ActionButtonText = actionButtonText;
|
||||||
|
|
||||||
|
ActionButtonIsVisible = buttonPressedAction != null && !string.IsNullOrWhiteSpace(actionButtonText);
|
||||||
|
|
||||||
|
buttonPressedAction ??= () => { };
|
||||||
|
|
||||||
|
ButtonPressedCommand = ReactiveCommand.Create(buttonPressedAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PreCheckResult FromSuccess(string message = "") => new PreCheckResult(message, true, "", null);
|
||||||
|
|
||||||
|
public static PreCheckResult FromError(string message, string actionButtonText = "", Action? actionButtonPressedAction = null) => new PreCheckResult(message, false, actionButtonText, actionButtonPressedAction);
|
||||||
|
|
||||||
|
public static PreCheckResult FromException(Exception ex, string actionButtonText = "", Action? actionButtonPressedAction = null) => new PreCheckResult($"An exception was thrown during this precheck\n\nException:\n{ex.Message}\n\nStacktrace:\n{ex.StackTrace}", false, actionButtonText, actionButtonPressedAction);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user