Skip to content

Commit

Permalink
(maint) move find_package to NuGetList
Browse files Browse the repository at this point in the history
Listing or searching using some of NuGet.Core components should be in
a common place - that is NuGetList.cs currently. Move the optimized
method to where it can be used everywhere.

Additionally, add smarts to the method to determine if one is using the
older methods of search when repository optimizations are not available.
  • Loading branch information
ferventcoder committed May 26, 2019
1 parent da91eb3 commit 754cd0a
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 93 deletions.
96 changes: 95 additions & 1 deletion src/chocolatey/infrastructure.app/nuget/NugetList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace chocolatey.infrastructure.app.nuget
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;

using NuGet;
Expand Down Expand Up @@ -142,8 +143,101 @@ private static IQueryable<IPackage> execute_package_search(ChocolateyConfigurati
: results;

return results;
}
}

/// <summary>
/// Searches for packages that are available based on name and other options
/// </summary>
/// <param name="packageName">Name of package to search for</param>
/// <param name="version">Optional version to search for</param>
/// <param name="config">Chocolatey configuration used to help supply the search parameters</param>
/// <param name="repository">Repository (aggregate for multiple) to search in</param>
/// <returns>One result or nothing</returns>
public static IPackage find_package(string packageName, SemanticVersion version, ChocolateyConfiguration config, IPackageRepository repository)
{
// use old method when newer method causes issues
if (!config.Features.UsePackageRepositoryOptimizations) return repository.FindPackage(packageName, version, config.Prerelease, allowUnlisted: false);

packageName = packageName.to_string().ToLower(CultureInfo.CurrentCulture);
// find the package based on version using older method
if (version != null) return repository.FindPackage(packageName, version, config.Prerelease, allowUnlisted: false);

// we should always be using an aggregate repository
var aggregateRepository = repository as AggregateRepository;
if (aggregateRepository != null)
{
var packageResults = new List<IPackage>();

foreach (var packageRepository in aggregateRepository.Repositories.or_empty_list_if_null())
{
try
{
"chocolatey".Log().Debug("Using '" + packageRepository.Source + "'.");
"chocolatey".Log().Debug("- Supports prereleases? '" + packageRepository.SupportsPrereleasePackages + "'.");
"chocolatey".Log().Debug("- Is ServiceBased? '" + (packageRepository is IServiceBasedRepository) + "'.");

// search based on lower case id - similar to PackageRepositoryExtensions.FindPackagesByIdCore()
IQueryable<IPackage> combinedResults = packageRepository.GetPackages().Where(x => x.Id.ToLower() == packageName);

if (config.Prerelease && packageRepository.SupportsPrereleasePackages)
{
combinedResults = combinedResults.Where(p => p.IsAbsoluteLatestVersion);
}
else
{
combinedResults = combinedResults.Where(p => p.IsLatestVersion);
}

if (!(packageRepository is IServiceBasedRepository))
{
combinedResults = combinedResults
.Where(PackageExtensions.IsListed)
.Where(p => config.Prerelease || p.IsReleaseVersion())
.distinct_last(PackageEqualityComparer.Id, PackageComparer.Version)
.AsQueryable();
}

var packageRepositoryResults = combinedResults.ToList();
if (packageRepositoryResults.Count() != 0)
{
"chocolatey".Log().Debug("Package '{0}' found on source '{1}'".format_with(packageName, packageRepository.Source));
packageResults.AddRange(packageRepositoryResults);
}
}
catch (Exception e)
{
"chocolatey".Log().Warn("Error retrieving packages from source '{0}':{1} {2}".format_with(packageRepository.Source, Environment.NewLine, e.Message));
}
}

// get only one result, should be the latest - similar to TryFindLatestPackageById
return packageResults.OrderByDescending(x => x.Version).FirstOrDefault();
}

// search based on lower case id - similar to PackageRepositoryExtensions.FindPackagesByIdCore()
IQueryable<IPackage> results = repository.GetPackages().Where(x => x.Id.ToLower() == packageName);

if (config.Prerelease && repository.SupportsPrereleasePackages)
{
results = results.Where(p => p.IsAbsoluteLatestVersion);
}
else
{
results = results.Where(p => p.IsLatestVersion);
}

if (!(repository is IServiceBasedRepository))
{
results = results
.Where(PackageExtensions.IsListed)
.Where(p => config.Prerelease || p.IsReleaseVersion())
.distinct_last(PackageEqualityComparer.Id, PackageComparer.Version)
.AsQueryable();
}

// get only one result, should be the latest - similar to TryFindLatestPackageById
return results.ToList().OrderByDescending(x => x.Version).FirstOrDefault();
}

}

Expand Down
96 changes: 4 additions & 92 deletions src/chocolatey/infrastructure.app/services/NugetService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -471,9 +471,7 @@ public virtual ConcurrentDictionary<string, PackageResult> install_run(Chocolate
continue;
}

IPackage availablePackage = config.Features.UsePackageRepositoryOptimizations ?
find_package(packageName, version, config, packageManager.SourceRepository)
: packageManager.SourceRepository.FindPackage(packageName, version, config.Prerelease, allowUnlisted: false);
IPackage availablePackage = NugetList.find_package(packageName, version, config, packageManager.SourceRepository);

if (availablePackage == null)
{
Expand Down Expand Up @@ -695,9 +693,8 @@ public virtual ConcurrentDictionary<string, PackageResult> upgrade_run(Chocolate
config.Prerelease = true;
}

IPackage availablePackage = config.Features.UsePackageRepositoryOptimizations ?
find_package(packageName, version, config, packageManager.SourceRepository)
: packageManager.SourceRepository.FindPackage(packageName, version, config.Prerelease, allowUnlisted: false);
IPackage availablePackage = NugetList.find_package(packageName, version, config, packageManager.SourceRepository);


config.Prerelease = originalPrerelease;

Expand Down Expand Up @@ -924,9 +921,7 @@ public virtual ConcurrentDictionary<string, PackageResult> get_outdated(Chocolat
}

SemanticVersion version = null;
var latestPackage = config.Features.UsePackageRepositoryOptimizations ?
find_package(packageName, null, config, packageManager.SourceRepository)
: packageManager.SourceRepository.FindPackage(packageName, version, config.Prerelease, allowUnlisted: false);
var latestPackage = NugetList.find_package(packageName, null, config, packageManager.SourceRepository);

if (latestPackage == null)
{
Expand Down Expand Up @@ -954,89 +949,6 @@ public virtual ConcurrentDictionary<string, PackageResult> get_outdated(Chocolat
return outdatedPackages;
}

private IPackage find_package(string packageName, SemanticVersion version, ChocolateyConfiguration config, IPackageRepository repository)
{
packageName = packageName.to_string().ToLower(CultureInfo.CurrentCulture);
// find the package based on version
if (version != null) return repository.FindPackage(packageName, version, config.Prerelease, allowUnlisted: false);

// we should always be using an aggregate repository
var aggregateRepository = repository as AggregateRepository;
if (aggregateRepository != null)
{
var packageResults = new List<IPackage>();

foreach (var packageRepository in aggregateRepository.Repositories.or_empty_list_if_null())
{
try
{
this.Log().Debug("Using '" + packageRepository.Source + "'.");
this.Log().Debug("- Supports prereleases? '" + packageRepository.SupportsPrereleasePackages + "'.");
this.Log().Debug("- Is ServiceBased? '" + (packageRepository is IServiceBasedRepository) + "'.");

// search based on lower case id - similar to PackageRepositoryExtensions.FindPackagesByIdCore()
IQueryable<IPackage> combinedResults = packageRepository.GetPackages().Where(x => x.Id.ToLower() == packageName);

if (config.Prerelease && packageRepository.SupportsPrereleasePackages)
{
combinedResults = combinedResults.Where(p => p.IsAbsoluteLatestVersion);
}
else
{
combinedResults = combinedResults.Where(p => p.IsLatestVersion);
}

if (!(packageRepository is IServiceBasedRepository))
{
combinedResults = combinedResults
.Where(PackageExtensions.IsListed)
.Where(p => config.Prerelease || p.IsReleaseVersion())
.distinct_last(PackageEqualityComparer.Id, PackageComparer.Version)
.AsQueryable();
}

var packageRepositoryResults = combinedResults.ToList();
if (packageRepositoryResults.Count() != 0)
{
this.Log().Debug("Package '{0}' found on source '{1}'".format_with(packageName, packageRepository.Source));
packageResults.AddRange(packageRepositoryResults);
}
}
catch (Exception e)
{
this.Log().Warn("Error retrieving packages from source '{0}':{1} {2}".format_with(packageRepository.Source, Environment.NewLine, e.Message));
}
}

// get only one result, should be the latest - similar to TryFindLatestPackageById
return packageResults.OrderByDescending(x => x.Version).FirstOrDefault();
}

// search based on lower case id - similar to PackageRepositoryExtensions.FindPackagesByIdCore()
IQueryable<IPackage> results = repository.GetPackages().Where(x => x.Id.ToLower() == packageName);

if (config.Prerelease && repository.SupportsPrereleasePackages)
{
results = results.Where(p => p.IsAbsoluteLatestVersion);
}
else
{
results = results.Where(p => p.IsLatestVersion);
}

if (!(repository is IServiceBasedRepository))
{
results = results
.Where(PackageExtensions.IsListed)
.Where(p => config.Prerelease || p.IsReleaseVersion())
.distinct_last(PackageEqualityComparer.Id, PackageComparer.Version)
.AsQueryable();
}

// get only one result, should be the latest - similar to TryFindLatestPackageById
return results.ToList().OrderByDescending(x => x.Version).FirstOrDefault();
}

/// <summary>
/// Sets the configuration for the package upgrade
/// </summary>
Expand Down

0 comments on commit 754cd0a

Please sign in to comment.