Browse Source

Move DirectoryPathExtensions to Core, add cancel token

pull/438/head
ionite34 10 months ago
parent
commit
cec7342f6d
No known key found for this signature in database
GPG Key ID: B3404C5F3827849B
  1. 1
      StabilityMatrix.Avalonia/ViewModels/Dialogs/InstallerViewModel.cs
  2. 31
      StabilityMatrix.Avalonia/ViewModels/Dialogs/OneClickInstallViewModel.cs
  3. 1
      StabilityMatrix.Avalonia/ViewModels/PackageManager/PackageInstallDetailViewModel.cs
  4. 58
      StabilityMatrix.Core/Extensions/DirectoryPathExtensions.cs

1
StabilityMatrix.Avalonia/ViewModels/Dialogs/InstallerViewModel.cs

@ -22,6 +22,7 @@ using StabilityMatrix.Avalonia.Services;
using StabilityMatrix.Avalonia.ViewModels.Base;
using StabilityMatrix.Avalonia.Views.Dialogs;
using StabilityMatrix.Core.Attributes;
using StabilityMatrix.Core.Extensions;
using StabilityMatrix.Core.Helper;
using StabilityMatrix.Core.Helper.Factory;
using StabilityMatrix.Core.Models;

31
StabilityMatrix.Avalonia/ViewModels/Dialogs/OneClickInstallViewModel.cs

@ -12,6 +12,7 @@ using StabilityMatrix.Avalonia.Languages;
using StabilityMatrix.Avalonia.Services;
using StabilityMatrix.Avalonia.ViewModels.Base;
using StabilityMatrix.Core.Attributes;
using StabilityMatrix.Core.Extensions;
using StabilityMatrix.Core.Helper;
using StabilityMatrix.Core.Helper.Factory;
using StabilityMatrix.Core.Models;
@ -87,15 +88,12 @@ public partial class OneClickInstallViewModel : ContentDialogViewModelBase
SubHeaderText = Resources.Text_OneClickInstaller_SubHeader;
ShowInstallButton = true;
var filteredPackages = this.packageFactory
.GetAllAvailablePackages()
var filteredPackages = this.packageFactory.GetAllAvailablePackages()
.Where(p => p is { OfferInOneClickInstaller: true, IsCompatible: true })
.ToList();
AllPackages = new ObservableCollection<BasePackage>(
filteredPackages.Any()
? filteredPackages
: this.packageFactory.GetAllAvailablePackages()
filteredPackages.Any() ? filteredPackages : this.packageFactory.GetAllAvailablePackages()
);
SelectedPackage = AllPackages[0];
}
@ -136,11 +134,7 @@ public partial class OneClickInstallViewModel : ContentDialogViewModelBase
};
// get latest version & download & install
var installLocation = Path.Combine(
settingsManager.LibraryDir,
"Packages",
SelectedPackage.Name
);
var installLocation = Path.Combine(settingsManager.LibraryDir, "Packages", SelectedPackage.Name);
if (Directory.Exists(installLocation))
{
var installPath = new DirectoryPath(installLocation);
@ -163,11 +157,7 @@ public partial class OneClickInstallViewModel : ContentDialogViewModelBase
var torchVersion = SelectedPackage.GetRecommendedTorchVersion();
var recommendedSharedFolderMethod = SelectedPackage.RecommendedSharedFolderMethod;
var downloadStep = new DownloadPackageVersionStep(
SelectedPackage,
installLocation,
downloadVersion
);
var downloadStep = new DownloadPackageVersionStep(SelectedPackage, installLocation, downloadVersion);
steps.Add(downloadStep);
var installStep = new InstallPackageStep(
@ -199,17 +189,10 @@ public partial class OneClickInstallViewModel : ContentDialogViewModelBase
PreferredSharedFolderMethod = recommendedSharedFolderMethod
};
var addInstalledPackageStep = new AddInstalledPackageStep(
settingsManager,
installedPackage
);
var addInstalledPackageStep = new AddInstalledPackageStep(settingsManager, installedPackage);
steps.Add(addInstalledPackageStep);
var runner = new PackageModificationRunner
{
ShowDialogOnStart = true,
HideCloseButton = true,
};
var runner = new PackageModificationRunner { ShowDialogOnStart = true, HideCloseButton = true, };
EventManager.Instance.OnPackageInstallProgressAdded(runner);
await runner.ExecuteSteps(steps);

1
StabilityMatrix.Avalonia/ViewModels/PackageManager/PackageInstallDetailViewModel.cs

@ -16,6 +16,7 @@ using StabilityMatrix.Avalonia.Languages;
using StabilityMatrix.Avalonia.Services;
using StabilityMatrix.Avalonia.ViewModels.Base;
using StabilityMatrix.Core.Attributes;
using StabilityMatrix.Core.Extensions;
using StabilityMatrix.Core.Helper;
using StabilityMatrix.Core.Models;
using StabilityMatrix.Core.Models.Database;

58
StabilityMatrix.Avalonia/Extensions/DirectoryPathExtensions.cs → StabilityMatrix.Core/Extensions/DirectoryPathExtensions.cs

@ -1,12 +1,9 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Threading.Tasks;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Extensions.Logging;
using Polly;
using StabilityMatrix.Core.Models.FileInterfaces;
namespace StabilityMatrix.Avalonia.Extensions;
namespace StabilityMatrix.Core.Extensions;
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
public static class DirectoryPathExtensions
@ -15,21 +12,32 @@ public static class DirectoryPathExtensions
/// Deletes a directory and all of its contents recursively.
/// Uses Polly to retry the deletion if it fails, up to 5 times with an exponential backoff.
/// </summary>
public static Task DeleteVerboseAsync(this DirectoryPath directory, ILogger? logger = default)
public static Task DeleteVerboseAsync(
this DirectoryPath directory,
ILogger? logger = default,
CancellationToken cancellationToken = default
)
{
var policy = Policy.Handle<IOException>()
.WaitAndRetryAsync(3, attempt => TimeSpan.FromMilliseconds(50 * Math.Pow(2, attempt)),
var policy = Policy
.Handle<IOException>()
.WaitAndRetryAsync(
3,
attempt => TimeSpan.FromMilliseconds(50 * Math.Pow(2, attempt)),
onRetry: (exception, calculatedWaitDuration) =>
{
logger?.LogWarning(
exception,
"Deletion of {TargetDirectory} failed. Retrying in {CalculatedWaitDuration}",
directory, calculatedWaitDuration);
});
directory,
calculatedWaitDuration
);
}
);
return policy.ExecuteAsync(async () =>
{
await Task.Run(() => { DeleteVerbose(directory, logger); });
await Task.Run(() => DeleteVerbose(directory, logger, cancellationToken), cancellationToken)
.ConfigureAwait(false);
});
}
@ -37,8 +45,14 @@ public static class DirectoryPathExtensions
/// Deletes a directory and all of its contents recursively.
/// Removes link targets without deleting the source.
/// </summary>
public static void DeleteVerbose(this DirectoryPath directory, ILogger? logger = default)
public static void DeleteVerbose(
this DirectoryPath directory,
ILogger? logger = default,
CancellationToken cancellationToken = default
)
{
cancellationToken.ThrowIfCancellationRequested();
// Skip if directory does not exist
if (!directory.Exists)
{
@ -47,7 +61,7 @@ public static class DirectoryPathExtensions
// For junction points, delete with recursive false
if (directory.IsSymbolicLink)
{
logger?.LogInformation("Removing junction point {TargetDirectory}", directory);
logger?.LogInformation("Removing junction point {TargetDirectory}", directory.FullPath);
try
{
directory.Delete(false);
@ -55,29 +69,31 @@ public static class DirectoryPathExtensions
}
catch (IOException ex)
{
throw new IOException($"Failed to delete junction point {directory}", ex);
throw new IOException($"Failed to delete junction point {directory.FullPath}", ex);
}
}
// Recursively delete all subdirectories
foreach (var subDir in directory.Info.EnumerateDirectories())
foreach (var subDir in directory.EnumerateDirectories())
{
DeleteVerbose(subDir, logger);
DeleteVerbose(subDir, logger, cancellationToken);
}
// Delete all files in the directory
foreach (var filePath in directory.Info.EnumerateFiles())
foreach (var filePath in directory.EnumerateFiles())
{
cancellationToken.ThrowIfCancellationRequested();
try
{
filePath.Attributes = FileAttributes.Normal;
filePath.Info.Attributes = FileAttributes.Normal;
filePath.Delete();
}
catch (IOException ex)
{
throw new IOException($"Failed to delete file {filePath.FullName}", ex);
throw new IOException($"Failed to delete file {filePath.FullPath}", ex);
}
}
// Delete this directory
try
{
Loading…
Cancel
Save