Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Package data lifecycle optimization #2317

Merged
merged 8 commits into from
Jun 15, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,23 @@ public class BaseNuGetDetailsProvider : BasePackageDetailsProvider<PackageManage
{
public BaseNuGetDetailsProvider(BaseNuGet manager) : base(manager) { }

protected override async Task<PackageDetails> GetPackageDetails_Unsafe(Package package)
{
PackageDetails details = new(package);
protected override async Task GetPackageDetails_Unsafe(PackageDetails details)
{
var logger = Manager.TaskLogger.CreateNew(LoggableTaskType.LoadPackageDetails);
try
{

details.ManifestUrl = PackageManifestLoader.GetPackageManifestUrl(package);
string? PackageManifestContents = await PackageManifestLoader.GetPackageManifestContent(package);
details.ManifestUrl = PackageManifestLoader.GetPackageManifestUrl(details.Package);
string? PackageManifestContents = await PackageManifestLoader.GetPackageManifestContent(details.Package);
logger.Log(PackageManifestContents);

if (PackageManifestContents == null)
{
logger.Error($"No manifest content could be loaded for package {package.Id} on manager {package.Manager.Name}, returning empty PackageDetails");
logger.Error($"No manifest content could be loaded for package {details.Package.Id} on manager {details.Package.Manager.Name}, returning empty PackageDetails");
logger.Close(1);
return details;
return;
}

// details.InstallerUrl = new Uri($"https://globalcdn.nuget.org/packages/{package.Id}.{package.Version}.nupkg");
details.InstallerUrl = PackageManifestLoader.GetPackageNuGetPackageUrl(package);
details.InstallerUrl = PackageManifestLoader.GetPackageNuGetPackageUrl(details.Package);
details.InstallerType = CoreTools.Translate("NuPkg (zipped manifest)");
details.InstallerSize = await CoreTools.GetFileSizeAsync(details.InstallerUrl);

Expand Down Expand Up @@ -90,13 +87,13 @@ protected override async Task<PackageDetails> GetPackageDetails_Unsafe(Package p
}

logger.Close(0);
return details;
return;
}
catch (Exception e)
{
logger.Error(e);
logger.Close(1);
return details;
return;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,20 @@ internal class NpmPackageDetailsProvider : BasePackageDetailsProvider<PackageMan
{
public NpmPackageDetailsProvider(Npm manager) : base(manager) { }

protected override async Task<PackageDetails> GetPackageDetails_Unsafe(Package package)
protected override async Task GetPackageDetails_Unsafe(PackageDetails details)
{
PackageDetails details = new(package);
try
{
details.InstallerType = "Tarball";
details.ManifestUrl = new Uri($"https://www.npmjs.com/package/{package.Id}");
details.ReleaseNotesUrl = new Uri($"https://www.npmjs.com/package/{package.Id}?activeTab=versions");
details.ManifestUrl = new Uri($"https://www.npmjs.com/package/{details.Package.Id}");
details.ReleaseNotesUrl = new Uri($"https://www.npmjs.com/package/{details.Package.Id}?activeTab=versions");

using (Process p = new())
{
p.StartInfo = new ProcessStartInfo()
{
FileName = Manager.Status.ExecutablePath,
Arguments = Manager.Properties.ExecutableCallArgs + " info " + package.Id,
Arguments = Manager.Properties.ExecutableCallArgs + " info " + details.Package.Id,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
Expand Down Expand Up @@ -100,7 +99,7 @@ protected override async Task<PackageDetails> GetPackageDetails_Unsafe(Package p
Logger.Error(e);
}

return details;
return;
}

protected override Task<CacheableIcon?> GetPackageIcon_Unsafe(Package package)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,22 @@ internal class PipPackageDetailsProvider : BasePackageDetailsProvider<PackageMan
{
public PipPackageDetailsProvider(Pip manager) : base(manager) { }

protected override async Task<PackageDetails> GetPackageDetails_Unsafe(Package package)
protected override async Task GetPackageDetails_Unsafe(PackageDetails details)
{
PackageDetails details = new(package);

var logger = Manager.TaskLogger.CreateNew(Enums.LoggableTaskType.LoadPackageDetails);

string JsonString;
HttpClient client = new(CoreData.GenericHttpClientParameters);
client.DefaultRequestHeaders.UserAgent.ParseAdd(CoreData.UserAgentString);
JsonString = await client.GetStringAsync($"https://pypi.org/pypi/{package.Id}/json");
JsonString = await client.GetStringAsync($"https://pypi.org/pypi/{details.Package.Id}/json");

JsonObject? RawInfo = JsonObject.Parse(JsonString) as JsonObject;

if(RawInfo == null)
{
logger.Error($"Can't load package info on manager {Manager.Name}, JsonObject? RawInfo was null");
logger.Close(1);
return details;
return;
}

JsonObject? infoNode = RawInfo["info"] as JsonObject;
Expand Down Expand Up @@ -117,7 +115,7 @@ protected override async Task<PackageDetails> GetPackageDetails_Unsafe(Package p
catch (Exception ex) { logger.Error("Can't load installer data: " + ex); }

logger.Close(0);
return details;
return;
}

protected override Task<CacheableIcon?> GetPackageIcon_Unsafe(Package package)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,12 @@ internal class ScoopPackageDetailsProvider : BasePackageDetailsProvider<PackageM
{
public ScoopPackageDetailsProvider(Scoop manager) : base(manager) { }

protected override async Task<PackageDetails> GetPackageDetails_Unsafe(Package package)
protected override async Task GetPackageDetails_Unsafe(PackageDetails details)
{
PackageDetails details = new(package);

if (package.Source.Url != null)
if (details.Package.Source.Url != null)
try
{
details.ManifestUrl = new Uri(package.Source.Url.ToString() + "/blob/master/bucket/" + package.Id + ".json");
details.ManifestUrl = new Uri(details.Package.Source.Url.ToString() + "/blob/master/bucket/" + details.Package.Id + ".json");
}
catch (Exception ex)
{
Expand All @@ -33,7 +31,7 @@ protected override async Task<PackageDetails> GetPackageDetails_Unsafe(Package p
p.StartInfo = new ProcessStartInfo()
{
FileName = Manager.Status.ExecutablePath,
Arguments = Manager.Properties.ExecutableCallArgs + " cat " + package.Source.Name + "/" + package.Id,
Arguments = Manager.Properties.ExecutableCallArgs + " cat " + details.Package.Source.Name + "/" + details.Package.Id,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
Expand Down Expand Up @@ -153,7 +151,7 @@ protected override async Task<PackageDetails> GetPackageDetails_Unsafe(Package p
catch (Exception ex) { logger.AddToStdErr("Can't load notes URL: " + ex); }

logger.Close(0);
return details;
return;

}

Expand Down
70 changes: 30 additions & 40 deletions src/UniGetUI.PackageEngine.Managers.WinGet/WinGetHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ internal interface IWinGetPackageHelper
public Task<Package[]> FindPackages_UnSafe(WinGet ManagerInstance, string query);
public Task<ManagerSource[]> GetSources_UnSafe(WinGet ManagerInstance);
public Task<string[]> GetPackageVersions_Unsafe(WinGet ManagerInstance, Package package);
public Task<PackageDetails> GetPackageDetails_UnSafe(WinGet ManagerInstance, Package package);
public Task GetPackageDetails_UnSafe(WinGet ManagerInstance, PackageDetails details);

}

Expand Down Expand Up @@ -217,58 +217,56 @@ public async Task<string[]> GetPackageVersions_Unsafe(WinGet ManagerInstance, Pa
var versions = NativePackage.AvailableVersions.Select(x => x.Version).ToArray();
foreach (var version in versions) logger.Log(version);
logger.Close(0);
return versions;
return versions ?? [];
}

public async Task<PackageDetails> GetPackageDetails_UnSafe(WinGet ManagerInstance, Package package)
public async Task GetPackageDetails_UnSafe(WinGet ManagerInstance, PackageDetails details)
{
PackageDetails details = new(package);

var logger = ManagerInstance.TaskLogger.CreateNew(LoggableTaskType.LoadPackageDetails);

if (package.Source.Name == "winget")
if (details.Package.Source.Name == "winget")
details.ManifestUrl = new Uri("https://github.com/microsoft/winget-pkgs/tree/master/manifests/"
+ package.Id[0].ToString().ToLower() + "/"
+ package.Id.Split('.')[0] + "/"
+ String.Join("/", (package.Id.Contains('.') ? package.Id.Split('.')[1..] : package.Id.Split('.')))
+ details.Package.Id[0].ToString().ToLower() + "/"
+ details.Package.Id.Split('.')[0] + "/"
+ String.Join("/", (details.Package.Id.Contains('.') ? details.Package.Id.Split('.')[1..] : details.Package.Id.Split('.')))
);
else if (package.Source.Name == "msstore")
details.ManifestUrl = new Uri("https://apps.microsoft.com/detail/" + package.Id);
else if (details.Package.Source.Name == "msstore")
details.ManifestUrl = new Uri("https://apps.microsoft.com/detail/" + details.Package.Id);

// Find the native package for the given Package object
PackageCatalogReference Catalog = WinGetManager.GetPackageCatalogByName(package.Source.Name);
PackageCatalogReference Catalog = WinGetManager.GetPackageCatalogByName(details.Package.Source.Name);
if (Catalog == null)
{
logger.Error("Failed to get catalog " + package.Source.Name + ". Is the package local?");
logger.Error("Failed to get catalog " + details.Package.Source.Name + ". Is the package local?");
logger.Close(1);
return details;
return;
}

// Connect to catalog
Catalog.AcceptSourceAgreements = true;
ConnectResult ConnectResult = await Task.Run(() => Catalog.Connect());
if (ConnectResult.Status != Deployment.ConnectResultStatus.Ok)
{
logger.Error("Failed to connect to catalog " + package.Source.Name);
logger.Error("Failed to connect to catalog " + details.Package.Source.Name);
logger.Close(1);
return details;
return;
}

// Match only the exact same Id
FindPackagesOptions packageMatchFilter = Factory.CreateFindPackagesOptions();
PackageMatchFilter filters = Factory.CreatePackageMatchFilter();
filters.Field = Deployment.PackageMatchField.Id;
filters.Value = package.Id;
filters.Value = details.Package.Id;
filters.Option = Deployment.PackageFieldMatchOption.Equals;
packageMatchFilter.Filters.Add(filters);
packageMatchFilter.ResultLimit = 1;
Task<FindPackagesResult> SearchResult = Task.Run(() => ConnectResult.PackageCatalog.FindPackages(packageMatchFilter));

if (SearchResult.Result == null || SearchResult.Result.Matches == null || SearchResult.Result.Matches.Count() == 0)
{
logger.Error("WinGet: Failed to find package " + package.Id + " in catalog " + package.Source.Name);
logger.Error("WinGet: Failed to find package " + details.Package.Id + " in catalog " + details.Package.Source.Name);
logger.Close(1);
return details;
return;
}

// Get the Native Package
Expand Down Expand Up @@ -312,7 +310,7 @@ public async Task<PackageDetails> GetPackageDetails_UnSafe(WinGet ManagerInstanc
ProcessStartInfo startInfo = new()
{
FileName = Path.Join(CoreData.UniGetUIExecutableDirectory, "winget-cli_x64", "winget.exe"),
Arguments = ManagerInstance.Properties.ExecutableCallArgs + " show --id " + package.Id + " --exact --disable-interactivity --accept-source-agreements --source " + package.Source.Name,
Arguments = ManagerInstance.Properties.ExecutableCallArgs + " show --id " + details.Package.Id + " --exact --disable-interactivity --accept-source-agreements --source " + details.Package.Source.Name,
RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = true,
Expand Down Expand Up @@ -365,7 +363,7 @@ public async Task<PackageDetails> GetPackageDetails_UnSafe(WinGet ManagerInstanc
}
}
logger.Close(0);
return details;
return;
}
}

Expand Down Expand Up @@ -448,28 +446,20 @@ function Print-WinGetPackage {

}

public async Task<PackageDetails> GetPackageDetails_UnSafe(WinGet ManagerInstance, Package package)
public async Task GetPackageDetails_UnSafe(WinGet ManagerInstance, PackageDetails details)
{
PackageDetails details = new(package);

if (package.Source.Name == "winget")
if (details.Package.Source.Name == "winget")
details.ManifestUrl = new Uri("https://github.com/microsoft/winget-pkgs/tree/master/manifests/"
+ package.Id[0].ToString().ToLower() + "/"
+ package.Id.Split('.')[0] + "/"
+ String.Join("/", (package.Id.Contains('.') ? package.Id.Split('.')[1..] : package.Id.Split('.')))
+ details.Package.Id[0].ToString().ToLower() + "/"
+ details.Package.Id.Split('.')[0] + "/"
+ String.Join("/", (details.Package.Id.Contains('.') ? details.Package.Id.Split('.')[1..] : details.Package.Id.Split('.')))
);
else if (package.Source.Name == "msstore")
details.ManifestUrl = new Uri("https://apps.microsoft.com/detail/" + package.Id);
else if (details.Package.Source.Name == "msstore")
details.ManifestUrl = new Uri("https://apps.microsoft.com/detail/" + details.Package.Id);

// Get the output for the best matching locale
Process process = new();
string packageIdentifier;
if (!package.Id.Contains("…"))
packageIdentifier = "--id " + package.Id + " --exact";
else if (!package.Name.Contains("…"))
packageIdentifier = "--name " + package.Id + " --exact";
else
packageIdentifier = "--id " + package.Id;
string packageIdentifier = "--id " + details.Package.Id + " --exact";

List<string> output = new();
bool LocaleFound = true;
Expand Down Expand Up @@ -503,7 +493,7 @@ public async Task<PackageDetails> GetPackageDetails_UnSafe(WinGet ManagerInstanc
if (!LocaleFound)
{
output.Clear();
Logger.Info("Winget could not found culture data for package Id=" + package.Id + " and Culture=" + System.Globalization.CultureInfo.CurrentCulture.ToString() + ". Trying to get data for en-US");
Logger.Info("Winget could not found culture data for package Id=" + details.Package.Id + " and Culture=" + System.Globalization.CultureInfo.CurrentCulture.ToString() + ". Trying to get data for en-US");
process = new Process();
LocaleFound = true;
startInfo = new()
Expand Down Expand Up @@ -536,7 +526,7 @@ public async Task<PackageDetails> GetPackageDetails_UnSafe(WinGet ManagerInstanc
if (!LocaleFound)
{
output.Clear();
Logger.Info("Winget could not found culture data for package Id=" + package.Id + " and Culture=en-US. Loading default");
Logger.Info("Winget could not found culture data for package Id=" + details.Package.Id + " and Culture=en-US. Loading default");
LocaleFound = true;
process = new Process();
startInfo = new()
Expand Down Expand Up @@ -644,7 +634,7 @@ public async Task<PackageDetails> GetPackageDetails_UnSafe(WinGet ManagerInstanc
}
}

return details;
return;
}

public async Task<string[]> GetPackageVersions_Unsafe(WinGet ManagerInstance, Package package)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ protected override async Task<string[]> GetPackageVersions_Unsafe(Package packag
return await WinGetHelper.Instance.GetPackageVersions_Unsafe((WinGet)Manager, package);
}

protected override async Task<PackageDetails> GetPackageDetails_Unsafe(Package package)
protected override async Task GetPackageDetails_Unsafe(PackageDetails details)
{
return await WinGetHelper.Instance.GetPackageDetails_UnSafe((WinGet)Manager, package);
await WinGetHelper.Instance.GetPackageDetails_UnSafe((WinGet)Manager, details);
}

protected override async Task<CacheableIcon?> GetPackageIcon_Unsafe(Package package)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ public BasePackageDetailsProvider(T manager)
Manager = manager;
}

public async Task<PackageDetails> GetPackageDetails(Package package)
public async Task GetPackageDetails(PackageDetails details)
{
return await GetPackageDetails_Unsafe(package);
await GetPackageDetails_Unsafe(details);
}

public async Task<string[]> GetPackageVersions(Package package)
Expand Down Expand Up @@ -83,7 +83,7 @@ public async Task<Uri[]> GetPackageScreenshotsUrl(Package package)
return URIs;
}

protected abstract Task<PackageDetails> GetPackageDetails_Unsafe(Package package);
protected abstract Task GetPackageDetails_Unsafe(PackageDetails details);
protected abstract Task<string[]> GetPackageVersions_Unsafe(Package package);
protected abstract Task<CacheableIcon?> GetPackageIcon_Unsafe(Package package);
protected abstract Task<Uri[]> GetPackageScreenshots_Unsafe(Package package);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ internal interface IPackageDetailsProvider
/// This method is fail-safe and will return a valid but empty PackageDetails object with the package
/// id if an error occurs.
/// </summary>
/// <param name="package"></param>
/// <param name="details">The PackageDetails instance to load</param>
/// <returns>A PackageDetails object</returns>
public abstract Task<PackageDetails> GetPackageDetails(Package package);
public abstract Task GetPackageDetails(PackageDetails details);


/// <summary>
/// Returns the available versions to install for the given package.
Expand Down
Loading
Loading