From d2489d0eb053afd41b421a804cf834bb27821b47 Mon Sep 17 00:00:00 2001 From: Matt Parker <61717342+MattParkerDev@users.noreply.github.com> Date: Sat, 1 Nov 2025 14:00:21 +1000 Subject: [PATCH] get top 100 results across sources --- .../Features/Nuget/NugetClientService.cs | 71 ++++++++++++++++++- .../Features/Nuget/NugetPanel.cs | 3 +- 2 files changed, 70 insertions(+), 4 deletions(-) diff --git a/src/SharpIDE.Application/Features/Nuget/NugetClientService.cs b/src/SharpIDE.Application/Features/Nuget/NugetClientService.cs index 4359809..217d1ed 100644 --- a/src/SharpIDE.Application/Features/Nuget/NugetClientService.cs +++ b/src/SharpIDE.Application/Features/Nuget/NugetClientService.cs @@ -1,17 +1,82 @@ -using NuGet.Configuration; +using NuGet.Common; +using NuGet.Configuration; +using NuGet.Protocol; +using NuGet.Protocol.Core.Types; using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence; namespace SharpIDE.Application.Features.Nuget; +public record IdePackageResult(IPackageSearchMetadata PackageSearchMetadata, List PackageSources); public class NugetClientService { - public async Task Test(string directoryPath) + private readonly bool _includePrerelease = false; + public async Task> GetTop100Results(string directoryPath, CancellationToken cancellationToken = default) { var settings = Settings.LoadDefaultSettings(root: directoryPath); var packageSourceProvider = new PackageSourceProvider(settings); var packageSources = packageSourceProvider.LoadPackageSources().Where(p => p.IsEnabled).ToList(); - // Get top 100 packages across all sources, ordered by download count + var logger = NullLogger.Instance; + var cache = new SourceCacheContext(); + var packagesResult = new List(); + + foreach (var source in packageSources) + { + var repository = Repository.Factory.GetCoreV3(source.Source); + var searchResource = await repository.GetResourceAsync(cancellationToken); + + if (searchResource == null) + continue; + + // Search for top packages (no search term = all) + var results = await searchResource.SearchAsync( + searchTerm: string.Empty, + filters: new SearchFilter(includePrerelease: _includePrerelease), + skip: 0, + take: 100, + log: logger, + cancellationToken: cancellationToken); + + packagesResult.AddRange(results.Select(s => new IdePackageResult(s, [source]))); + } + + // Combine, group, and order by download count + var topPackages = packagesResult + .GroupBy(p => p.PackageSearchMetadata.Identity.Id, StringComparer.OrdinalIgnoreCase) + .Select(g => g.First()) + .OrderByDescending(p => p.PackageSearchMetadata.DownloadCount ?? 0) + .Take(100) + .ToList(); + + // we need to find out if other package sources have the package too + foreach (var package in topPackages) + { + foreach (var source in packageSources.Except(package.PackageSources).ToList()) + { + var repository = Repository.Factory.GetCoreV3(source.Source); + var searchResource = await repository.GetResourceAsync(cancellationToken); + + if (searchResource == null) + continue; + + var packageId = package.PackageSearchMetadata.Identity.Id; + // TODO: Might be faster to use FindPackageByIdResource + var results = await searchResource.SearchAsync( + searchTerm: packageId, + filters: new SearchFilter(includePrerelease: _includePrerelease), + skip: 0, + take: 2, + log: logger, + cancellationToken: cancellationToken); + var foundPackage = results.SingleOrDefault(r => r.Identity.Id.Equals(packageId, StringComparison.OrdinalIgnoreCase)); + if (foundPackage != null) + { + package.PackageSources.Add(source); + } + } + } + + return topPackages; } } diff --git a/src/SharpIDE.Godot/Features/Nuget/NugetPanel.cs b/src/SharpIDE.Godot/Features/Nuget/NugetPanel.cs index 41facd1..3831414 100644 --- a/src/SharpIDE.Godot/Features/Nuget/NugetPanel.cs +++ b/src/SharpIDE.Godot/Features/Nuget/NugetPanel.cs @@ -23,7 +23,8 @@ public partial class NugetPanel : Control _ = Task.GodotRun(async () => { await Task.Delay(300); - await _nugetClientService.Test(Solution!.DirectoryPath); + var result = await _nugetClientService.GetTop100Results(Solution!.DirectoryPath); + ; }); } } \ No newline at end of file