Skip to content
This repository was archived by the owner on Mar 17, 2025. It is now read-only.

Commit b219c65

Browse files
committed
Add support for packageType query parameter
1 parent c59a82a commit b219c65

10 files changed

+150
-53
lines changed

src/ProjectFileTools.NuGetSearch/Contracts/IPackageInfo.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using ProjectFileTools.NuGetSearch.Feeds;
1+
using System.Collections.Generic;
2+
using ProjectFileTools.NuGetSearch.Feeds;
23

34
namespace ProjectFileTools.NuGetSearch.Contracts
45
{
@@ -24,6 +25,8 @@ public interface IPackageInfo
2425

2526
string Tags { get; }
2627

28+
IReadOnlyList<PackageType> PackageTypes { get; }
29+
2730
FeedKind SourceKind { get; }
2831
}
2932
}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
namespace ProjectFileTools.NuGetSearch.Contracts
1+
namespace ProjectFileTools.NuGetSearch.Contracts
22
{
33
public interface IPackageQueryConfiguration
44
{
5-
string CompatibiltyTarget { get; }
5+
string CompatibilityTarget { get; }
66

77
bool IncludePreRelease { get; }
88

99
int MaxResults { get; }
10+
11+
PackageType PackageType { get; }
1012
}
1113
}

src/ProjectFileTools.NuGetSearch/Contracts/IPackageSearchManager.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
using System;
1+
using System;
22
using ProjectFileTools.NuGetSearch.Feeds;
33

44
namespace ProjectFileTools.NuGetSearch.Contracts
55
{
66

77
public interface IPackageSearchManager
88
{
9-
IPackageFeedSearchJob<Tuple<string, FeedKind>> SearchPackageNames(string prefix, string tfm);
9+
IPackageFeedSearchJob<Tuple<string, FeedKind>> SearchPackageNames(string prefix, string tfm, string packageType = null);
1010

11-
IPackageFeedSearchJob<Tuple<string, FeedKind>> SearchPackageVersions(string packageName, string tfm);
11+
IPackageFeedSearchJob<Tuple<string, FeedKind>> SearchPackageVersions(string packageName, string tfm, string packageType = null);
1212

1313
IPackageFeedSearchJob<IPackageInfo> SearchPackageInfo(string packageId, string version, string tfm);
1414
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace ProjectFileTools.NuGetSearch.Contracts
5+
{
6+
public class PackageType : IEquatable<PackageType>
7+
{
8+
public static IReadOnlyList<PackageType> DefaultList { get; } = new[] { KnownPackageType.Dependency };
9+
10+
public PackageType(string id, string version = null)
11+
{
12+
Name = id ?? throw new ArgumentNullException(nameof(id));
13+
Version = version;
14+
}
15+
public string Name { get; }
16+
public string Version { get; }
17+
18+
19+
public override bool Equals(object obj) => Equals(obj as PackageType);
20+
21+
public bool Equals(PackageType other) => other is PackageType
22+
&& string.Equals(Name, other.Name, StringComparison.Ordinal)
23+
&& string.Equals(Version, other.Version, StringComparison.Ordinal);
24+
25+
public override int GetHashCode()
26+
{
27+
int hashCode = -612338121;
28+
hashCode = hashCode * -1521134295 + StringComparer.Ordinal.GetHashCode(Name);
29+
hashCode = hashCode * -1521134295 + StringComparer.Ordinal.GetHashCode(Version);
30+
return hashCode;
31+
}
32+
}
33+
34+
public class KnownPackageType
35+
{
36+
public static PackageType Legacy { get; } = new PackageType("Legacy");
37+
public static PackageType DotnetCliTool { get; } = new PackageType("DotnetCliTool");
38+
public static PackageType Dependency { get; } = new PackageType("Dependency");
39+
public static PackageType DotnetTool { get; } = new PackageType("DotnetTool");
40+
public static PackageType SymbolsPackage { get; } = new PackageType("SymbolsPackage");
41+
public static PackageType DotnetPlatform { get; } = new PackageType("DotnetPlatform");
42+
public static PackageType MSBuildSdk { get; } = new PackageType("MSBuildSdk");
43+
}
44+
}

src/ProjectFileTools.NuGetSearch/Feeds/Disk/NuGetPackageMatcher.cs

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using ProjectFileTools.NuGetSearch.Contracts;
1+
using System.Linq;
2+
3+
using ProjectFileTools.NuGetSearch.Contracts;
24
using ProjectFileTools.NuGetSearch.IO;
35

46
namespace ProjectFileTools.NuGetSearch.Feeds.Disk
@@ -17,7 +19,16 @@ public static bool IsMatch(string dir, IPackageInfo info, IPackageQueryConfigura
1719
}
1820
}
1921

20-
return true;
22+
if (queryConfiguration.PackageType != null)
23+
{
24+
//NOTE: can't find any info on how the version is supposed to be handled (or what it's even for), so use an exact match
25+
if (!info.PackageTypes.Any(p => queryConfiguration.PackageType.Equals(p)))
26+
{
27+
return false;
28+
}
29+
}
30+
31+
return true;
2132
}
2233
}
2334
}

src/ProjectFileTools.NuGetSearch/Feeds/NuSpecReader.cs

+20-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Xml.Linq;
1+
using System.Collections.Generic;
2+
using System.Xml.Linq;
23
using ProjectFileTools.NuGetSearch.Contracts;
34

45
namespace ProjectFileTools.NuGetSearch.Feeds
@@ -23,9 +24,26 @@ internal static IPackageInfo Read(string nuspec, FeedKind kind)
2324
XElement iconUrl = metadata?.Element (XName.Get ("iconUrl", ns.NamespaceName));
2425
XElement tags = metadata?.Element(XName.Get("tags", ns.NamespaceName));
2526

27+
List<PackageType> packageTypes = null;
28+
XElement packageTypesEl = metadata?.Element(XName.Get("packageTypes", ns.NamespaceName));
29+
if (packageTypesEl != null)
30+
{
31+
var nameName = XName.Get("name", ns.NamespaceName);
32+
var versionName = XName.Get("name", ns.NamespaceName);
33+
packageTypes = new List<PackageType>();
34+
foreach (var packageType in packageTypesEl.Elements(XName.Get("packageType", ns.NamespaceName)))
35+
{
36+
var typeName = packageType.Attribute(nameName).Value;
37+
var typeVersion = packageType.Attribute(versionName)?.Value;
38+
packageTypes.Add (new PackageType(typeName, typeVersion));
39+
}
40+
}
41+
2642
if (id != null)
2743
{
28-
return new PackageInfo(id.Value, version?.Value, title?.Value, authors?.Value, summary?.Value, description?.Value, licenseUrl?.Value, projectUrl?.Value, iconUrl?.Value, tags?.Value, kind);
44+
return new PackageInfo(
45+
id.Value, version?.Value, title?.Value, authors?.Value, summary?.Value, description?.Value,
46+
licenseUrl?.Value, projectUrl?.Value, iconUrl?.Value, tags?.Value, kind, packageTypes);
2947
}
3048

3149
return null;

src/ProjectFileTools.NuGetSearch/Feeds/PackageInfo.cs

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
using ProjectFileTools.NuGetSearch.Contracts;
1+
using System.Collections.Generic;
2+
3+
using ProjectFileTools.NuGetSearch.Contracts;
24

35
namespace ProjectFileTools.NuGetSearch.Feeds
46
{
57

68
public class PackageInfo : IPackageInfo
79
{
8-
public PackageInfo(string id, string version, string title, string authors, string summary, string description, string licenseUrl, string projectUrl, string iconUrl, string tags, FeedKind sourceKind)
10+
public PackageInfo(string id, string version, string title, string authors, string summary, string description, string licenseUrl, string projectUrl, string iconUrl, string tags, FeedKind sourceKind, IReadOnlyList<PackageType> packageTypes)
911
{
1012
Id = id;
1113
Version = version;
@@ -17,6 +19,7 @@ public PackageInfo(string id, string version, string title, string authors, stri
1719
SourceKind = sourceKind;
1820
IconUrl = iconUrl;
1921
Tags = tags;
22+
PackageTypes = packageTypes ?? PackageType.DefaultList;
2023
}
2124

2225
public string Id { get; }
@@ -40,5 +43,7 @@ public PackageInfo(string id, string version, string title, string authors, stri
4043
public string Tags { get; }
4144

4245
public FeedKind SourceKind { get; }
46+
47+
public IReadOnlyList<PackageType> PackageTypes { get; }
4348
}
4449
}
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,37 @@
1-
using ProjectFileTools.NuGetSearch.Contracts;
1+
using ProjectFileTools.NuGetSearch.Contracts;
22

33
namespace ProjectFileTools.NuGetSearch.Feeds
44
{
55
public class PackageQueryConfiguration : IPackageQueryConfiguration
66
{
7-
public PackageQueryConfiguration(string targetFrameworkMoniker, bool includePreRelease = true, int maxResults = 100)
7+
public PackageQueryConfiguration(string targetFrameworkMoniker, bool includePreRelease = true, int maxResults = 100, PackageType packageType = null)
88
{
9-
CompatibiltyTarget = targetFrameworkMoniker;
9+
CompatibilityTarget = targetFrameworkMoniker;
1010
IncludePreRelease = includePreRelease;
1111
MaxResults = maxResults;
12+
PackageType = packageType;
1213
}
1314

14-
public string CompatibiltyTarget { get; }
15+
public string CompatibilityTarget { get; }
1516

1617
public bool IncludePreRelease { get; }
1718

1819
public int MaxResults { get; }
1920

21+
public PackageType PackageType { get; }
22+
2023
public override int GetHashCode()
2124
{
22-
return (CompatibiltyTarget?.GetHashCode() ?? 0) ^ IncludePreRelease.GetHashCode() ^ MaxResults.GetHashCode();
25+
return (CompatibilityTarget?.GetHashCode() ?? 0) ^ IncludePreRelease.GetHashCode() ^ MaxResults.GetHashCode() ^ (PackageType?.GetHashCode() ?? 0);
2326
}
2427

2528
public override bool Equals(object obj)
2629
{
27-
PackageQueryConfiguration cfg = obj as PackageQueryConfiguration;
28-
return cfg != null
29-
&& string.Equals(CompatibiltyTarget, cfg.CompatibiltyTarget, System.StringComparison.Ordinal)
30+
return obj is PackageQueryConfiguration cfg
31+
&& string.Equals(CompatibilityTarget, cfg.CompatibilityTarget, System.StringComparison.Ordinal)
3032
&& IncludePreRelease == cfg.IncludePreRelease
31-
&& MaxResults == cfg.MaxResults;
33+
&& MaxResults == cfg.MaxResults
34+
&& (PackageType?.Equals(cfg.PackageType) ?? false);
3235
}
3336
}
3437
}

src/ProjectFileTools.NuGetSearch/Feeds/Web/NuGetV3ServiceFeed.cs

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Threading;
@@ -192,10 +192,11 @@ public async Task<IPackageNameSearchResult> GetPackageNamesAsync(string prefix,
192192
}
193193

194194
IReadOnlyList<string> results = new List<string>();
195-
string frameworkQuery = !string.IsNullOrEmpty(queryConfiguration.CompatibiltyTarget) ? $"&supportedFramework={queryConfiguration.CompatibiltyTarget}" : "";
196-
const string autoCompleteServiceTypeIdentifier = "SearchAutocompleteService";
195+
string frameworkQuery = !string.IsNullOrEmpty(queryConfiguration.CompatibilityTarget) ? $"&supportedFramework={queryConfiguration.CompatibilityTarget}" : "";
196+
string packageTypeQuery = !string.IsNullOrEmpty(queryConfiguration.PackageType?.Name) ? $"&packageType={queryConfiguration.PackageType.Name}" : "";
197+
const string autoCompleteServiceTypeIdentifier = "SearchAutocompleteService/3.5.0";
197198
List<string> serviceEndpoints = await DiscoverEndpointsAsync(_feed, autoCompleteServiceTypeIdentifier, cancellationToken).ConfigureAwait(false);
198-
Func<string, string> queryFunc = x => $"{x}?q={prefix}{frameworkQuery}&take={queryConfiguration.MaxResults}&prerelease={queryConfiguration.IncludePreRelease}";
199+
Func<string, string> queryFunc = x => $"{x}?q={prefix}&semVerLevel=2.0.0{frameworkQuery}{packageTypeQuery}&take={queryConfiguration.MaxResults}&prerelease={queryConfiguration.IncludePreRelease}";
199200
JObject document = await ExecuteAutocompleteServiceQueryAsync(serviceEndpoints, queryFunc, cancellationToken).ConfigureAwait(false);
200201

201202
if (document != null)
@@ -294,7 +295,7 @@ public async Task<IPackageInfo> GetPackageInfoAsync(string packageId, string ver
294295
licenseUrl = catalogEntry["licenseUrl"]?.ToString();
295296
iconUrl = catalogEntry["iconUrl"]?.ToString();
296297
tags = catalogEntry ["tags"]?.ToString ();
297-
packageInfo = new PackageInfo(id, version, title, authors, summary, description, licenseUrl, projectUrl, iconUrl, tags, _kind);
298+
packageInfo = new PackageInfo(id, version, title, authors, summary, description, licenseUrl, projectUrl, iconUrl, tags, _kind, null);
298299
return packageInfo;
299300
}
300301
}
@@ -311,7 +312,7 @@ public async Task<IPackageInfo> GetPackageInfoAsync(string packageId, string ver
311312
licenseUrl = catalogEntry["licenseUrl"]?.ToString();
312313
iconUrl = catalogEntry["iconUrl"]?.ToString ();
313314
tags = catalogEntry["tags"]?.ToString();
314-
packageInfo = new PackageInfo(id, version, title, authors, summary, description, licenseUrl, projectUrl, iconUrl, tags, _kind);
315+
packageInfo = new PackageInfo(id, version, title, authors, summary, description, licenseUrl, projectUrl, iconUrl, tags, _kind, null);
315316
bestSemanticVersion = currentVersion;
316317
}
317318
}
@@ -329,7 +330,7 @@ public async Task<IPackageInfo> GetPackageInfoAsync(string packageId, string ver
329330
public async Task<IPackageVersionSearchResult> GetPackageVersionsAsync(string id, IPackageQueryConfiguration queryConfiguration, CancellationToken cancellationToken)
330331
{
331332
IReadOnlyList<string> results = new List<string>();
332-
string frameworkQuery = !string.IsNullOrEmpty(queryConfiguration.CompatibiltyTarget) ? $"&supportedFramework={queryConfiguration.CompatibiltyTarget}" : "";
333+
string frameworkQuery = !string.IsNullOrEmpty(queryConfiguration.CompatibilityTarget) ? $"&supportedFramework={queryConfiguration.CompatibilityTarget}" : "";
333334
const string autoCompleteServiceTypeIdentifier = "SearchAutocompleteService";
334335
List<string> serviceEndpoints = await DiscoverEndpointsAsync(_feed, autoCompleteServiceTypeIdentifier, cancellationToken).ConfigureAwait(false);
335336
Func<string, string> queryFunc = x => $"{x}?id={id}{frameworkQuery}&take={queryConfiguration.MaxResults}&prerelease={queryConfiguration.IncludePreRelease}";

0 commit comments

Comments
 (0)