Skip to content

Commit

Permalink
(chocolatey#3433) Update how exact versions are looked up
Browse files Browse the repository at this point in the history
This updates the dependency handling of packages to directly look up the
version when an exact version range is being used. This improves
packages that uses such queries, and allows less data being requested
from servers in the cases that we are able to do this determination.
  • Loading branch information
AdmiringWorm committed Apr 29, 2024
1 parent 3bed7a6 commit 918f643
Showing 1 changed file with 81 additions and 33 deletions.
114 changes: 81 additions & 33 deletions src/chocolatey/infrastructure.app/nuget/NugetCommon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
using Console = chocolatey.infrastructure.adapters.Console;
using Environment = chocolatey.infrastructure.adapters.Environment;
using System.Collections.Concurrent;
using System.Windows.Forms;

namespace chocolatey.infrastructure.app.nuget
{
Expand Down Expand Up @@ -371,21 +372,36 @@ public static async Task GetPackageDependencies(PackageIdentity package,
ISet<PackageDependency> dependencyCache,
ChocolateyConfiguration configuration)
{
if (availablePackages.Contains(package))
foreach (var resource in resources)
{
return;
}
var dependencyInfoResource = resource.DependencyInfoResource;

var dependencyInfoResources = resources.DependencyInfoResources();
if (dependencyInfoResource is null)
{
// We can't lookup any dependencies using this resource.
continue;
}

foreach (var dependencyInfoResource in dependencyInfoResources)
{
SourcePackageDependencyInfo dependencyInfo = null;
var dependencyInfo = availablePackages.FirstOrDefault(p => string.Equals(p.Id, package.Id, StringComparison.OrdinalIgnoreCase) && p.Version == package.Version);

try
{
dependencyInfo = await dependencyInfoResource.ResolvePackage(
package, framework, cacheContext, logger, CancellationToken.None);
if (dependencyInfo is null && !package.HasVersion)
{
var latestPackage = NugetList.FindPackage(package.Id, configuration, logger, cacheContext, new[] { resource });

dependencyInfo = availablePackages.FirstOrDefault(p => string.Equals(p.Id, latestPackage.Identity.Id, StringComparison.OrdinalIgnoreCase) && p.Version == latestPackage.Identity.Version);

if (dependencyInfo is null)
{
dependencyInfo = await dependencyInfoResource.ResolvePackage(latestPackage.Identity, framework, cacheContext, logger, CancellationToken.None);
}
}
else if (dependencyInfo is null)
{
dependencyInfo = await dependencyInfoResource.ResolvePackage(
package, framework, cacheContext, logger, CancellationToken.None);
}
}
catch (AggregateException ex) when (!(ex.InnerException is null))
{
Expand All @@ -402,21 +418,12 @@ public static async Task GetPackageDependencies(PackageIdentity package,
}

availablePackages.Add(dependencyInfo);
foreach (var dependency in dependencyInfo.Dependencies)
{
if (dependencyCache.Contains(dependency))
{
continue;
}

dependencyCache.Add(dependency);
await GetPackageDependencies(
dependency.Id, framework, cacheContext, logger, resources, availablePackages, dependencyCache, configuration);
}
await HandleDependencies(framework, cacheContext, logger, resources, availablePackages, dependencyCache, configuration, dependencyInfo.Dependencies);
}
}

public static async Task GetPackageDependencies(string packageId,
[Obsolete("Use overload requiring a VersionRange being specified. Will be removed in v3.0.0")]
public static Task GetPackageDependencies(string packageId,
NuGetFramework framework,
SourceCacheContext cacheContext,
ILogger logger,
Expand All @@ -425,6 +432,24 @@ public static async Task GetPackageDependencies(string packageId,
ISet<PackageDependency> dependencyCache,
ChocolateyConfiguration configuration)
{
return GetPackageDependencies(packageId, framework, cacheContext, logger, resources, availablePackages, dependencyCache, configuration, VersionRange.All);
}

public static async Task GetPackageDependencies(string packageId,
NuGetFramework framework,
SourceCacheContext cacheContext,
ILogger logger,
IEnumerable<NuGetEndpointResources> resources,
ISet<SourcePackageDependencyInfo> availablePackages,
ISet<PackageDependency> dependencyCache,
ChocolateyConfiguration configuration,
VersionRange versionRange)
{
if (versionRange is null)
{
throw new ArgumentNullException(nameof(versionRange));
}

//if (availablePackages.Contains(packageID)) return;

var dependencyInfoResources = resources.DependencyInfoResources();
Expand Down Expand Up @@ -452,20 +477,13 @@ public static async Task GetPackageDependencies(string packageId,
continue;
}

availablePackages.AddRange(dependencyInfos);
foreach (var dependency in dependencyInfos.SelectMany(p => p.Dependencies))
{
if (dependencyCache.Contains(dependency))
{
continue;
}
availablePackages.AddRange(dependencyInfos.Except(availablePackages));
// We call ToList here, otherwise we have the risk of the packages list being
// modified before we are done with the iteration
dependencyInfos = dependencyInfos.Where(di => versionRange.Satisfies(di.Version)).ToList();

dependencyCache.Add(dependency);

// Recursion is fun, kids
await GetPackageDependencies(
dependency.Id, framework, cacheContext, logger, resources, availablePackages, dependencyCache, configuration);
}
await HandleDependencies(framework, cacheContext, logger, resources, availablePackages, dependencyCache, configuration, dependencyInfos.SelectMany(di => di.Dependencies));
}
}

Expand All @@ -487,5 +505,35 @@ public static async Task GetPackageParents(string packageId,
}
}
}

private static async Task HandleDependencies(
NuGetFramework framework,
SourceCacheContext cacheContext,
ILogger logger,
IEnumerable<NuGetEndpointResources> resources,
ISet<SourcePackageDependencyInfo> availablePackages,
ISet<PackageDependency> dependencyCache, ChocolateyConfiguration configuration,
IEnumerable<PackageDependency> dependencies)
{
foreach (var dependency in dependencies)
{
if (dependencyCache.Contains(dependency))
{
continue;
}

dependencyCache.Add(dependency);

if (dependency.VersionRange.HasLowerAndUpperBounds && dependency.VersionRange.MaxVersion == dependency.VersionRange.MinVersion)
{
await GetPackageDependencies(new PackageIdentity(dependency.Id.ToLower(), dependency.VersionRange.MaxVersion), framework, cacheContext, logger, resources, availablePackages, dependencyCache, configuration);
}
else
{
await GetPackageDependencies(
dependency.Id.ToLower(), framework, cacheContext, logger, resources, availablePackages, dependencyCache, configuration, dependency.VersionRange);
}
}
}
}
}

0 comments on commit 918f643

Please sign in to comment.