-
Notifications
You must be signed in to change notification settings - Fork 695
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for package type queries in both local and remote sources #5991
base: dev
Are you sure you want to change the base?
Conversation
var types = string.Join("&", | ||
filters.PackageTypes.Select( | ||
s => "packageTypeFilter=" + s)); | ||
s => "packageType=" + s)); | ||
queryString += "&" + types; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@joelverhagen are multiple package types defined as &packageType=type1&packageType=type2
or &packageType=type1+type2
?
Additionally, are the semantics that the package must contain all package types, or just one? This is important, to make sure that local folder feed sources behave in the same way.
the docs are not sufficiently specific about multiple values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only a single package type filter is supported. The package type parameter is plumbed through in our search service as a single string:
https://github.com/NuGet/NuGetGallery/blob/dc7abf2bd145d91596b032c19e1c9abe8b276956/src/NuGet.Services.AzureSearch/SearchService/SearchParametersBuilder.cs#L169-L172
PRs on the docs are welcome if they are unclear!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding multiple package types on the package, the package type parameter matches the package if ANY of the package types match, per:
The
packageType
parameter is used to further filter the search results to only packages that have at least one package type matching the package type name.
Emphasis mine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@joelverhagen @zivkan Thank you both for the feedback. In that case, it seems that the API surface of SearchFilter
might be slightly inconsistent with current SearchQueryService/3.5.0
capabilities, since SearchFilter
allows for multiple package types to be specified.
How do you prefer to address this? Shall PackageSearchResourceV3
and LocalPackageSearchResource
throw if more than one package type is provided? Or shall we deprecate the entire PackageTypes
property and introduce a new PackageType
property with a single value?
Personally I would prefer not touching the current surface API, since this feature is very much needed and breaking the surface API might delay adoption and confuse existing API consumers (having two properties vary their names by a single letter is usually very much discouraged).
@joelverhagen Is there any expectation that multiple package type filters will ever be supported? That might inform whether the deprecation route might be preferred.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no expectation that NuGet.org should support multiple package type filters. If this is needed, we would need to design, implement, and document a protocol enhancement. I am not aware of any other package source that implements multiple package type filters.
IMHO, PackageTypes
should be deprecated and PackageType
should be introduced, to match the current state of the protocol. But I do not work on the client side much so I may be missing something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know of any plans to add multiple package type support. It's not even clear to what existing scenario could benefit from such a filter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally I would prefer not touching the current surface API
To be fair, this PR is breaking server APIs, even if it's not breaking the assembly's API. If there are any servers (that are not nuget.org) that use the current packageTypeFilter
, this PR will break clients using those servers. There's evidence that (in 2018) neither nuget.org nor myget implemented packageTypeFilter
, but there's no way to know if some other server uses it. On the other hand, the V2 protocol isn't documented, and packageTypeFilter
was never part of the official V3 protocol.
I'm trying to rush reviewing a bunch of old PRs that I haven't reviewed in a long time, so I haven't yet formed an opinion about breaking APIs (about changing NuGet.Protocol to remove the plural PackageTypes
and have a singular PackageType
). There's a case to be made that NuGet.Client should implement the official protocol spec.
src/NuGet.Core/NuGet.Protocol/LocalRepositories/LocalPackageSearchResource.cs
Outdated
Show resolved
Hide resolved
src/NuGet.Core/NuGet.Protocol/Resources/PackageSearchResourceV3.cs
Outdated
Show resolved
Hide resolved
the reason is that I could not find a way to filter on a package type for a search, i'm not aware of any workaround |
Sorry again for the delay. The lead up to .NET 9 GA, and the days following, were very busy. Anyway, if someone in the NuGet team was doing this, I would ask them for the following:
I don't consider myself "good" at open source. After all, look at how much time passes between my comments here. I also don't know if it's reasonable to expect the same quality of contribution from external people as team members who work in the code every day. What I am confident about is that when something doesn't work as expected, NuGet will get the support requests, not the original contributor, which is why I typically don't approve PRs from external contributions unless they're close to the quality that I'd expect of a team member. And I'm working on higher priority changes, so I don't have the time to take over this PR and implement the 3 things I listed above. |
@zivkan I was trying to do this and started getting the below analyzer error when declaring a single string property: public string PackageType { get; set; }
Upon investigation there are actually three different
Trying to follow the pattern for other properties I changed it to:
As expected this now raises the same RS0016 error for the existing Is there anything obvious I might be missing? Also, should I be adding the new API to the Apologies in advance for not being very clear on the use and syntax of the |
I also don't know the syntax for the public API files. When using an IDE, the analyzer will have a codefix (available from the "lightbulb" button), which will automatically add a syntactically correct line into the Unshipped file. Unfortunately the analyzer (or roslyn itself) only works on one target framework at a time, so you need to repeat codefix for each target framework, as we documented here: https://github.com/NuGet/NuGet.Client/blob/dev/docs/nuget-sdk.md#development |
287cdc3
to
cf99bb6
Compare
@zivkan Thanks for the feedback, no worries about any delay.
This is a good point, and made me go back to double-check whether However, I am a bit at a loss at how to implement the check you requested, since the way that search query service endpoints are accessed right now is not via the "resource" abstraction. Instead, the API requests a list of URI endpoints via the NuGet.Client/src/NuGet.Core/NuGet.Protocol/Providers/PackageSearchResourceV3Provider.cs Lines 25 to 26 in 949031c
Because My feeling is perhaps we should refactor the entire approach to use
Given the above, I am going to interpret this as exposing a new boolean property in Does this sound acceptable?
Done, see cf99bb6. |
Since
Something I don't like about the version strings we use is that it implies that newer client versions support all past features (making it "impossible" to deprecate features), and it implies that if a server wants to support a particular feature, it must also implement all past versions as well, even if they have features they don't want. This makes sense for some resources and features like package metadata (registration) where older versions needed the response to be uncompressed, and newer clients support gzip and deflate. I mean, that really should have been done via the Anyway, I'm getting way off topic. What I'm trying to get at, is that going forward we probably need to treat the service index entries as feature flags, not as a client version.
Yes, that's exactly what I was thinking. |
@zivkan I've been thinking more about these two points and I admit I am now conflicted on this. My personal use case is reproducing a NuGet client much like the VS code package manager. In these types of front-end, the user may select among a large number of package sources for search, including local folders, old v3 and v2 clients, or the "All" option which works as a mixed package source which can run search across all of the above simultaneously. At that point, what should happen if the user runs a filtered search on "All" and by chance it happens that one of the sources does not support package type filtering? Should an unhandled exception bubble up to the user in this case? And what should the expected resolution be from a user point of view? Should we really disallow running package type filtering on the "All" source entirely whenever the user adds a single package source which does not support it? This would mean that to fix the situation the user would have to understand pretty deeply the NuGet service index protocol and modify by hand the package source list to get things working again. I am really fearful this could create confusion and further error reports. Also it makes the abstraction of the Not sure about others, but I know for example that we wouldn't use it in this case, and would simply default to having no filter and instead use our current workaround of wrapping the resource and modify query strings directly so we retain the simplicity. What might be the negative impact of simply ignoring the filter if the resource does not support it? Maybe @joelverhagen has some thoughts on this since related decisions were impacting the SDK, e.g. dotnet/sdk#12038? |
I guess answering myself, one option might be we leave it to the client front-end to adjust its own implementation of the "All" feed to avoid launching queries to package sources which do not support package type filtering. |
Bug
Fixes: NuGet/Home#8915
Description
nuget.org allows filtering by package type using the
packageType
query parameter sinceSearchQueryService/3.5.0
. This parameter has not been officially surfaced by the client API, although relevant infrastructure has already been introduced in theSearchFilter
class:NuGet.Client/src/NuGet.Core/NuGet.Protocol/SearchFilter.cs
Line 60 in c8d14f3
Upon inspection of relevant source code, it looks like the relevant bits had already been introduced in
PackageSearchResourceV3
but using the old query parameter namepackageTypeFilter
. The fix is simply replacing the below query parameter withpackageType
:NuGet.Client/src/NuGet.Core/NuGet.Protocol/Resources/PackageSearchResourceV3.cs
Lines 140 to 147 in c8d14f3
For completeness, we also add package type filtering functionality to
LocalPackageSearchResource
by filtering over the package types available throughpackage.Nuspec.GetPackageTypes()
.PR Checklist