Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
0cb3180
improvements to package manager initialization process, separe steps …
marticliment Sep 1, 2025
b136c3e
migrate cargo and dotnet to new initialization
marticliment Sep 1, 2025
8cc8f89
Migrate Pip, PowerShell, PowerShell7
marticliment Sep 1, 2025
2262d0d
Update Chocolatey.cs
marticliment Sep 1, 2025
8416a36
Update Scoop.cs
marticliment Sep 1, 2025
696279e
migrate vcpkg
marticliment Sep 1, 2025
4e1864c
move bootstrap to _performExtraLoadingSteps
marticliment Sep 1, 2025
1e24bdc
migrate WinGet
marticliment Sep 1, 2025
ebcda9d
fix build errors
marticliment Sep 1, 2025
6058b1f
fix small issues
marticliment Sep 1, 2025
a6a8d09
Change how package loaders are accessed
marticliment Sep 2, 2025
9ae9607
Change PackageLoader initialization procedure
marticliment Sep 2, 2025
c77abfa
Less awful instance creation
marticliment Sep 2, 2025
0b2036d
Merge branch 'main' into hot-reload-package-managers
marticliment Sep 2, 2025
059869b
Hot-reload package managers from settings window
marticliment Sep 3, 2025
01d6a7f
allow hot-reloading from package managers homepage
marticliment Sep 3, 2025
cc92a7d
Remove experimental winget toggles from settings, add missing transla…
marticliment Sep 3, 2025
20c1ad2
fix runtime crash due to invalid styles
marticliment Sep 3, 2025
e37dfb8
Add new status badges to Package Managers page
marticliment Sep 4, 2025
e22f816
minor tweaks to PackageManagers settings page
marticliment Sep 4, 2025
2f6675f
fix UI update bug
marticliment Sep 4, 2025
fda67fa
Merge branch 'main' into hot-reload-package-managers
marticliment Sep 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 13 additions & 25 deletions src/UniGetUI.Core.IconStore/IconDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,11 @@ public struct IconCount
public IconCount() { }
}

private static IconDatabase? __instance;

private static IconDatabase? __instance;
public static IconDatabase Instance
{
get
{
if (__instance is null)
{
Logger.Error("IconStore.Instance was not initialized, creating an empty instance.");
InitializeInstance();
return Instance;
}
return __instance;
}
}

public static void InitializeInstance()
{
__instance = new();
get => __instance ??= new();
}

/// <summary>
Expand All @@ -51,10 +37,12 @@ public static void InitializeInstance()
/// </summary>
public async Task LoadIconAndScreenshotsDatabaseAsync()
{
string IconsAndScreenshotsFile = Path.Join(CoreData.UniGetUICacheDirectory_Data, "Icon Database.json");
try
{
Uri DownloadUrl = new("https://github.com/marticliment/UniGetUI/raw/refs/heads/main/WebBasedData/screenshot-database-v2.json");
string IconsAndScreenshotsFile = Path.Join(CoreData.UniGetUICacheDirectory_Data, "Icon Database.json");
Uri DownloadUrl =
new(
"https://github.com/marticliment/UniGetUI/raw/refs/heads/main/WebBasedData/screenshot-database-v2.json");
if (Settings.Get(Settings.K.IconDataBaseURL))
{
DownloadUrl = new Uri(Settings.GetValue(Settings.K.IconDataBaseURL));
Expand All @@ -69,29 +57,29 @@ public async Task LoadIconAndScreenshotsDatabaseAsync()

Logger.ImportantInfo("Downloaded new icons and screenshots successfully!");


if (!File.Exists(IconsAndScreenshotsFile))
{
Logger.Error("Icon Database file not found");
return;
}
}
catch (Exception e)
{
Logger.Warn("Failed to download icons and screenshots");
Logger.Warn(e);
}

if (!File.Exists(IconsAndScreenshotsFile))
{
Logger.Error("Icon Database file not found");
return;
}

// Update data with new cached file
await LoadFromCacheAsync();
}


public async Task LoadFromCacheAsync()
{
string IconsAndScreenshotsFile = Path.Join(CoreData.UniGetUICacheDirectory_Data, "Icon Database.json");
try
{
string IconsAndScreenshotsFile = Path.Join(CoreData.UniGetUICacheDirectory_Data, "Icon Database.json");
IconScreenshotDatabase_v2 JsonData = JsonSerializer.Deserialize<IconScreenshotDatabase_v2>(
await File.ReadAllTextAsync(IconsAndScreenshotsFile),
SerializationHelpers.DefaultOptions
Expand Down
11 changes: 6 additions & 5 deletions src/UniGetUI.Interface.BackgroundApi/BackgroundApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using UniGetUI.Interface.Enums;
using UniGetUI.PackageEngine;
using UniGetUI.PackageEngine.Interfaces;
using UniGetUI.PackageEngine.PackageLoader;

namespace UniGetUI.Interface
{
Expand Down Expand Up @@ -128,18 +129,18 @@ private async Task WIDGETS_V1_GetUpdates(HttpContext context)
return;
}

if (!PEInterface.UpgradablePackagesLoader.IsLoaded && !PEInterface.UpgradablePackagesLoader.IsLoading)
if (!UpgradablePackagesLoader.Instance.IsLoaded && !UpgradablePackagesLoader.Instance.IsLoading)
{
_ = PEInterface.UpgradablePackagesLoader.ReloadPackages();
_ = UpgradablePackagesLoader.Instance.ReloadPackages();
}

while (PEInterface.UpgradablePackagesLoader.IsLoading)
while (UpgradablePackagesLoader.Instance.IsLoading)
{
await Task.Delay(100);
}

StringBuilder packages = new();
foreach (IPackage package in PEInterface.UpgradablePackagesLoader.Packages)
foreach (IPackage package in UpgradablePackagesLoader.Instance.Packages)
{
if (package.Tag is PackageTag.OnQueue or PackageTag.BeingProcessed) continue;

Expand Down Expand Up @@ -247,7 +248,7 @@ private async Task WIDGETS_V2_GetIconForPackage(HttpContext context)

string iconPath = Path.Join(CoreData.UniGetUIExecutableDirectory, "Assets", "Images", "package_color.png");

IPackage? package = PEInterface.UpgradablePackagesLoader.GetPackageForId(packageId, packageSource);
IPackage? package = UpgradablePackagesLoader.Instance.GetPackageForId(packageId, packageSource);
if (package != null)
{
var iconUrl = await Task.Run(package.GetIconUrl);
Expand Down
1 change: 0 additions & 1 deletion src/UniGetUI.PAckageEngine.Interfaces/IPackageManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ public interface IPackageManager
public string Name { get; }
public string DisplayName { get; }
public IManagerSource DefaultSource { get; }
public bool ManagerReady { get; }
public IManagerLogger TaskLogger { get; }
public IMultiSourceHelper SourcesHelper { get; }
public IPackageDetailsHelper DetailsHelper { get; }
Expand Down
8 changes: 3 additions & 5 deletions src/UniGetUI.PackageEngine.Enums/ManagerStatus.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
namespace UniGetUI.PackageEngine.Classes.Manager.ManagerHelpers
{
public struct ManagerStatus
public class ManagerStatus
{
public string Version = "";
public bool Found = false;
public bool Found;
public string ExecutablePath = "";
public string ExecutableCallArgs { get; set; } = "Unset";
public ManagerStatus()
{ }
public string ExecutableCallArgs = "Unset";
}
}
29 changes: 11 additions & 18 deletions src/UniGetUI.PackageEngine.Managers.Cargo/Cargo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,30 +138,23 @@ protected override IReadOnlyList<Package> GetInstalledPackages_UnSafe()
}

public override IReadOnlyList<string> FindCandidateExecutableFiles()
=> CoreTools.WhichMultiple("cargo.exe");

protected override void _loadManagerExecutableFile(out bool found, out string path, out string callArguments)
{
return CoreTools.WhichMultiple("cargo.exe");
var (_found, _executablePath) = GetExecutableFile();
found = _found;
path = _executablePath;
callArguments = "";
}

protected override ManagerStatus LoadManager()
protected override void _loadManagerVersion(out string version)
{
var (found, executablePath) = GetExecutableFile();
if (!found)
{
return new(){ ExecutablePath = executablePath, Found = false, Version = ""};
}

Status = new() { ExecutablePath = executablePath, Found = found, Version = "", ExecutableCallArgs = ""};

using Process p = GetProcess(executablePath, "--version");
using Process p = GetProcess(Status.ExecutablePath, "--version");
p.Start();
string version = p.StandardOutput.ReadToEnd().Trim();
version = p.StandardOutput.ReadToEnd().Trim();
string error = p.StandardError.ReadToEnd();
if (!string.IsNullOrEmpty(error))
{
Logger.Error("cargo version error: " + error);
}

return new() { ExecutablePath = executablePath, Found = found, Version = version, ExecutableCallArgs = ""};
if (!string.IsNullOrEmpty(error)) Logger.Error("cargo version error: " + error);
}

private IReadOnlyList<Package> GetPackages(LoggableTaskType taskType)
Expand Down
38 changes: 19 additions & 19 deletions src/UniGetUI.PackageEngine.Managers.Chocolatey/Chocolatey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ public override IReadOnlyList<string> FindCandidateExecutableFiles()
return candidates;
}

protected override ManagerStatus LoadManager()
protected override void _loadManagerExecutableFile(out bool found, out string path, out string callArguments)
{
if (!Directory.Exists(OldChocoPath))
{
Expand Down Expand Up @@ -293,19 +293,19 @@ protected override ManagerStatus LoadManager()
}
}

var (found, executable) = GetExecutableFile();
ManagerStatus status = new() { Found = found, ExecutablePath = executable, ExecutableCallArgs = "", };

if (!status.Found)
{
return status;
}
var (_found, _path) = GetExecutableFile();
found = _found;
path = _path;
callArguments = "";
}

protected override void _loadManagerVersion(out string version)
{
Process process = new()
{
StartInfo = new ProcessStartInfo
{
FileName = status.ExecutablePath,
FileName = Status.ExecutablePath,
Arguments = "--version " + GetProxyArgument(),
UseShellExecute = false,
RedirectStandardOutput = true,
Expand All @@ -315,19 +315,21 @@ protected override ManagerStatus LoadManager()
}
};
process.Start();
status.Version = process.StandardOutput.ReadToEnd().Trim();
version = process.StandardOutput.ReadToEnd().Trim();
}

protected override void _performExtraLoadingSteps()
{
// If the user is running bundled chocolatey and chocolatey is not in path, add chocolatey to path
if (!Settings.Get(Settings.K.UseSystemChocolatey)
&& !File.Exists("C:\\ProgramData\\Chocolatey\\bin\\choco.exe"))
/* && Settings.Get(Settings.K.ShownWelcomeWizard)) */
if (!Settings.Get(Settings.K.UseSystemChocolatey) && !File.Exists("C:\\ProgramData\\Chocolatey\\bin\\choco.exe"))
/* && Settings.Get(Settings.K.ShownWelcomeWizard)) */
{
string? path = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.User);
if (!path?.Contains(status.ExecutablePath.Replace("\\choco.exe", "\\bin")) ?? false)
if (!path?.Contains(Status.ExecutablePath.Replace("\\choco.exe", "\\bin")) ?? false)
{
Logger.ImportantInfo("Adding chocolatey to path since it was not on path.");
Environment.SetEnvironmentVariable("PATH", $"{status.ExecutablePath.Replace("\\choco.exe", "\\bin")};{path}", EnvironmentVariableTarget.User);
Environment.SetEnvironmentVariable("chocolateyinstall", Path.GetDirectoryName(status.ExecutablePath), EnvironmentVariableTarget.User);
Environment.SetEnvironmentVariable("PATH", $"{Status.ExecutablePath.Replace("\\choco.exe", "\\bin")};{path}", EnvironmentVariableTarget.User);
Environment.SetEnvironmentVariable("chocolateyinstall", Path.GetDirectoryName(Status.ExecutablePath), EnvironmentVariableTarget.User);
}
else
{
Expand All @@ -336,14 +338,12 @@ protected override ManagerStatus LoadManager()
}

// Trick chocolatey into using the wanted installation
var choco_dir = Path.GetDirectoryName(status.ExecutablePath)?.Replace('/', '\\').Trim('\\') ?? "";
var choco_dir = Path.GetDirectoryName(Status.ExecutablePath)?.Replace('/', '\\').Trim('\\') ?? "";
if (choco_dir.EndsWith("bin"))
{
choco_dir = choco_dir[..^3].Trim('\\');
}
Environment.SetEnvironmentVariable("chocolateyinstall", choco_dir, EnvironmentVariableTarget.Process);

return status;
}
}
}
49 changes: 19 additions & 30 deletions src/UniGetUI.PackageEngine.Managers.Dotnet/DotNet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,31 +126,23 @@ protected override IReadOnlyList<Package> _getInstalledPackages_UnSafe()
}

public override IReadOnlyList<string> FindCandidateExecutableFiles()
{
return CoreTools.WhichMultiple("dotnet.exe");
}
=> CoreTools.WhichMultiple("dotnet.exe");

protected override ManagerStatus LoadManager()
protected override void _loadManagerExecutableFile(out bool found, out string path, out string callArguments)
{
var (found, path) = GetExecutableFile();
ManagerStatus status = new()
{
ExecutablePath = path,
Found = found,
ExecutableCallArgs = "tool "
};

if (!status.Found)
{
return status;
}

Process process = new()
var (_found, _path) = GetExecutableFile();
found = _found;
path = _path;
callArguments = "tool ";

// Ensure .NET SDK is installed
if (!found) return;
var process = new Process()
{
StartInfo = new ProcessStartInfo
{
FileName = status.ExecutablePath,
Arguments = status.ExecutableCallArgs + "-h",
FileName = path,
Arguments = callArguments + "-h",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
Expand All @@ -160,17 +152,16 @@ protected override ManagerStatus LoadManager()
};
process.Start();
process.WaitForExit();
if (process.ExitCode != 0)
{
status.Found = false;
return status;
}
found = process.ExitCode is 0;
}

process = new()
protected override void _loadManagerVersion(out string version)
{
var process = new Process()
{
StartInfo = new ProcessStartInfo
{
FileName = status.ExecutablePath,
FileName = Status.ExecutablePath,
Arguments = "--version",
UseShellExecute = false,
RedirectStandardOutput = true,
Expand All @@ -181,9 +172,7 @@ protected override ManagerStatus LoadManager()
};

process.Start();
status.Version = process.StandardOutput.ReadToEnd().Trim();

return status;
version = process.StandardOutput.ReadToEnd().Trim();
}
}
}
Loading
Loading