Browse Source

Merge pull request #303 from ionite34/use-git

Use git operations for package updates & installs
pull/240/head
JT 1 year ago committed by GitHub
parent
commit
7e16d3f03e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 8
      StabilityMatrix.Avalonia/App.axaml.cs
  3. 6
      StabilityMatrix.Avalonia/Helpers/UnixPrerequisiteHelper.cs
  4. 90
      StabilityMatrix.Avalonia/Helpers/WindowsPrerequisiteHelper.cs
  5. 12
      StabilityMatrix.Avalonia/ViewModels/Dialogs/InstallerViewModel.cs
  6. 17
      StabilityMatrix.Avalonia/ViewModels/Dialogs/OneClickInstallViewModel.cs
  7. 39
      StabilityMatrix.Avalonia/ViewModels/OutputsPageViewModel.cs
  8. 24
      StabilityMatrix.Avalonia/ViewModels/PackageManager/PackageCardViewModel.cs
  9. 22
      StabilityMatrix.Avalonia/Views/OutputsPage.axaml
  10. 3
      StabilityMatrix.Avalonia/Views/PackageManagerPage.axaml
  11. 7
      StabilityMatrix.Core/Helper/IPrerequisiteHelper.cs
  12. 138
      StabilityMatrix.Core/Helper/PrerequisiteHelper.cs
  13. 1
      StabilityMatrix.Core/Models/DownloadPackageVersionOptions.cs
  14. 11
      StabilityMatrix.Core/Models/PackageModification/InstallPackageStep.cs
  15. 11
      StabilityMatrix.Core/Models/PackageModification/UpdatePackageStep.cs
  16. 7
      StabilityMatrix.Core/Models/Packages/A3WebUI.cs
  17. 190
      StabilityMatrix.Core/Models/Packages/BaseGitPackage.cs
  18. 2
      StabilityMatrix.Core/Models/Packages/BasePackage.cs
  19. 3
      StabilityMatrix.Core/Models/Packages/ComfyUI.cs
  20. 12
      StabilityMatrix.Core/Models/Packages/DankDiffusion.cs
  21. 2
      StabilityMatrix.Core/Models/Packages/Fooocus.cs
  22. 5
      StabilityMatrix.Core/Models/Packages/FooocusMre.cs
  23. 143
      StabilityMatrix.Core/Models/Packages/InvokeAI.cs
  24. 7
      StabilityMatrix.Core/Models/Packages/StableDiffusionUx.cs
  25. 2
      StabilityMatrix.Core/Models/Packages/UnknownPackage.cs
  26. 20
      StabilityMatrix.Core/Models/Packages/VladAutomatic.cs
  27. 3
      StabilityMatrix.Core/Models/Packages/VoltaML.cs

1
CHANGELOG.md

@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning 2.0](https://semver.org/spec/v2
- Added [Stable Diffusion WebUI/UX](https://github.com/anapnoe/stable-diffusion-webui-ux) package - Added [Stable Diffusion WebUI/UX](https://github.com/anapnoe/stable-diffusion-webui-ux) package
### Changed ### Changed
- If ComfyUI for Inference is chosen during the One-Click Installer, the Inference page will be opened after installation instead of the Launch page - If ComfyUI for Inference is chosen during the One-Click Installer, the Inference page will be opened after installation instead of the Launch page
- Changed all package installs & updates to use git commands instead of downloading zip files
### Fixed ### Fixed
- Fixed crash when clicking Inference gallery image after the image is deleted externally in file explorer - Fixed crash when clicking Inference gallery image after the image is deleted externally in file explorer
- Fixed Inference popup Install button not working on One-Click Installer - Fixed Inference popup Install button not working on One-Click Installer

8
StabilityMatrix.Avalonia/App.axaml.cs

@ -434,12 +434,12 @@ public sealed class App : Application
{ {
services.AddSingleton<BasePackage, A3WebUI>(); services.AddSingleton<BasePackage, A3WebUI>();
services.AddSingleton<BasePackage, StableDiffusionUx>(); services.AddSingleton<BasePackage, StableDiffusionUx>();
services.AddSingleton<BasePackage, VladAutomatic>(); services.AddSingleton<BasePackage, InvokeAI>();
services.AddSingleton<BasePackage, Fooocus>();
services.AddSingleton<BasePackage, FooocusMre>();
services.AddSingleton<BasePackage, ComfyUI>(); services.AddSingleton<BasePackage, ComfyUI>();
services.AddSingleton<BasePackage, Fooocus>();
services.AddSingleton<BasePackage, VladAutomatic>();
services.AddSingleton<BasePackage, VoltaML>(); services.AddSingleton<BasePackage, VoltaML>();
services.AddSingleton<BasePackage, InvokeAI>(); services.AddSingleton<BasePackage, FooocusMre>();
} }
private static IServiceCollection ConfigureServices() private static IServiceCollection ConfigureServices()

6
StabilityMatrix.Avalonia/Helpers/UnixPrerequisiteHelper.cs

@ -126,7 +126,11 @@ public class UnixPrerequisiteHelper : IPrerequisiteHelper
} }
} }
public async Task RunGit(string? workingDirectory = null, params string[] args) public async Task RunGit(
string? workingDirectory = null,
Action<ProcessOutput>? onProcessOutput = null,
params string[] args
)
{ {
var command = var command =
args.Length == 0 ? "git" : "git " + string.Join(" ", args.Select(ProcessRunner.Quote)); args.Length == 0 ? "git" : "git " + string.Join(" ", args.Select(ProcessRunner.Quote));

90
StabilityMatrix.Avalonia/Helpers/WindowsPrerequisiteHelper.cs

@ -36,6 +36,7 @@ public class WindowsPrerequisiteHelper : IPrerequisiteHelper
private string PythonDllPath => Path.Combine(PythonDir, "python310.dll"); private string PythonDllPath => Path.Combine(PythonDir, "python310.dll");
private string PythonLibraryZipPath => Path.Combine(PythonDir, "python310.zip"); private string PythonLibraryZipPath => Path.Combine(PythonDir, "python310.zip");
private string GetPipPath => Path.Combine(PythonDir, "get-pip.pyc"); private string GetPipPath => Path.Combine(PythonDir, "get-pip.pyc");
// Temporary directory to extract venv to during python install // Temporary directory to extract venv to during python install
private string VenvTempDir => Path.Combine(PythonDir, "venv"); private string VenvTempDir => Path.Combine(PythonDir, "venv");
@ -49,21 +50,30 @@ public class WindowsPrerequisiteHelper : IPrerequisiteHelper
public WindowsPrerequisiteHelper( public WindowsPrerequisiteHelper(
IGitHubClient gitHubClient, IGitHubClient gitHubClient,
IDownloadService downloadService, IDownloadService downloadService,
ISettingsManager settingsManager) ISettingsManager settingsManager
)
{ {
this.gitHubClient = gitHubClient; this.gitHubClient = gitHubClient;
this.downloadService = downloadService; this.downloadService = downloadService;
this.settingsManager = settingsManager; this.settingsManager = settingsManager;
} }
public async Task RunGit(string? workingDirectory = null, params string[] args) public async Task RunGit(
string? workingDirectory = null,
Action<ProcessOutput>? onProcessOutput = null,
params string[] args
)
{ {
var process = ProcessRunner.StartAnsiProcess(GitExePath, args, var process = ProcessRunner.StartAnsiProcess(
GitExePath,
args,
workingDirectory: workingDirectory, workingDirectory: workingDirectory,
environmentVariables: new Dictionary<string, string> environmentVariables: new Dictionary<string, string>
{ {
{"PATH", Compat.GetEnvPathWithExtensions(GitBinPath)} { "PATH", Compat.GetEnvPathWithExtensions(GitBinPath) }
}); },
outputDataReceived: onProcessOutput
);
await ProcessRunner.WaitForExitConditionAsync(process); await ProcessRunner.WaitForExitConditionAsync(process);
} }
@ -71,12 +81,14 @@ public class WindowsPrerequisiteHelper : IPrerequisiteHelper
public async Task<string> GetGitOutput(string? workingDirectory = null, params string[] args) public async Task<string> GetGitOutput(string? workingDirectory = null, params string[] args)
{ {
var process = await ProcessRunner.GetProcessOutputAsync( var process = await ProcessRunner.GetProcessOutputAsync(
GitExePath, string.Join(" ", args), GitExePath,
string.Join(" ", args),
workingDirectory: workingDirectory, workingDirectory: workingDirectory,
environmentVariables: new Dictionary<string, string> environmentVariables: new Dictionary<string, string>
{ {
{"PATH", Compat.GetEnvPathWithExtensions(GitBinPath)} { "PATH", Compat.GetEnvPathWithExtensions(GitBinPath) }
}); }
);
return process; return process;
} }
@ -98,7 +110,9 @@ public class WindowsPrerequisiteHelper : IPrerequisiteHelper
(Assets.SevenZipLicense, AssetsDir), (Assets.SevenZipLicense, AssetsDir),
}; };
progress?.Report(new ProgressReport(0, message: "Unpacking resources", isIndeterminate: true)); progress?.Report(
new ProgressReport(0, message: "Unpacking resources", isIndeterminate: true)
);
Directory.CreateDirectory(AssetsDir); Directory.CreateDirectory(AssetsDir);
foreach (var (asset, extractDir) in assets) foreach (var (asset, extractDir) in assets)
@ -106,7 +120,9 @@ public class WindowsPrerequisiteHelper : IPrerequisiteHelper
await asset.ExtractToDir(extractDir); await asset.ExtractToDir(extractDir);
} }
progress?.Report(new ProgressReport(1, message: "Unpacking resources", isIndeterminate: false)); progress?.Report(
new ProgressReport(1, message: "Unpacking resources", isIndeterminate: false)
);
} }
public async Task InstallPythonIfNecessary(IProgress<ProgressReport>? progress = null) public async Task InstallPythonIfNecessary(IProgress<ProgressReport>? progress = null)
@ -143,8 +159,9 @@ public class WindowsPrerequisiteHelper : IPrerequisiteHelper
{ {
var fileExists = File.Exists(PythonDownloadPath); var fileExists = File.Exists(PythonDownloadPath);
var fileSize = new FileInfo(PythonDownloadPath).Length; var fileSize = new FileInfo(PythonDownloadPath).Length;
var msg = $"Python download hash mismatch: {downloadHash} != {remote.HashSha256} " + var msg =
$"(file exists: {fileExists}, size: {fileSize})"; $"Python download hash mismatch: {downloadHash} != {remote.HashSha256} "
+ $"(file exists: {fileExists}, size: {fileSize})";
throw new Exception(msg); throw new Exception(msg);
} }
@ -233,7 +250,11 @@ public class WindowsPrerequisiteHelper : IPrerequisiteHelper
if (!File.Exists(PortableGitDownloadPath)) if (!File.Exists(PortableGitDownloadPath))
{ {
await downloadService.DownloadToFileAsync(portableGitUrl, PortableGitDownloadPath, progress: progress); await downloadService.DownloadToFileAsync(
portableGitUrl,
PortableGitDownloadPath,
progress: progress
);
progress?.Report(new ProgressReport(progress: 1f, message: "Git download complete")); progress?.Report(new ProgressReport(progress: 1f, message: "Git download complete"));
} }
@ -245,7 +266,9 @@ public class WindowsPrerequisiteHelper : IPrerequisiteHelper
{ {
var registry = Registry.LocalMachine; var registry = Registry.LocalMachine;
var key = registry.OpenSubKey( var key = registry.OpenSubKey(
@"SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\X64", false); @"SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\X64",
false
);
if (key != null) if (key != null)
{ {
var buildId = Convert.ToUInt32(key.GetValue("Bld")); var buildId = Convert.ToUInt32(key.GetValue("Bld"));
@ -257,16 +280,40 @@ public class WindowsPrerequisiteHelper : IPrerequisiteHelper
Logger.Info("Downloading VC Redist"); Logger.Info("Downloading VC Redist");
await downloadService.DownloadToFileAsync(VcRedistDownloadUrl, VcRedistDownloadPath, progress: progress); await downloadService.DownloadToFileAsync(
progress?.Report(new ProgressReport(progress: 1f, message: "Visual C++ download complete", VcRedistDownloadUrl,
type: ProgressType.Download)); VcRedistDownloadPath,
progress: progress
);
progress?.Report(
new ProgressReport(
progress: 1f,
message: "Visual C++ download complete",
type: ProgressType.Download
)
);
Logger.Info("Installing VC Redist"); Logger.Info("Installing VC Redist");
progress?.Report(new ProgressReport(progress: 0.5f, isIndeterminate: true, type: ProgressType.Generic, message: "Installing prerequisites...")); progress?.Report(
var process = ProcessRunner.StartAnsiProcess(VcRedistDownloadPath, "/install /quiet /norestart"); new ProgressReport(
progress: 0.5f,
isIndeterminate: true,
type: ProgressType.Generic,
message: "Installing prerequisites..."
)
);
var process = ProcessRunner.StartAnsiProcess(
VcRedistDownloadPath,
"/install /quiet /norestart"
);
await process.WaitForExitAsync(); await process.WaitForExitAsync();
progress?.Report(new ProgressReport(progress: 1f, message: "Visual C++ install complete", progress?.Report(
type: ProgressType.Generic)); new ProgressReport(
progress: 1f,
message: "Visual C++ install complete",
type: ProgressType.Generic
)
);
File.Delete(VcRedistDownloadPath); File.Delete(VcRedistDownloadPath);
} }
@ -286,5 +333,4 @@ public class WindowsPrerequisiteHelper : IPrerequisiteHelper
File.Delete(PortableGitDownloadPath); File.Delete(PortableGitDownloadPath);
} }
} }

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

@ -238,6 +238,8 @@ public partial class InstallerViewModel : ContentDialogViewModelBase
downloadOptions.VersionTag = downloadOptions.VersionTag =
SelectedVersion?.TagName SelectedVersion?.TagName
?? throw new NullReferenceException("Selected version is null"); ?? throw new NullReferenceException("Selected version is null");
downloadOptions.IsLatest =
AvailableVersions?.First().TagName == downloadOptions.VersionTag;
installedVersion.InstalledReleaseVersion = downloadOptions.VersionTag; installedVersion.InstalledReleaseVersion = downloadOptions.VersionTag;
} }
@ -245,6 +247,11 @@ public partial class InstallerViewModel : ContentDialogViewModelBase
{ {
downloadOptions.CommitHash = downloadOptions.CommitHash =
SelectedCommit?.Sha ?? throw new NullReferenceException("Selected commit is null"); SelectedCommit?.Sha ?? throw new NullReferenceException("Selected commit is null");
downloadOptions.BranchName =
SelectedVersion?.TagName
?? throw new NullReferenceException("Selected version is null");
downloadOptions.IsLatest = AvailableCommits?.First().Sha == SelectedCommit.Sha;
installedVersion.InstalledBranch = installedVersion.InstalledBranch =
SelectedVersion?.TagName SelectedVersion?.TagName
?? throw new NullReferenceException("Selected version is null"); ?? throw new NullReferenceException("Selected version is null");
@ -259,6 +266,7 @@ public partial class InstallerViewModel : ContentDialogViewModelBase
var installStep = new InstallPackageStep( var installStep = new InstallPackageStep(
SelectedPackage, SelectedPackage,
SelectedTorchVersion, SelectedTorchVersion,
downloadOptions,
installLocation installLocation
); );
var setupModelFoldersStep = new SetupModelFoldersStep( var setupModelFoldersStep = new SetupModelFoldersStep(
@ -307,6 +315,10 @@ public partial class InstallerViewModel : ContentDialogViewModelBase
{ {
SelectedVersion = null; SelectedVersion = null;
} }
else if (SelectedPackage is FooocusMre)
{
SelectedVersion = AvailableVersions.FirstOrDefault(x => x.TagName == "moonride-main");
}
else else
{ {
// First try to find master // First try to find master

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

@ -145,7 +145,7 @@ public partial class OneClickInstallViewModel : ViewModelBase
// get latest version & download & install // get latest version & download & install
var installLocation = Path.Combine(libraryDir, "Packages", SelectedPackage.Name); var installLocation = Path.Combine(libraryDir, "Packages", SelectedPackage.Name);
var downloadVersion = new DownloadPackageVersionOptions(); var downloadVersion = new DownloadPackageVersionOptions { IsLatest = true };
var installedVersion = new InstalledPackageVersion(); var installedVersion = new InstalledPackageVersion();
var versionOptions = await SelectedPackage.GetAllVersionOptions(); var versionOptions = await SelectedPackage.GetAllVersionOptions();
@ -157,13 +157,19 @@ public partial class OneClickInstallViewModel : ViewModelBase
else else
{ {
downloadVersion.BranchName = await SelectedPackage.GetLatestVersion(); downloadVersion.BranchName = await SelectedPackage.GetLatestVersion();
downloadVersion.CommitHash =
(await SelectedPackage.GetAllCommits(downloadVersion.BranchName))
?.FirstOrDefault()
?.Sha ?? string.Empty;
installedVersion.InstalledBranch = downloadVersion.BranchName; installedVersion.InstalledBranch = downloadVersion.BranchName;
installedVersion.InstalledCommitSha = downloadVersion.CommitHash;
} }
var torchVersion = SelectedPackage.GetRecommendedTorchVersion(); var torchVersion = SelectedPackage.GetRecommendedTorchVersion();
await DownloadPackage(installLocation, downloadVersion); await DownloadPackage(installLocation, downloadVersion);
await InstallPackage(installLocation, torchVersion); await InstallPackage(installLocation, torchVersion, downloadVersion);
var recommendedSharedFolderMethod = SelectedPackage.RecommendedSharedFolderMethod; var recommendedSharedFolderMethod = SelectedPackage.RecommendedSharedFolderMethod;
await SelectedPackage.SetupModelFolders(installLocation, recommendedSharedFolderMethod); await SelectedPackage.SetupModelFolders(installLocation, recommendedSharedFolderMethod);
@ -222,7 +228,11 @@ public partial class OneClickInstallViewModel : ViewModelBase
OneClickInstallProgress = 100; OneClickInstallProgress = 100;
} }
private async Task InstallPackage(string installLocation, TorchVersion torchVersion) private async Task InstallPackage(
string installLocation,
TorchVersion torchVersion,
DownloadPackageVersionOptions versionOptions
)
{ {
var progress = new Progress<ProgressReport>(progress => var progress = new Progress<ProgressReport>(progress =>
{ {
@ -235,6 +245,7 @@ public partial class OneClickInstallViewModel : ViewModelBase
await SelectedPackage.InstallPackage( await SelectedPackage.InstallPackage(
installLocation, installLocation,
torchVersion, torchVersion,
versionOptions,
progress, progress,
(output) => SubSubHeaderText = output.Text (output) => SubSubHeaderText = output.Text
); );

39
StabilityMatrix.Avalonia/ViewModels/OutputsPageViewModel.cs

@ -24,6 +24,7 @@ using StabilityMatrix.Avalonia.Models;
using StabilityMatrix.Avalonia.Services; using StabilityMatrix.Avalonia.Services;
using StabilityMatrix.Avalonia.ViewModels.Base; using StabilityMatrix.Avalonia.ViewModels.Base;
using StabilityMatrix.Avalonia.ViewModels.Dialogs; using StabilityMatrix.Avalonia.ViewModels.Dialogs;
using StabilityMatrix.Avalonia.ViewModels.Inference;
using StabilityMatrix.Avalonia.ViewModels.OutputsPage; using StabilityMatrix.Avalonia.ViewModels.OutputsPage;
using StabilityMatrix.Core.Attributes; using StabilityMatrix.Core.Attributes;
using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Helper;
@ -72,6 +73,9 @@ public partial class OutputsPageViewModel : PageViewModelBase
[NotifyPropertyChangedFor(nameof(NumImagesSelected))] [NotifyPropertyChangedFor(nameof(NumImagesSelected))]
private int numItemsSelected; private int numItemsSelected;
[ObservableProperty]
private string searchQuery;
public bool CanShowOutputTypes => SelectedCategory.Name.Equals("Shared Output Folder"); public bool CanShowOutputTypes => SelectedCategory.Name.Equals("Shared Output Folder");
public string NumImagesSelected => public string NumImagesSelected =>
@ -92,11 +96,35 @@ public partial class OutputsPageViewModel : PageViewModelBase
this.navigationService = navigationService; this.navigationService = navigationService;
this.logger = logger; this.logger = logger;
var predicate = this.WhenPropertyChanged(vm => vm.SearchQuery)
.Throttle(TimeSpan.FromMilliseconds(50))!
.Select<PropertyValue<OutputsPageViewModel, string>, Func<OutputImageViewModel, bool>>(
propertyValue =>
output =>
{
if (string.IsNullOrWhiteSpace(propertyValue.Value))
return true;
return output.ImageFile.FileName.Contains(
propertyValue.Value,
StringComparison.OrdinalIgnoreCase
)
|| (
output.ImageFile.GenerationParameters?.PositivePrompt != null
&& output.ImageFile.GenerationParameters.PositivePrompt.Contains(
propertyValue.Value,
StringComparison.OrdinalIgnoreCase
)
);
}
)
.AsObservable();
OutputsCache OutputsCache
.Connect() .Connect()
.DeferUntilLoaded() .DeferUntilLoaded()
.Filter(predicate)
.SortBy(x => x.ImageFile.CreatedAt, SortDirection.Descending) .SortBy(x => x.ImageFile.CreatedAt, SortDirection.Descending)
.ObserveOn(SynchronizationContext.Current)
.Bind(Outputs) .Bind(Outputs)
.WhenPropertyChanged(p => p.IsSelected) .WhenPropertyChanged(p => p.IsSelected)
.Subscribe(_ => .Subscribe(_ =>
@ -135,6 +163,7 @@ public partial class OutputsPageViewModel : PageViewModelBase
Categories = new ObservableCollection<PackageOutputCategory>(packageCategories); Categories = new ObservableCollection<PackageOutputCategory>(packageCategories);
SelectedCategory = Categories.First(); SelectedCategory = Categories.First();
SelectedOutputType = SharedOutputType.All; SelectedOutputType = SharedOutputType.All;
SearchQuery = string.Empty;
} }
public override void OnLoaded() public override void OnLoaded()
@ -280,16 +309,16 @@ public partial class OutputsPageViewModel : PageViewModelBase
} }
} }
public void SendToTextToImage(LocalImageFile image) public void SendToTextToImage(OutputImageViewModel vm)
{ {
navigationService.NavigateTo<InferenceViewModel>(); navigationService.NavigateTo<InferenceViewModel>();
EventManager.Instance.OnInferenceTextToImageRequested(image); EventManager.Instance.OnInferenceTextToImageRequested(vm.ImageFile);
} }
public void SendToUpscale(LocalImageFile image) public void SendToUpscale(OutputImageViewModel vm)
{ {
navigationService.NavigateTo<InferenceViewModel>(); navigationService.NavigateTo<InferenceViewModel>();
EventManager.Instance.OnInferenceUpscaleRequested(image); EventManager.Instance.OnInferenceUpscaleRequested(vm.ImageFile);
} }
public void ClearSelection() public void ClearSelection()

24
StabilityMatrix.Avalonia/ViewModels/PackageManager/PackageCardViewModel.cs

@ -240,7 +240,29 @@ public partial class PackageCardViewModel : ProgressViewModel
{ {
ModificationCompleteMessage = $"{packageName} Update Complete" ModificationCompleteMessage = $"{packageName} Update Complete"
}; };
var updatePackageStep = new UpdatePackageStep(settingsManager, Package, basePackage);
var versionOptions = new DownloadPackageVersionOptions { IsLatest = true };
if (Package.Version.IsReleaseMode)
{
versionOptions.VersionTag = await basePackage.GetLatestVersion();
}
else
{
var commits = await basePackage.GetAllCommits(Package.Version.InstalledBranch);
var latest = commits?.FirstOrDefault();
if (latest == null)
throw new Exception("Could not find latest commit");
versionOptions.BranchName = Package.Version.InstalledBranch;
versionOptions.CommitHash = latest.Sha;
}
var updatePackageStep = new UpdatePackageStep(
settingsManager,
Package,
versionOptions,
basePackage
);
var steps = new List<IPackageStep> { updatePackageStep }; var steps = new List<IPackageStep> { updatePackageStep };
EventManager.Instance.OnPackageInstallProgressAdded(runner); EventManager.Instance.OnPackageInstallProgressAdded(runner);

22
StabilityMatrix.Avalonia/Views/OutputsPage.axaml

@ -25,7 +25,7 @@
<Grid Grid.Row="0" Margin="0,0,0,16" <Grid Grid.Row="0" Margin="0,0,0,16"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
RowDefinitions="Auto, Auto" RowDefinitions="Auto, Auto"
ColumnDefinitions="Auto, Auto, Auto, *, Auto, Auto"> ColumnDefinitions="Auto, Auto, Auto, Auto, *, Auto, Auto">
<TextBlock Grid.Row="0" <TextBlock Grid.Row="0"
Grid.Column="0" Grid.Column="0"
Text="{x:Static lang:Resources.Label_OutputFolder}" Text="{x:Static lang:Resources.Label_OutputFolder}"
@ -69,8 +69,20 @@
VerticalAlignment="Stretch" VerticalAlignment="Stretch"
VerticalContentAlignment="Center" /> VerticalContentAlignment="Center" />
<TextBlock Grid.Row="0"
Grid.Column="2"
Margin="4"
Text="Search"/>
<TextBox Grid.Row="1"
Grid.Column="2"
Text="{Binding SearchQuery, Mode=TwoWay}"
Watermark="Search"
Margin="4, 0"
VerticalContentAlignment="Center"
MinWidth="150"/>
<TextBlock Grid.Row="1" <TextBlock Grid.Row="1"
Grid.Column="3" Grid.Column="4"
IsVisible="{Binding !!NumItemsSelected}" IsVisible="{Binding !!NumItemsSelected}"
FontSize="16" FontSize="16"
Margin="8, 0" Margin="8, 0"
@ -80,7 +92,7 @@
Text="{Binding NumImagesSelected, FallbackValue=1234 images selected}" /> Text="{Binding NumImagesSelected, FallbackValue=1234 images selected}" />
<Button Grid.Row="1" <Button Grid.Row="1"
Grid.Column="4" Grid.Column="5"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
CornerRadius="8" CornerRadius="8"
Padding="12, 0" Padding="12, 0"
@ -92,7 +104,7 @@
</Button> </Button>
<Button Grid.Row="1" <Button Grid.Row="1"
Grid.Column="5" Grid.Column="6"
Content="{x:Static lang:Resources.Action_ClearSelection}" Content="{x:Static lang:Resources.Action_ClearSelection}"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
CornerRadius="8" CornerRadius="8"
@ -101,7 +113,7 @@
Command="{Binding ClearSelection}" Command="{Binding ClearSelection}"
IsVisible="{Binding !!NumItemsSelected}" /> IsVisible="{Binding !!NumItemsSelected}" />
<Button Grid.Row="1" <Button Grid.Row="1"
Grid.Column="5" Grid.Column="6"
Content="{x:Static lang:Resources.Action_SelectAll}" Content="{x:Static lang:Resources.Action_SelectAll}"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
Classes="accent" Classes="accent"

3
StabilityMatrix.Avalonia/Views/PackageManagerPage.axaml

@ -120,7 +120,8 @@
</MenuItem> </MenuItem>
<MenuItem <MenuItem
Header="{x:Static lang:Resources.Label_UseSharedOutputFolder}" Header="{x:Static lang:Resources.Label_UseSharedOutputFolder}"
Command="{Binding ToggleSharedOutput}"> Command="{Binding ToggleSharedOutput}"
IsVisible="{Binding !IsUnknownPackage}">
<MenuItem.Icon> <MenuItem.Icon>
<CheckBox Margin="8,0,0,0" <CheckBox Margin="8,0,0,0"
Padding="0" Padding="0"

7
StabilityMatrix.Core/Helper/IPrerequisiteHelper.cs

@ -1,5 +1,6 @@
using System.Runtime.Versioning; using System.Runtime.Versioning;
using StabilityMatrix.Core.Models.Progress; using StabilityMatrix.Core.Models.Progress;
using StabilityMatrix.Core.Processes;
namespace StabilityMatrix.Core.Helper; namespace StabilityMatrix.Core.Helper;
@ -20,6 +21,10 @@ public interface IPrerequisiteHelper
/// <summary> /// <summary>
/// Run embedded git with the given arguments. /// Run embedded git with the given arguments.
/// </summary> /// </summary>
Task RunGit(string? workingDirectory = null, params string[] args); Task RunGit(
string? workingDirectory = null,
Action<ProcessOutput>? onProcessOutput = null,
params string[] args
);
Task<string> GetGitOutput(string? workingDirectory = null, params string[] args); Task<string> GetGitOutput(string? workingDirectory = null, params string[] args);
} }

138
StabilityMatrix.Core/Helper/PrerequisiteHelper.cs

@ -19,8 +19,10 @@ public class PrerequisiteHelper : IPrerequisiteHelper
private readonly ISettingsManager settingsManager; private readonly ISettingsManager settingsManager;
private const string VcRedistDownloadUrl = "https://aka.ms/vs/16/release/vc_redist.x64.exe"; private const string VcRedistDownloadUrl = "https://aka.ms/vs/16/release/vc_redist.x64.exe";
private const string PythonDownloadUrl = "https://www.python.org/ftp/python/3.10.11/python-3.10.11-embed-amd64.zip"; private const string PythonDownloadUrl =
private const string PythonDownloadHashBlake3 = "24923775f2e07392063aaa0c78fbd4ae0a320e1fc9c6cfbab63803402279fe5a"; "https://www.python.org/ftp/python/3.10.11/python-3.10.11-embed-amd64.zip";
private const string PythonDownloadHashBlake3 =
"24923775f2e07392063aaa0c78fbd4ae0a320e1fc9c6cfbab63803402279fe5a";
private string HomeDir => settingsManager.LibraryDir; private string HomeDir => settingsManager.LibraryDir;
@ -34,6 +36,7 @@ public class PrerequisiteHelper : IPrerequisiteHelper
private string PythonDllPath => Path.Combine(PythonDir, "python310.dll"); private string PythonDllPath => Path.Combine(PythonDir, "python310.dll");
private string PythonLibraryZipPath => Path.Combine(PythonDir, "python310.zip"); private string PythonLibraryZipPath => Path.Combine(PythonDir, "python310.zip");
private string GetPipPath => Path.Combine(PythonDir, "get-pip.pyc"); private string GetPipPath => Path.Combine(PythonDir, "get-pip.pyc");
// Temporary directory to extract venv to during python install // Temporary directory to extract venv to during python install
private string VenvTempDir => Path.Combine(PythonDir, "venv"); private string VenvTempDir => Path.Combine(PythonDir, "venv");
@ -44,8 +47,12 @@ public class PrerequisiteHelper : IPrerequisiteHelper
public bool IsPythonInstalled => File.Exists(PythonDllPath); public bool IsPythonInstalled => File.Exists(PythonDllPath);
public PrerequisiteHelper(ILogger<PrerequisiteHelper> logger, IGitHubClient gitHubClient, public PrerequisiteHelper(
IDownloadService downloadService, ISettingsManager settingsManager) ILogger<PrerequisiteHelper> logger,
IGitHubClient gitHubClient,
IDownloadService downloadService,
ISettingsManager settingsManager
)
{ {
this.logger = logger; this.logger = logger;
this.gitHubClient = gitHubClient; this.gitHubClient = gitHubClient;
@ -53,16 +60,30 @@ public class PrerequisiteHelper : IPrerequisiteHelper
this.settingsManager = settingsManager; this.settingsManager = settingsManager;
} }
public async Task RunGit(string? workingDirectory = null, params string[] args) public async Task RunGit(
string? workingDirectory = null,
Action<ProcessOutput>? onProcessOutput = null,
params string[] args
)
{ {
var process = ProcessRunner.StartAnsiProcess(GitExePath, args, workingDirectory: workingDirectory); var process = ProcessRunner.StartAnsiProcess(
GitExePath,
args,
workingDirectory,
onProcessOutput
);
await ProcessRunner.WaitForExitConditionAsync(process).ConfigureAwait(false); await ProcessRunner.WaitForExitConditionAsync(process).ConfigureAwait(false);
} }
public async Task<string> GetGitOutput(string? workingDirectory = null, params string[] args) public async Task<string> GetGitOutput(string? workingDirectory = null, params string[] args)
{ {
var output = await ProcessRunner.GetProcessOutputAsync(GitExePath, string.Join(" ", args), var output = await ProcessRunner
workingDirectory: workingDirectory).ConfigureAwait(false); .GetProcessOutputAsync(
GitExePath,
string.Join(" ", args),
workingDirectory: workingDirectory
)
.ConfigureAwait(false);
return output; return output;
} }
@ -85,11 +106,14 @@ public class PrerequisiteHelper : IPrerequisiteHelper
// from "StabilityMatrix.Assets.Python310.libssl-1_1.dll" // from "StabilityMatrix.Assets.Python310.libssl-1_1.dll"
// to "Python310\libssl-1_1.dll" // to "Python310\libssl-1_1.dll"
var fileExt = Path.GetExtension(resourceName); var fileExt = Path.GetExtension(resourceName);
var fileName = resourceName var fileName =
resourceName
.Replace(fileExt, "") .Replace(fileExt, "")
.Replace("StabilityMatrix.Assets.", "") .Replace("StabilityMatrix.Assets.", "")
.Replace(".", Path.DirectorySeparatorChar.ToString()) + fileExt; .Replace(".", Path.DirectorySeparatorChar.ToString()) + fileExt;
await using var resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)!; await using var resourceStream = Assembly
.GetExecutingAssembly()
.GetManifestResourceStream(resourceName)!;
if (resourceStream == null) if (resourceStream == null)
{ {
throw new Exception($"Resource {resourceName} not found"); throw new Exception($"Resource {resourceName} not found");
@ -101,7 +125,11 @@ public class PrerequisiteHelper : IPrerequisiteHelper
/// <summary> /// <summary>
/// Extracts all embedded resources starting with resourceDir to outputDirectory /// Extracts all embedded resources starting with resourceDir to outputDirectory
/// </summary> /// </summary>
private async Task ExtractAllEmbeddedResources(string resourceDir, string outputDirectory, string resourceRoot = "StabilityMatrix.Assets.") private async Task ExtractAllEmbeddedResources(
string resourceDir,
string outputDirectory,
string resourceRoot = "StabilityMatrix.Assets."
)
{ {
Directory.CreateDirectory(outputDirectory); Directory.CreateDirectory(outputDirectory);
// Unpack from embedded resources // Unpack from embedded resources
@ -117,12 +145,15 @@ public class PrerequisiteHelper : IPrerequisiteHelper
// from "StabilityMatrix.Assets.Python310.libssl-1_1.dll" // from "StabilityMatrix.Assets.Python310.libssl-1_1.dll"
// to "Python310\libssl-1_1.dll" // to "Python310\libssl-1_1.dll"
var fileExt = Path.GetExtension(resourceName); var fileExt = Path.GetExtension(resourceName);
var fileName = resourceName var fileName =
resourceName
.Replace(fileExt, "") .Replace(fileExt, "")
.Replace(resourceRoot, "") .Replace(resourceRoot, "")
.Replace(".", Path.DirectorySeparatorChar.ToString()) + fileExt; .Replace(".", Path.DirectorySeparatorChar.ToString()) + fileExt;
// Unpack resource // Unpack resource
await using var resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)!; await using var resourceStream = Assembly
.GetExecutingAssembly()
.GetManifestResourceStream(resourceName)!;
var outputFilePath = Path.Combine(outputDirectory, fileName); var outputFilePath = Path.Combine(outputDirectory, fileName);
// Create missing directories // Create missing directories
var outputDir = Path.GetDirectoryName(outputFilePath); var outputDir = Path.GetDirectoryName(outputFilePath);
@ -134,13 +165,21 @@ public class PrerequisiteHelper : IPrerequisiteHelper
await resourceStream.CopyToAsync(fileStream); await resourceStream.CopyToAsync(fileStream);
copied.Add(outputFilePath); copied.Add(outputFilePath);
} }
logger.LogInformation("Successfully unpacked {Num} embedded resources: [{Resources}]", total, string.Join(",", copied)); logger.LogInformation(
"Successfully unpacked {Num} embedded resources: [{Resources}]",
total,
string.Join(",", copied)
);
} }
public async Task UnpackResourcesIfNecessary(IProgress<ProgressReport>? progress = null) public async Task UnpackResourcesIfNecessary(IProgress<ProgressReport>? progress = null)
{ {
// Skip if all files exist // Skip if all files exist
if (File.Exists(SevenZipPath) && File.Exists(PythonDllPath) && File.Exists(PythonLibraryZipPath)) if (
File.Exists(SevenZipPath)
&& File.Exists(PythonDllPath)
&& File.Exists(PythonLibraryZipPath)
)
{ {
return; return;
} }
@ -180,13 +219,19 @@ public class PrerequisiteHelper : IPrerequisiteHelper
logger.LogInformation( logger.LogInformation(
"Downloading Python from {PythonLibraryZipUrl} to {PythonLibraryZipPath}", "Downloading Python from {PythonLibraryZipUrl} to {PythonLibraryZipPath}",
PythonDownloadUrl, PythonLibraryZipPath); PythonDownloadUrl,
PythonLibraryZipPath
);
// Cleanup to remove zip if download fails // Cleanup to remove zip if download fails
try try
{ {
// Download python zip // Download python zip
await downloadService.DownloadToFileAsync(PythonDownloadUrl, PythonDownloadPath, progress: progress); await downloadService.DownloadToFileAsync(
PythonDownloadUrl,
PythonDownloadPath,
progress: progress
);
// Verify python hash // Verify python hash
var downloadHash = await FileHash.GetBlake3Async(PythonDownloadPath, progress); var downloadHash = await FileHash.GetBlake3Async(PythonDownloadPath, progress);
@ -194,8 +239,9 @@ public class PrerequisiteHelper : IPrerequisiteHelper
{ {
var fileExists = File.Exists(PythonDownloadPath); var fileExists = File.Exists(PythonDownloadPath);
var fileSize = new FileInfo(PythonDownloadPath).Length; var fileSize = new FileInfo(PythonDownloadPath).Length;
var msg = $"Python download hash mismatch: {downloadHash} != {PythonDownloadHashBlake3} " + var msg =
$"(file exists: {fileExists}, size: {fileSize})"; $"Python download hash mismatch: {downloadHash} != {PythonDownloadHashBlake3} "
+ $"(file exists: {fileExists}, size: {fileSize})";
throw new Exception(msg); throw new Exception(msg);
} }
@ -207,7 +253,10 @@ public class PrerequisiteHelper : IPrerequisiteHelper
if (!File.Exists(SevenZipPath)) if (!File.Exists(SevenZipPath))
{ {
await ExtractEmbeddedResource("StabilityMatrix.Assets.7za.exe", AssetsDir); await ExtractEmbeddedResource("StabilityMatrix.Assets.7za.exe", AssetsDir);
await ExtractEmbeddedResource("StabilityMatrix.Assets.7za - LICENSE.txt", AssetsDir); await ExtractEmbeddedResource(
"StabilityMatrix.Assets.7za - LICENSE.txt",
AssetsDir
);
} }
// Delete existing python dir // Delete existing python dir
@ -272,7 +321,11 @@ public class PrerequisiteHelper : IPrerequisiteHelper
if (!File.Exists(PortableGitDownloadPath)) if (!File.Exists(PortableGitDownloadPath))
{ {
await downloadService.DownloadToFileAsync(portableGitUrl, PortableGitDownloadPath, progress: progress); await downloadService.DownloadToFileAsync(
portableGitUrl,
PortableGitDownloadPath,
progress: progress
);
progress?.Report(new ProgressReport(progress: 1f, message: "Git download complete")); progress?.Report(new ProgressReport(progress: 1f, message: "Git download complete"));
} }
@ -284,7 +337,9 @@ public class PrerequisiteHelper : IPrerequisiteHelper
{ {
var registry = Registry.LocalMachine; var registry = Registry.LocalMachine;
var key = registry.OpenSubKey( var key = registry.OpenSubKey(
@"SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\X64", false); @"SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\X64",
false
);
if (key != null) if (key != null)
{ {
var buildId = Convert.ToUInt32(key.GetValue("Bld")); var buildId = Convert.ToUInt32(key.GetValue("Bld"));
@ -296,16 +351,40 @@ public class PrerequisiteHelper : IPrerequisiteHelper
logger.LogInformation("Downloading VC Redist"); logger.LogInformation("Downloading VC Redist");
await downloadService.DownloadToFileAsync(VcRedistDownloadUrl, VcRedistDownloadPath, progress: progress); await downloadService.DownloadToFileAsync(
progress?.Report(new ProgressReport(progress: 1f, message: "Visual C++ download complete", VcRedistDownloadUrl,
type: ProgressType.Download)); VcRedistDownloadPath,
progress: progress
);
progress?.Report(
new ProgressReport(
progress: 1f,
message: "Visual C++ download complete",
type: ProgressType.Download
)
);
logger.LogInformation("Installing VC Redist"); logger.LogInformation("Installing VC Redist");
progress?.Report(new ProgressReport(progress: 0.5f, isIndeterminate: true, type: ProgressType.Generic, message: "Installing prerequisites...")); progress?.Report(
var process = ProcessRunner.StartAnsiProcess(VcRedistDownloadPath, "/install /quiet /norestart"); new ProgressReport(
progress: 0.5f,
isIndeterminate: true,
type: ProgressType.Generic,
message: "Installing prerequisites..."
)
);
var process = ProcessRunner.StartAnsiProcess(
VcRedistDownloadPath,
"/install /quiet /norestart"
);
await process.WaitForExitAsync(); await process.WaitForExitAsync();
progress?.Report(new ProgressReport(progress: 1f, message: "Visual C++ install complete", progress?.Report(
type: ProgressType.Generic)); new ProgressReport(
progress: 1f,
message: "Visual C++ install complete",
type: ProgressType.Generic
)
);
File.Delete(VcRedistDownloadPath); File.Delete(VcRedistDownloadPath);
} }
@ -335,5 +414,4 @@ public class PrerequisiteHelper : IPrerequisiteHelper
settingsManager.AddPathExtension(GitBinPath); settingsManager.AddPathExtension(GitBinPath);
settingsManager.InsertPathExtensions(); settingsManager.InsertPathExtensions();
} }
} }

1
StabilityMatrix.Core/Models/DownloadPackageVersionOptions.cs

@ -5,4 +5,5 @@ public class DownloadPackageVersionOptions
public string BranchName { get; set; } public string BranchName { get; set; }
public string CommitHash { get; set; } public string CommitHash { get; set; }
public string VersionTag { get; set; } public string VersionTag { get; set; }
public bool IsLatest { get; set; }
} }

11
StabilityMatrix.Core/Models/PackageModification/InstallPackageStep.cs

@ -8,12 +8,19 @@ public class InstallPackageStep : IPackageStep
{ {
private readonly BasePackage package; private readonly BasePackage package;
private readonly TorchVersion torchVersion; private readonly TorchVersion torchVersion;
private readonly DownloadPackageVersionOptions versionOptions;
private readonly string installPath; private readonly string installPath;
public InstallPackageStep(BasePackage package, TorchVersion torchVersion, string installPath) public InstallPackageStep(
BasePackage package,
TorchVersion torchVersion,
DownloadPackageVersionOptions versionOptions,
string installPath
)
{ {
this.package = package; this.package = package;
this.torchVersion = torchVersion; this.torchVersion = torchVersion;
this.versionOptions = versionOptions;
this.installPath = installPath; this.installPath = installPath;
} }
@ -25,7 +32,7 @@ public class InstallPackageStep : IPackageStep
} }
await package await package
.InstallPackage(installPath, torchVersion, progress, OnConsoleOutput) .InstallPackage(installPath, torchVersion, versionOptions, progress, OnConsoleOutput)
.ConfigureAwait(false); .ConfigureAwait(false);
} }

11
StabilityMatrix.Core/Models/PackageModification/UpdatePackageStep.cs

@ -9,16 +9,19 @@ public class UpdatePackageStep : IPackageStep
{ {
private readonly ISettingsManager settingsManager; private readonly ISettingsManager settingsManager;
private readonly InstalledPackage installedPackage; private readonly InstalledPackage installedPackage;
private readonly DownloadPackageVersionOptions versionOptions;
private readonly BasePackage basePackage; private readonly BasePackage basePackage;
public UpdatePackageStep( public UpdatePackageStep(
ISettingsManager settingsManager, ISettingsManager settingsManager,
InstalledPackage installedPackage, InstalledPackage installedPackage,
DownloadPackageVersionOptions versionOptions,
BasePackage basePackage BasePackage basePackage
) )
{ {
this.settingsManager = settingsManager; this.settingsManager = settingsManager;
this.installedPackage = installedPackage; this.installedPackage = installedPackage;
this.versionOptions = versionOptions;
this.basePackage = basePackage; this.basePackage = basePackage;
} }
@ -33,7 +36,13 @@ public class UpdatePackageStep : IPackageStep
} }
var updateResult = await basePackage var updateResult = await basePackage
.Update(installedPackage, torchVersion, progress, onConsoleOutput: OnConsoleOutput) .Update(
installedPackage,
torchVersion,
versionOptions,
progress,
onConsoleOutput: OnConsoleOutput
)
.ConfigureAwait(false); .ConfigureAwait(false);
settingsManager.UpdatePackageVersionNumber(installedPackage.Id, updateResult); settingsManager.UpdatePackageVersionNumber(installedPackage.Id, updateResult);

7
StabilityMatrix.Core/Models/Packages/A3WebUI.cs

@ -67,9 +67,9 @@ public class A3WebUI : BaseGitPackage
[SharedOutputType.Extras] = new[] { "outputs/extras-images" }, [SharedOutputType.Extras] = new[] { "outputs/extras-images" },
[SharedOutputType.Saved] = new[] { "log/images" }, [SharedOutputType.Saved] = new[] { "log/images" },
[SharedOutputType.Img2Img] = new[] { "outputs/img2img-images" }, [SharedOutputType.Img2Img] = new[] { "outputs/img2img-images" },
[SharedOutputType.Text2Img] = new[] { "outputs/text2img-images" }, [SharedOutputType.Text2Img] = new[] { "outputs/txt2img-images" },
[SharedOutputType.Img2ImgGrids] = new[] { "outputs/img2img-grids" }, [SharedOutputType.Img2ImgGrids] = new[] { "outputs/img2img-grids" },
[SharedOutputType.Text2ImgGrids] = new[] { "outputs/text2img-grids" } [SharedOutputType.Text2ImgGrids] = new[] { "outputs/txt2img-grids" }
}; };
[SuppressMessage("ReSharper", "ArrangeObjectCreationWhenTypeNotEvident")] [SuppressMessage("ReSharper", "ArrangeObjectCreationWhenTypeNotEvident")]
@ -181,12 +181,11 @@ public class A3WebUI : BaseGitPackage
public override async Task InstallPackage( public override async Task InstallPackage(
string installLocation, string installLocation,
TorchVersion torchVersion, TorchVersion torchVersion,
DownloadPackageVersionOptions versionOptions,
IProgress<ProgressReport>? progress = null, IProgress<ProgressReport>? progress = null,
Action<ProcessOutput>? onConsoleOutput = null Action<ProcessOutput>? onConsoleOutput = null
) )
{ {
await base.InstallPackage(installLocation, torchVersion, progress).ConfigureAwait(false);
progress?.Report(new ProgressReport(-1f, "Setting up venv", isIndeterminate: true)); progress?.Report(new ProgressReport(-1f, "Setting up venv", isIndeterminate: true));
// Setup venv // Setup venv
await using var venvRunner = new PyVenvRunner(Path.Combine(installLocation, "venv")); await using var venvRunner = new PyVenvRunner(Path.Combine(installLocation, "venv"));

190
StabilityMatrix.Core/Models/Packages/BaseGitPackage.cs

@ -170,29 +170,43 @@ public abstract class BaseGitPackage : BasePackage
IProgress<ProgressReport>? progress = null IProgress<ProgressReport>? progress = null
) )
{ {
var downloadUrl = GetDownloadUrl(versionOptions); if (!string.IsNullOrWhiteSpace(versionOptions.VersionTag))
if (!Directory.Exists(DownloadLocation.Replace($"{Name}.zip", "")))
{ {
Directory.CreateDirectory(DownloadLocation.Replace($"{Name}.zip", "")); await PrerequisiteHelper
.RunGit(
null,
null,
"clone",
"--branch",
versionOptions.VersionTag,
GithubUrl,
$"\"{installLocation}\""
)
.ConfigureAwait(false);
} }
else if (!string.IsNullOrWhiteSpace(versionOptions.BranchName))
await DownloadService {
.DownloadToFileAsync(downloadUrl, DownloadLocation, progress: progress) await PrerequisiteHelper
.RunGit(
null,
null,
"clone",
"--branch",
versionOptions.BranchName,
GithubUrl,
$"\"{installLocation}\""
)
.ConfigureAwait(false); .ConfigureAwait(false);
progress?.Report(new ProgressReport(100, message: "Download Complete"));
} }
public override async Task InstallPackage( if (!versionOptions.IsLatest && !string.IsNullOrWhiteSpace(versionOptions.CommitHash))
string installLocation,
TorchVersion torchVersion,
IProgress<ProgressReport>? progress = null,
Action<ProcessOutput>? onConsoleOutput = null
)
{ {
await UnzipPackage(installLocation, progress).ConfigureAwait(false); await PrerequisiteHelper
File.Delete(DownloadLocation); .RunGit(installLocation, null, "checkout", versionOptions.CommitHash)
.ConfigureAwait(false);
}
progress?.Report(new ProgressReport(100, message: "Download Complete"));
} }
protected Task UnzipPackage(string installLocation, IProgress<ProgressReport>? progress = null) protected Task UnzipPackage(string installLocation, IProgress<ProgressReport>? progress = null)
@ -279,6 +293,7 @@ public abstract class BaseGitPackage : BasePackage
public override async Task<InstalledPackageVersion> Update( public override async Task<InstalledPackageVersion> Update(
InstalledPackage installedPackage, InstalledPackage installedPackage,
TorchVersion torchVersion, TorchVersion torchVersion,
DownloadPackageVersionOptions versionOptions,
IProgress<ProgressReport>? progress = null, IProgress<ProgressReport>? progress = null,
bool includePrerelease = false, bool includePrerelease = false,
Action<ProcessOutput>? onConsoleOutput = null Action<ProcessOutput>? onConsoleOutput = null
@ -287,47 +302,146 @@ public abstract class BaseGitPackage : BasePackage
if (installedPackage.Version == null) if (installedPackage.Version == null)
throw new NullReferenceException("Version is null"); throw new NullReferenceException("Version is null");
if (installedPackage.Version.IsReleaseMode) if (!Directory.Exists(Path.Combine(installedPackage.FullPath!, ".git")))
{ {
var releases = await GetAllReleases().ConfigureAwait(false); Logger.Info("not a git repo, initializing...");
var latestRelease = releases.First(x => includePrerelease || !x.Prerelease); progress?.Report(
new ProgressReport(-1f, "Initializing git repo", isIndeterminate: true)
);
await PrerequisiteHelper
.RunGit(installedPackage.FullPath!, onConsoleOutput, "init")
.ConfigureAwait(false);
await PrerequisiteHelper
.RunGit(
installedPackage.FullPath!,
onConsoleOutput,
"remote",
"add",
"origin",
GithubUrl
)
.ConfigureAwait(false);
}
await DownloadPackage( if (!string.IsNullOrWhiteSpace(versionOptions.VersionTag))
installedPackage.FullPath, {
new DownloadPackageVersionOptions { VersionTag = latestRelease.TagName }, progress?.Report(new ProgressReport(-1f, "Fetching tags...", isIndeterminate: true));
progress await PrerequisiteHelper
.RunGit(installedPackage.FullPath!, onConsoleOutput, "fetch", "--tags")
.ConfigureAwait(false);
progress?.Report(
new ProgressReport(
-1f,
$"Checking out {versionOptions.VersionTag}",
isIndeterminate: true
)
);
await PrerequisiteHelper
.RunGit(
installedPackage.FullPath!,
onConsoleOutput,
"checkout",
versionOptions.VersionTag,
"--force"
) )
.ConfigureAwait(false); .ConfigureAwait(false);
await InstallPackage(installedPackage.FullPath, torchVersion, progress, onConsoleOutput) await InstallPackage(
installedPackage.FullPath!,
torchVersion,
new DownloadPackageVersionOptions
{
VersionTag = versionOptions.VersionTag,
IsLatest = versionOptions.IsLatest
},
progress,
onConsoleOutput
)
.ConfigureAwait(false); .ConfigureAwait(false);
return new InstalledPackageVersion { InstalledReleaseVersion = latestRelease.TagName }; return new InstalledPackageVersion
{
InstalledReleaseVersion = versionOptions.VersionTag
};
} }
// Commit mode // fetch
var allCommits = await GetAllCommits(installedPackage.Version.InstalledBranch) progress?.Report(new ProgressReport(-1f, "Fetching data...", isIndeterminate: true));
await PrerequisiteHelper
.RunGit(installedPackage.FullPath!, onConsoleOutput, "fetch")
.ConfigureAwait(false);
if (versionOptions.IsLatest)
{
// checkout
progress?.Report(
new ProgressReport(
-1f,
$"Checking out {installedPackage.Version.InstalledBranch}...",
isIndeterminate: true
)
);
await PrerequisiteHelper
.RunGit(
installedPackage.FullPath!,
onConsoleOutput,
"checkout",
versionOptions.BranchName,
"--force"
)
.ConfigureAwait(false); .ConfigureAwait(false);
var latestCommit = allCommits?.First();
if (latestCommit is null || string.IsNullOrEmpty(latestCommit.Sha)) // pull
progress?.Report(new ProgressReport(-1f, "Pulling changes...", isIndeterminate: true));
await PrerequisiteHelper
.RunGit(
installedPackage.FullPath!,
onConsoleOutput,
"pull",
"origin",
installedPackage.Version.InstalledBranch
)
.ConfigureAwait(false);
}
else
{ {
throw new Exception("No commits found for branch"); // checkout
progress?.Report(
new ProgressReport(
-1f,
$"Checking out {installedPackage.Version.InstalledBranch}...",
isIndeterminate: true
)
);
await PrerequisiteHelper
.RunGit(
installedPackage.FullPath!,
onConsoleOutput,
"checkout",
versionOptions.CommitHash,
"--force"
)
.ConfigureAwait(false);
} }
await DownloadPackage( await InstallPackage(
installedPackage.FullPath, installedPackage.FullPath,
new DownloadPackageVersionOptions { CommitHash = latestCommit.Sha }, torchVersion,
progress new DownloadPackageVersionOptions
{
CommitHash = versionOptions.CommitHash,
IsLatest = versionOptions.IsLatest
},
progress,
onConsoleOutput
) )
.ConfigureAwait(false); .ConfigureAwait(false);
await InstallPackage(installedPackage.FullPath, torchVersion, progress, onConsoleOutput)
.ConfigureAwait(false);
return new InstalledPackageVersion return new InstalledPackageVersion
{ {
InstalledBranch = installedPackage.Version.InstalledBranch, InstalledBranch = versionOptions.BranchName,
InstalledCommitSha = latestCommit.Sha InstalledCommitSha = versionOptions.CommitHash
}; };
} }

2
StabilityMatrix.Core/Models/Packages/BasePackage.cs

@ -49,6 +49,7 @@ public abstract class BasePackage
public abstract Task InstallPackage( public abstract Task InstallPackage(
string installLocation, string installLocation,
TorchVersion torchVersion, TorchVersion torchVersion,
DownloadPackageVersionOptions versionOptions,
IProgress<ProgressReport>? progress = null, IProgress<ProgressReport>? progress = null,
Action<ProcessOutput>? onConsoleOutput = null Action<ProcessOutput>? onConsoleOutput = null
); );
@ -65,6 +66,7 @@ public abstract class BasePackage
public abstract Task<InstalledPackageVersion> Update( public abstract Task<InstalledPackageVersion> Update(
InstalledPackage installedPackage, InstalledPackage installedPackage,
TorchVersion torchVersion, TorchVersion torchVersion,
DownloadPackageVersionOptions versionOptions,
IProgress<ProgressReport>? progress = null, IProgress<ProgressReport>? progress = null,
bool includePrerelease = false, bool includePrerelease = false,
Action<ProcessOutput>? onConsoleOutput = null Action<ProcessOutput>? onConsoleOutput = null

3
StabilityMatrix.Core/Models/Packages/ComfyUI.cs

@ -151,12 +151,11 @@ public class ComfyUI : BaseGitPackage
public override async Task InstallPackage( public override async Task InstallPackage(
string installLocation, string installLocation,
TorchVersion torchVersion, TorchVersion torchVersion,
DownloadPackageVersionOptions versionOptions,
IProgress<ProgressReport>? progress = null, IProgress<ProgressReport>? progress = null,
Action<ProcessOutput>? onConsoleOutput = null Action<ProcessOutput>? onConsoleOutput = null
) )
{ {
await base.InstallPackage(installLocation, torchVersion, progress).ConfigureAwait(false);
progress?.Report(new ProgressReport(-1, "Setting up venv", isIndeterminate: true)); progress?.Report(new ProgressReport(-1, "Setting up venv", isIndeterminate: true));
// Setup venv // Setup venv
await using var venvRunner = new PyVenvRunner(Path.Combine(installLocation, "venv")); await using var venvRunner = new PyVenvRunner(Path.Combine(installLocation, "venv"));

12
StabilityMatrix.Core/Models/Packages/DankDiffusion.cs

@ -1,6 +1,7 @@
using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Helper;
using StabilityMatrix.Core.Helper.Cache; using StabilityMatrix.Core.Helper.Cache;
using StabilityMatrix.Core.Models.FileInterfaces; using StabilityMatrix.Core.Models.FileInterfaces;
using StabilityMatrix.Core.Models.Progress;
using StabilityMatrix.Core.Processes; using StabilityMatrix.Core.Processes;
using StabilityMatrix.Core.Services; using StabilityMatrix.Core.Services;
@ -32,6 +33,17 @@ public class DankDiffusion : BaseGitPackage
public override string OutputFolderName { get; } public override string OutputFolderName { get; }
public override Task InstallPackage(
string installLocation,
TorchVersion torchVersion,
DownloadPackageVersionOptions versionOptions,
IProgress<ProgressReport>? progress = null,
Action<ProcessOutput>? onConsoleOutput = null
)
{
throw new NotImplementedException();
}
public override Task RunPackage( public override Task RunPackage(
string installedPackagePath, string installedPackagePath,
string command, string command,

2
StabilityMatrix.Core/Models/Packages/Fooocus.cs

@ -98,11 +98,11 @@ public class Fooocus : BaseGitPackage
public override async Task InstallPackage( public override async Task InstallPackage(
string installLocation, string installLocation,
TorchVersion torchVersion, TorchVersion torchVersion,
DownloadPackageVersionOptions versionOptions,
IProgress<ProgressReport>? progress = null, IProgress<ProgressReport>? progress = null,
Action<ProcessOutput>? onConsoleOutput = null Action<ProcessOutput>? onConsoleOutput = null
) )
{ {
await base.InstallPackage(installLocation, torchVersion, progress).ConfigureAwait(false);
var venvRunner = await SetupVenv(installLocation, forceRecreate: true) var venvRunner = await SetupVenv(installLocation, forceRecreate: true)
.ConfigureAwait(false); .ConfigureAwait(false);

5
StabilityMatrix.Core/Models/Packages/FooocusMre.cs

@ -37,6 +37,9 @@ public class FooocusMre : BaseGitPackage
"https://user-images.githubusercontent.com/130458190/265366059-ce430ea0-0995-4067-98dd-cef1d7dc1ab6.png" "https://user-images.githubusercontent.com/130458190/265366059-ce430ea0-0995-4067-98dd-cef1d7dc1ab6.png"
); );
public override string Disclaimer =>
"This package may no longer receive updates from its author. It may be removed from Stability Matrix in the future.";
public override List<LaunchOptionDefinition> LaunchOptions => public override List<LaunchOptionDefinition> LaunchOptions =>
new() new()
{ {
@ -102,11 +105,11 @@ public class FooocusMre : BaseGitPackage
public override async Task InstallPackage( public override async Task InstallPackage(
string installLocation, string installLocation,
TorchVersion torchVersion, TorchVersion torchVersion,
DownloadPackageVersionOptions versionOptions,
IProgress<ProgressReport>? progress = null, IProgress<ProgressReport>? progress = null,
Action<ProcessOutput>? onConsoleOutput = null Action<ProcessOutput>? onConsoleOutput = null
) )
{ {
await base.InstallPackage(installLocation, torchVersion, progress).ConfigureAwait(false);
var venvRunner = await SetupVenv(installLocation, forceRecreate: true) var venvRunner = await SetupVenv(installLocation, forceRecreate: true)
.ConfigureAwait(false); .ConfigureAwait(false);

143
StabilityMatrix.Core/Models/Packages/InvokeAI.cs

@ -1,4 +1,5 @@
using System.Text.RegularExpressions; using System.Globalization;
using System.Text.RegularExpressions;
using NLog; using NLog;
using StabilityMatrix.Core.Extensions; using StabilityMatrix.Core.Extensions;
using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Helper;
@ -143,18 +144,10 @@ public class InvokeAI : BaseGitPackage
return base.GetRecommendedTorchVersion(); return base.GetRecommendedTorchVersion();
} }
public override Task DownloadPackage(
string installLocation,
DownloadPackageVersionOptions downloadOptions,
IProgress<ProgressReport>? progress = null
)
{
return Task.CompletedTask;
}
public override async Task InstallPackage( public override async Task InstallPackage(
string installLocation, string installLocation,
TorchVersion torchVersion, TorchVersion torchVersion,
DownloadPackageVersionOptions versionOptions,
IProgress<ProgressReport>? progress = null, IProgress<ProgressReport>? progress = null,
Action<ProcessOutput>? onConsoleOutput = null Action<ProcessOutput>? onConsoleOutput = null
) )
@ -162,7 +155,10 @@ public class InvokeAI : BaseGitPackage
// Setup venv // Setup venv
progress?.Report(new ProgressReport(-1f, "Setting up venv", isIndeterminate: true)); progress?.Report(new ProgressReport(-1f, "Setting up venv", isIndeterminate: true));
await using var venvRunner = new PyVenvRunner(Path.Combine(installLocation, "venv")); var venvPath = Path.Combine(installLocation, "venv");
var exists = Directory.Exists(venvPath);
await using var venvRunner = new PyVenvRunner(venvPath);
venvRunner.WorkingDirectory = installLocation; venvRunner.WorkingDirectory = installLocation;
await venvRunner.Setup(true, onConsoleOutput).ConfigureAwait(false); await venvRunner.Setup(true, onConsoleOutput).ConfigureAwait(false);
@ -170,29 +166,36 @@ public class InvokeAI : BaseGitPackage
progress?.Report(new ProgressReport(-1f, "Installing Package", isIndeterminate: true)); progress?.Report(new ProgressReport(-1f, "Installing Package", isIndeterminate: true));
var pipCommandArgs = var pipCommandArgs =
"InvokeAI --use-pep517 --extra-index-url https://download.pytorch.org/whl/cpu"; "-e . --use-pep517 --extra-index-url https://download.pytorch.org/whl/cpu";
switch (torchVersion) switch (torchVersion)
{ {
// If has Nvidia Gpu, install CUDA version
case TorchVersion.Cuda: case TorchVersion.Cuda:
await InstallCudaTorch(venvRunner, progress, onConsoleOutput).ConfigureAwait(false);
Logger.Info("Starting InvokeAI install (CUDA)..."); Logger.Info("Starting InvokeAI install (CUDA)...");
pipCommandArgs = pipCommandArgs =
"InvokeAI[xformers] --use-pep517 --extra-index-url https://download.pytorch.org/whl/cu117"; "-e .[xformers] --use-pep517 --extra-index-url https://download.pytorch.org/whl/cu118";
break; break;
// For AMD, Install ROCm version
case TorchVersion.Rocm: case TorchVersion.Rocm:
await venvRunner
.PipInstall(PyVenvRunner.TorchPipInstallArgsRocm542, onConsoleOutput)
.ConfigureAwait(false);
Logger.Info("Starting InvokeAI install (ROCm)..."); Logger.Info("Starting InvokeAI install (ROCm)...");
pipCommandArgs = pipCommandArgs =
"InvokeAI --use-pep517 --extra-index-url https://download.pytorch.org/whl/rocm5.4.2"; "-e . --use-pep517 --extra-index-url https://download.pytorch.org/whl/rocm5.4.2";
break; break;
case TorchVersion.Mps: case TorchVersion.Mps:
// For Apple silicon, use MPS
Logger.Info("Starting InvokeAI install (MPS)..."); Logger.Info("Starting InvokeAI install (MPS)...");
pipCommandArgs = "InvokeAI --use-pep517"; pipCommandArgs = "-e . --use-pep517";
break; break;
} }
await venvRunner.PipInstall(pipCommandArgs, onConsoleOutput).ConfigureAwait(false); await venvRunner
.PipInstall($"{pipCommandArgs}{(exists ? " --upgrade" : "")}", onConsoleOutput)
.ConfigureAwait(false);
await venvRunner await venvRunner
.PipInstall("rich packaging python-dotenv", onConsoleOutput) .PipInstall("rich packaging python-dotenv", onConsoleOutput)
@ -212,73 +215,6 @@ public class InvokeAI : BaseGitPackage
progress?.Report(new ProgressReport(1f, "Done!", isIndeterminate: false)); progress?.Report(new ProgressReport(1f, "Done!", isIndeterminate: false));
} }
public override async Task<InstalledPackageVersion> Update(
InstalledPackage installedPackage,
TorchVersion torchVersion,
IProgress<ProgressReport>? progress = null,
bool includePrerelease = false,
Action<ProcessOutput>? onConsoleOutput = null
)
{
progress?.Report(new ProgressReport(-1f, "Setting up venv", isIndeterminate: true));
if (installedPackage.FullPath is null || installedPackage.Version is null)
{
throw new NullReferenceException("Installed package is missing Path and/or Version");
}
await using var venvRunner = new PyVenvRunner(
Path.Combine(installedPackage.FullPath, "venv")
);
venvRunner.WorkingDirectory = installedPackage.FullPath;
venvRunner.EnvironmentVariables = GetEnvVars(installedPackage.FullPath);
var latestVersion = await GetUpdateVersion(installedPackage).ConfigureAwait(false);
var isReleaseMode = installedPackage.Version.IsReleaseMode;
var downloadUrl = isReleaseMode
? $"https://github.com/invoke-ai/InvokeAI/archive/{latestVersion}.zip"
: $"https://github.com/invoke-ai/InvokeAI/archive/refs/heads/{installedPackage.Version.InstalledBranch}.zip";
progress?.Report(new ProgressReport(-1f, "Installing Package", isIndeterminate: true));
var pipCommandArgs =
$"\"InvokeAI @ {downloadUrl}\" --use-pep517 --extra-index-url https://download.pytorch.org/whl/cpu --upgrade";
switch (torchVersion)
{
// If has Nvidia Gpu, install CUDA version
case TorchVersion.Cuda:
Logger.Info("Starting InvokeAI install (CUDA)...");
pipCommandArgs =
$"\"InvokeAI[xformers] @ {downloadUrl}\" --use-pep517 --extra-index-url https://download.pytorch.org/whl/cu117 --upgrade";
break;
// For AMD, Install ROCm version
case TorchVersion.Rocm:
Logger.Info("Starting InvokeAI install (ROCm)...");
pipCommandArgs =
$"\"InvokeAI @ {downloadUrl}\" --use-pep517 --extra-index-url https://download.pytorch.org/whl/rocm5.4.2 --upgrade";
break;
case TorchVersion.Mps:
// For Apple silicon, use MPS
Logger.Info("Starting InvokeAI install (MPS)...");
pipCommandArgs = $"\"InvokeAI @ {downloadUrl}\" --use-pep517 --upgrade";
break;
}
await venvRunner.PipInstall(pipCommandArgs, onConsoleOutput).ConfigureAwait(false);
progress?.Report(new ProgressReport(1f, "Done!", isIndeterminate: false));
return isReleaseMode
? new InstalledPackageVersion { InstalledReleaseVersion = latestVersion }
: new InstalledPackageVersion
{
InstalledBranch = installedPackage.Version.InstalledBranch,
InstalledCommitSha = latestVersion
};
}
public override Task RunPackage( public override Task RunPackage(
string installedPackagePath, string installedPackagePath,
string command, string command,
@ -286,27 +222,6 @@ public class InvokeAI : BaseGitPackage
Action<ProcessOutput>? onConsoleOutput Action<ProcessOutput>? onConsoleOutput
) => RunInvokeCommand(installedPackagePath, command, arguments, true, onConsoleOutput); ) => RunInvokeCommand(installedPackagePath, command, arguments, true, onConsoleOutput);
private async Task<string> GetUpdateVersion(
InstalledPackage installedPackage,
bool includePrerelease = false
)
{
if (installedPackage.Version == null)
throw new NullReferenceException("Installed package version is null");
if (installedPackage.Version.IsReleaseMode)
{
var releases = await GetAllReleases().ConfigureAwait(false);
var latestRelease = releases.First(x => includePrerelease || !x.Prerelease);
return latestRelease.TagName;
}
var allCommits = await GetAllCommits(installedPackage.Version.InstalledBranch)
.ConfigureAwait(false);
var latestCommit = allCommits.First();
return latestCommit.Sha;
}
private async Task RunInvokeCommand( private async Task RunInvokeCommand(
string installedPackagePath, string installedPackagePath,
string command, string command,
@ -320,7 +235,6 @@ public class InvokeAI : BaseGitPackage
arguments = command switch arguments = command switch
{ {
"invokeai-configure" => "--yes --skip-sd-weights", "invokeai-configure" => "--yes --skip-sd-weights",
"invokeai-model-install" => "--yes",
_ => arguments _ => arguments
}; };
@ -343,6 +257,21 @@ public class InvokeAI : BaseGitPackage
// above the minimum in invokeai.frontend.install.widgets // above the minimum in invokeai.frontend.install.widgets
var code = $""" var code = $"""
try:
import os
import shutil
from invokeai.frontend.install import widgets
_min_cols = widgets.MIN_COLS
_min_lines = widgets.MIN_LINES
static_size_fn = lambda: os.terminal_size((_min_cols, _min_lines))
shutil.get_terminal_size = static_size_fn
widgets.get_terminal_size = static_size_fn
except Exception as e:
import warnings
warnings.warn('Could not patch terminal size for InvokeAI' + str(e))
import sys import sys
from {split[0]} import {split[1]} from {split[0]} import {split[1]}
sys.exit({split[1]}()) sys.exit({split[1]}())

7
StabilityMatrix.Core/Models/Packages/StableDiffusionUx.cs

@ -68,9 +68,9 @@ public class StableDiffusionUx : BaseGitPackage
[SharedOutputType.Extras] = new[] { "outputs/extras-images" }, [SharedOutputType.Extras] = new[] { "outputs/extras-images" },
[SharedOutputType.Saved] = new[] { "log/images" }, [SharedOutputType.Saved] = new[] { "log/images" },
[SharedOutputType.Img2Img] = new[] { "outputs/img2img-images" }, [SharedOutputType.Img2Img] = new[] { "outputs/img2img-images" },
[SharedOutputType.Text2Img] = new[] { "outputs/text2img-images" }, [SharedOutputType.Text2Img] = new[] { "outputs/txt2img-images" },
[SharedOutputType.Img2ImgGrids] = new[] { "outputs/img2img-grids" }, [SharedOutputType.Img2ImgGrids] = new[] { "outputs/img2img-grids" },
[SharedOutputType.Text2ImgGrids] = new[] { "outputs/text2img-grids" } [SharedOutputType.Text2ImgGrids] = new[] { "outputs/txt2img-grids" }
}; };
[SuppressMessage("ReSharper", "ArrangeObjectCreationWhenTypeNotEvident")] [SuppressMessage("ReSharper", "ArrangeObjectCreationWhenTypeNotEvident")]
@ -180,12 +180,11 @@ public class StableDiffusionUx : BaseGitPackage
public override async Task InstallPackage( public override async Task InstallPackage(
string installLocation, string installLocation,
TorchVersion torchVersion, TorchVersion torchVersion,
DownloadPackageVersionOptions versionOptions,
IProgress<ProgressReport>? progress = null, IProgress<ProgressReport>? progress = null,
Action<ProcessOutput>? onConsoleOutput = null Action<ProcessOutput>? onConsoleOutput = null
) )
{ {
await base.InstallPackage(installLocation, torchVersion, progress).ConfigureAwait(false);
progress?.Report(new ProgressReport(-1f, "Setting up venv", isIndeterminate: true)); progress?.Report(new ProgressReport(-1f, "Setting up venv", isIndeterminate: true));
// Setup venv // Setup venv
await using var venvRunner = new PyVenvRunner(Path.Combine(installLocation, "venv")); await using var venvRunner = new PyVenvRunner(Path.Combine(installLocation, "venv"));

2
StabilityMatrix.Core/Models/Packages/UnknownPackage.cs

@ -41,6 +41,7 @@ public class UnknownPackage : BasePackage
public override Task InstallPackage( public override Task InstallPackage(
string installLocation, string installLocation,
TorchVersion torchVersion, TorchVersion torchVersion,
DownloadPackageVersionOptions versionOptions,
IProgress<ProgressReport>? progress = null, IProgress<ProgressReport>? progress = null,
Action<ProcessOutput>? onConsoleOutput = null Action<ProcessOutput>? onConsoleOutput = null
) )
@ -120,6 +121,7 @@ public class UnknownPackage : BasePackage
public override Task<InstalledPackageVersion> Update( public override Task<InstalledPackageVersion> Update(
InstalledPackage installedPackage, InstalledPackage installedPackage,
TorchVersion torchVersion, TorchVersion torchVersion,
DownloadPackageVersionOptions versionOptions,
IProgress<ProgressReport>? progress = null, IProgress<ProgressReport>? progress = null,
bool includePrerelease = false, bool includePrerelease = false,
Action<ProcessOutput>? onConsoleOutput = null Action<ProcessOutput>? onConsoleOutput = null

20
StabilityMatrix.Core/Models/Packages/VladAutomatic.cs

@ -174,6 +174,7 @@ public class VladAutomatic : BaseGitPackage
public override async Task InstallPackage( public override async Task InstallPackage(
string installLocation, string installLocation,
TorchVersion torchVersion, TorchVersion torchVersion,
DownloadPackageVersionOptions versionOptions,
IProgress<ProgressReport>? progress = null, IProgress<ProgressReport>? progress = null,
Action<ProcessOutput>? onConsoleOutput = null Action<ProcessOutput>? onConsoleOutput = null
) )
@ -238,6 +239,7 @@ public class VladAutomatic : BaseGitPackage
await PrerequisiteHelper await PrerequisiteHelper
.RunGit( .RunGit(
installDir.Parent ?? "", installDir.Parent ?? "",
null,
"clone", "clone",
"https://github.com/vladmandic/automatic", "https://github.com/vladmandic/automatic",
installDir.Name installDir.Name
@ -245,7 +247,7 @@ public class VladAutomatic : BaseGitPackage
.ConfigureAwait(false); .ConfigureAwait(false);
await PrerequisiteHelper await PrerequisiteHelper
.RunGit(installLocation, "checkout", downloadOptions.CommitHash) .RunGit(installLocation, null, "checkout", downloadOptions.CommitHash)
.ConfigureAwait(false); .ConfigureAwait(false);
} }
else if (!string.IsNullOrWhiteSpace(downloadOptions.BranchName)) else if (!string.IsNullOrWhiteSpace(downloadOptions.BranchName))
@ -253,6 +255,7 @@ public class VladAutomatic : BaseGitPackage
await PrerequisiteHelper await PrerequisiteHelper
.RunGit( .RunGit(
installDir.Parent ?? "", installDir.Parent ?? "",
null,
"clone", "clone",
"-b", "-b",
downloadOptions.BranchName, downloadOptions.BranchName,
@ -301,16 +304,12 @@ public class VladAutomatic : BaseGitPackage
public override async Task<InstalledPackageVersion> Update( public override async Task<InstalledPackageVersion> Update(
InstalledPackage installedPackage, InstalledPackage installedPackage,
TorchVersion torchVersion, TorchVersion torchVersion,
DownloadPackageVersionOptions versionOptions,
IProgress<ProgressReport>? progress = null, IProgress<ProgressReport>? progress = null,
bool includePrerelease = false, bool includePrerelease = false,
Action<ProcessOutput>? onConsoleOutput = null Action<ProcessOutput>? onConsoleOutput = null
) )
{ {
if (installedPackage.Version is null)
{
throw new Exception("Version is null");
}
progress?.Report( progress?.Report(
new ProgressReport( new ProgressReport(
-1f, -1f,
@ -321,7 +320,12 @@ public class VladAutomatic : BaseGitPackage
); );
await PrerequisiteHelper await PrerequisiteHelper
.RunGit(installedPackage.FullPath, "checkout", installedPackage.Version.InstalledBranch) .RunGit(
installedPackage.FullPath,
onConsoleOutput,
"checkout",
versionOptions.BranchName
)
.ConfigureAwait(false); .ConfigureAwait(false);
var venvRunner = new PyVenvRunner(Path.Combine(installedPackage.FullPath!, "venv")); var venvRunner = new PyVenvRunner(Path.Combine(installedPackage.FullPath!, "venv"));
@ -340,7 +344,7 @@ public class VladAutomatic : BaseGitPackage
return new InstalledPackageVersion return new InstalledPackageVersion
{ {
InstalledBranch = installedPackage.Version.InstalledBranch, InstalledBranch = versionOptions.BranchName,
InstalledCommitSha = output.Replace(Environment.NewLine, "").Replace("\n", "") InstalledCommitSha = output.Replace(Environment.NewLine, "").Replace("\n", "")
}; };
} }

3
StabilityMatrix.Core/Models/Packages/VoltaML.cs

@ -146,12 +146,11 @@ public class VoltaML : BaseGitPackage
public override async Task InstallPackage( public override async Task InstallPackage(
string installLocation, string installLocation,
TorchVersion torchVersion, TorchVersion torchVersion,
DownloadPackageVersionOptions versionOptions,
IProgress<ProgressReport>? progress = null, IProgress<ProgressReport>? progress = null,
Action<ProcessOutput>? onConsoleOutput = null Action<ProcessOutput>? onConsoleOutput = null
) )
{ {
await base.InstallPackage(installLocation, torchVersion, progress).ConfigureAwait(false);
// Setup venv // Setup venv
progress?.Report(new ProgressReport(-1, "Setting up venv", isIndeterminate: true)); progress?.Report(new ProgressReport(-1, "Setting up venv", isIndeterminate: true));
await using var venvRunner = new PyVenvRunner(Path.Combine(installLocation, "venv")); await using var venvRunner = new PyVenvRunner(Path.Combine(installLocation, "venv"));

Loading…
Cancel
Save