Skip to content

Commit

Permalink
(NuGet#9) Alter filter construction for prereleases
Browse files Browse the repository at this point in the history
When the prerelease option is included in the outgoing query, a
decision is made about including either IsLatestVersion is
IsAbsoluteLatestVersion in the query.  However, in the case where
preelease is true and the feed being queried doesn't support
IsAbsoluteLatestVersion, the IsLatestVersion is included in the query.

This is deemed as wrong, since it is the exact opposite of what is
being asked for.

This commit addresses this issue specifically by only including
IsLatestVersion when explicitly not asking for prerelease.  We believe
that this will prevent confusion when folks are using Chocolatey.

In addition, when doing the PackageAsync call, when we can't use
IsLatestVersion or IsAbsoluteLatestVersion, defer to using a new
helper method FindPackageByIdAsync which was introduced in another
scope of work, to selectively search for a package given the searchTerm
then order by version, and return the highest. This is required, since
the query can potentially return more than more result, which is
not desired.  In order to use this method, it was necessary to further
extend the IV2FeedParser to include the method definition.
  • Loading branch information
gep13 committed Mar 15, 2023
1 parent d79e7c5 commit f101507
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 12 deletions.
8 changes: 8 additions & 0 deletions src/NuGet.Core/NuGet.Protocol/LegacyFeed/IV2FeedParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ Task<V2FeedPage> GetSearchPageAsync(
// Start - Chocolatey Specific Modification
//////////////////////////////////////////////////////////

Task<IReadOnlyList<V2FeedPackageInfo>> FindPackagesByIdAsync(
string id,
bool includeUnlisted,
bool includePrerelease,
SourceCacheContext sourceCacheContext,
ILogger log,
CancellationToken token);

Task<IReadOnlyList<V2FeedPackageInfo>> GetPackageVersionsAsync(
string id,
bool includeUnlisted,
Expand Down
110 changes: 98 additions & 12 deletions src/NuGet.Core/NuGet.Protocol/LegacyFeed/V2FeedListResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Threading;
using System.Threading.Tasks;
using NuGet.Common;
using NuGet.Packaging;
using NuGet.Protocol;
using NuGet.Protocol.Core.Types;

Expand Down Expand Up @@ -52,13 +53,33 @@ public async override Task<IEnumerableAsync<IPackageSearchMetadata>> ListAsync(
{
var supportsIsAbsoluteLatestVersion =
await _feedCapabilities.SupportsIsAbsoluteLatestVersionAsync(logger, token);
if (prerelease && supportsIsAbsoluteLatestVersion)

//////////////////////////////////////////////////////////
// Start - Chocolatey Specific Modification
//////////////////////////////////////////////////////////

if (prerelease)
{
filter = new SearchFilter(includePrerelease: true, filter: SearchFilterType.IsAbsoluteLatestVersion)
if (supportsIsAbsoluteLatestVersion)
{
OrderBy = SearchOrderBy.Id,
IncludeDelisted = includeDelisted
};
filter = new SearchFilter(includePrerelease: true, filter: SearchFilterType.IsAbsoluteLatestVersion)
{
OrderBy = SearchOrderBy.Id,
IncludeDelisted = includeDelisted
};
}
else
{
filter = new SearchFilter(includePrerelease: true, filter: null)
{
OrderBy = SearchOrderBy.Version,
IncludeDelisted = includeDelisted
};
}

//////////////////////////////////////////////////////////
// End - Chocolatey Specific Modification
//////////////////////////////////////////////////////////
}
else
{
Expand All @@ -85,14 +106,33 @@ public async override Task<IEnumerableAsync<IPackageSearchMetadata>> ListAsync(
{
var supportsIsAbsoluteLatestVersion =
await _feedCapabilities.SupportsIsAbsoluteLatestVersionAsync(logger, token);
if (prerelease && supportsIsAbsoluteLatestVersion)

//////////////////////////////////////////////////////////
// Start - Chocolatey Specific Modification
//////////////////////////////////////////////////////////

if (prerelease)
{
filter = new SearchFilter(includePrerelease: true,
filter: SearchFilterType.IsAbsoluteLatestVersion)
if (supportsIsAbsoluteLatestVersion)
{
IncludeDelisted = includeDelisted,
OrderBy = SearchOrderBy.Id
};
filter = new SearchFilter(includePrerelease: true, filter: SearchFilterType.IsAbsoluteLatestVersion)
{
IncludeDelisted = includeDelisted,
OrderBy = SearchOrderBy.Id
};
}
else
{
filter = new SearchFilter(includePrerelease: true, null)
{
IncludeDelisted = includeDelisted,
OrderBy = SearchOrderBy.Version
};
}

//////////////////////////////////////////////////////////
// End - Chocolatey Specific Modification
//////////////////////////////////////////////////////////
}
else
{
Expand Down Expand Up @@ -121,7 +161,41 @@ public async override Task<IPackageSearchMetadata> PackageAsync(
CancellationToken token)
{
var metadataCache = new MetadataReferenceCache();
var searchFilter = new SearchFilter(prerelease);

var supportsIsAbsoluteLatestVersion = await _feedCapabilities.SupportsIsAbsoluteLatestVersionAsync(logger, token);
SearchFilter searchFilter = null;

if (prerelease)
{
if (supportsIsAbsoluteLatestVersion)
{
searchFilter = new SearchFilter(includePrerelease: true, filter: SearchFilterType.IsAbsoluteLatestVersion);
}
else
{
// In this scenario, we can't do a IsLatestVersion or IsAbsoluteVersion query, which means that any query we
// do will potentially result in more than one result, which is not desired.
// Instead, use the FindPackageByIdAsync method, and then order the results by version, and return the
// top result.
var packages = await FindPackageByIdAsync(searchTerm, includeUnlisted: false, prerelease, sourceCacheContext: null, logger, token);

searchFilter = new SearchFilter(includePrerelease: true, filter: null);
searchFilter.OrderBy = SearchOrderBy.Version;

if (packages.Count == 0)
{
return null;
}

var highestVersionPackage = packages.OrderByDescending(p => p.Version).FirstOrDefault();
return V2FeedUtilities.CreatePackageSearchResult(highestVersionPackage, metadataCache, searchFilter, (V2FeedParser)_feedParser, logger, token);
}
}
else
{
searchFilter = new SearchFilter(includePrerelease: false, filter: SearchFilterType.IsLatestVersion);
}

searchFilter.ExactPackageId = true;

var pageOfResults = await _feedParser.GetPackagesPageAsync(searchTerm, searchFilter, 0, 1, logger, token);
Expand All @@ -134,6 +208,18 @@ public async override Task<IPackageSearchMetadata> PackageAsync(
return V2FeedUtilities.CreatePackageSearchResult(pageOfResults.Items[0], metadataCache, searchFilter, (V2FeedParser)_feedParser, logger, token);
}

private async Task<IReadOnlyList<V2FeedPackageInfo>> FindPackageByIdAsync(string packageId, bool includeUnlisted, bool includePrerelease, SourceCacheContext sourceCacheContext, Common.ILogger log, CancellationToken token)
{
if (await _feedCapabilities.SupportsFindPackagesByIdAsync(log, token))
{
return await _feedParser.FindPackagesByIdAsync(packageId, includeUnlisted, includePrerelease, sourceCacheContext, log, token);
}
else
{
return await _feedParser.GetPackageVersionsAsync(packageId, includeUnlisted, includePrerelease, sourceCacheContext, log, token);
}
}

//////////////////////////////////////////////////////////
// End - Chocolatey Specific Modification
//////////////////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ NuGet.Protocol.IHttpSource.ProcessStreamAsync<T>(NuGet.Protocol.HttpSourceReques
NuGet.Protocol.IHttpSource.ProcessStreamAsync<T>(NuGet.Protocol.HttpSourceRequest request, System.Func<System.IO.Stream, System.Threading.Tasks.Task<T>> processAsync, NuGet.Protocol.Core.Types.SourceCacheContext cacheContext, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task<T>
NuGet.Protocol.IHttpSource.RetryHandler.get -> NuGet.Protocol.IHttpRetryHandler
NuGet.Protocol.IHttpSource.RetryHandler.set -> void
NuGet.Protocol.IV2FeedParser.FindPackagesByIdAsync(string id, bool includeUnlisted, bool includePrerelease, NuGet.Protocol.Core.Types.SourceCacheContext sourceCacheContext, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<NuGet.Protocol.V2FeedPackageInfo>>
NuGet.Protocol.IV2FeedParser.GetPackageVersionsAsync(string id, bool includeUnlisted, bool includePreRelease, NuGet.Protocol.Core.Types.SourceCacheContext sourceCacheContext, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<NuGet.Protocol.V2FeedPackageInfo>>
NuGet.Protocol.LocalPackageSearchMetadata.BugTrackerUrl.get -> System.Uri
NuGet.Protocol.LocalPackageSearchMetadata.DocsUrl.get -> System.Uri
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ NuGet.Protocol.IHttpSource.ProcessStreamAsync<T>(NuGet.Protocol.HttpSourceReques
NuGet.Protocol.IHttpSource.ProcessStreamAsync<T>(NuGet.Protocol.HttpSourceRequest request, System.Func<System.IO.Stream, System.Threading.Tasks.Task<T>> processAsync, NuGet.Protocol.Core.Types.SourceCacheContext cacheContext, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task<T>
NuGet.Protocol.IHttpSource.RetryHandler.get -> NuGet.Protocol.IHttpRetryHandler
NuGet.Protocol.IHttpSource.RetryHandler.set -> void
NuGet.Protocol.IV2FeedParser.FindPackagesByIdAsync(string id, bool includeUnlisted, bool includePrerelease, NuGet.Protocol.Core.Types.SourceCacheContext sourceCacheContext, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<NuGet.Protocol.V2FeedPackageInfo>>
NuGet.Protocol.IV2FeedParser.GetPackageVersionsAsync(string id, bool includeUnlisted, bool includePreRelease, NuGet.Protocol.Core.Types.SourceCacheContext sourceCacheContext, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<NuGet.Protocol.V2FeedPackageInfo>>
NuGet.Protocol.LocalPackageSearchMetadata.BugTrackerUrl.get -> System.Uri
NuGet.Protocol.LocalPackageSearchMetadata.DocsUrl.get -> System.Uri
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ NuGet.Protocol.IHttpSource.ProcessStreamAsync<T>(NuGet.Protocol.HttpSourceReques
NuGet.Protocol.IHttpSource.ProcessStreamAsync<T>(NuGet.Protocol.HttpSourceRequest request, System.Func<System.IO.Stream, System.Threading.Tasks.Task<T>> processAsync, NuGet.Protocol.Core.Types.SourceCacheContext cacheContext, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task<T>
NuGet.Protocol.IHttpSource.RetryHandler.get -> NuGet.Protocol.IHttpRetryHandler
NuGet.Protocol.IHttpSource.RetryHandler.set -> void
NuGet.Protocol.IV2FeedParser.FindPackagesByIdAsync(string id, bool includeUnlisted, bool includePrerelease, NuGet.Protocol.Core.Types.SourceCacheContext sourceCacheContext, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<NuGet.Protocol.V2FeedPackageInfo>>
NuGet.Protocol.IV2FeedParser.GetPackageVersionsAsync(string id, bool includeUnlisted, bool includePreRelease, NuGet.Protocol.Core.Types.SourceCacheContext sourceCacheContext, NuGet.Common.ILogger log, System.Threading.CancellationToken token) -> System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<NuGet.Protocol.V2FeedPackageInfo>>
NuGet.Protocol.LocalPackageSearchMetadata.BugTrackerUrl.get -> System.Uri
NuGet.Protocol.LocalPackageSearchMetadata.DocsUrl.get -> System.Uri
Expand Down

0 comments on commit f101507

Please sign in to comment.