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 authored and gep13 committed Apr 30, 2024
1 parent 376c692 commit 3a4f6d1
Showing 1 changed file with 80 additions and 33 deletions.
113 changes: 80 additions & 33 deletions src/chocolatey/infrastructure.app/nuget/NugetCommon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -371,21 +371,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 && p.Source == resource.Source);

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 && p.Source == resource.Source);

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 +417,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 +431,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 +476,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 +504,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 3a4f6d1

Please sign in to comment.