BaGetter fails to parse an upstream RegistrationsBaseUrl request.
Closed this issue · 1 comments
Describe the bug
BaGetter fails to parse an upstream RegistrationsBaseUrl
request.
According to the documentation NugetV3 allows for the tags
of PackageMetadata
/CatalogEntry to be either a string
or string[]
:
https://learn.microsoft.com/en-us/nuget/api/registration-base-url-resource#catalog-entry
And it seems like Github Packages is one of the few implementations that uses this possibility since when requesting i get:
{
"count": 1,
"items": [
{
"@id": "https://nuget.pkg.github.com/FakeOrga/fakepkg/index.json",
"lower": "1.4.1",
"upper": "1.5.1",
"count": 2,
"items": [
{
"@id": "https://nuget.pkg.github.com/FakeOrga/fakepkg/1.5.1.json",
"packageContent": "https://nuget.pkg.github.com/FakeOrga/download/fakepkg/1.5.1/fakepkg.1.5.1.nupkg",
"catalogEntry": {
"@id": "https://nuget.pkg.github.com/FakeOrga/fakepkg/1.5.1.json",
"authors": "Someone",
"copyright": "",
"dependencyGroups": [ ],
"description": "Package Description",
"iconUrl": "",
"id": "fakepkg",
"isPrerelease": false,
"language": "",
"licenseUrl": "",
"packageContent": "https://nuget.pkg.github.com/FakeOrga/download/fakepkg/1.5.1/fakepkg.1.5.1.nupkg",
"projectUrl": "",
"requireLicenseAcceptance": false,
"summary": "",
"tags": "",
"version": "1.5.1"
}
}
]
}
]
}
(details anonymized and shortened)
Since the current implementation only handles string[]
BaGetter/src/BaGetter.Protocol/Models/PackageMetadata.cs
Lines 116 to 120 in f2447c4
BaGetter will fail with
fail: BaGetter.Core.V3UpstreamClient[0]
Failed to mirror fakepkg's upstream metadata
System.Text.Json.JsonException: The JSON value could not be converted to System.Collections.Generic.IReadOnlyList`1[System.String]. Path: $.items[0].items[0].catalogEntry.tags | LineNumber: 0 | BytePositionInLine: 4828.
at System.Text.Json.ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type propertyType)
at System.Text.Json.Serialization.JsonCollectionConverter`2.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, TCollection& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.JsonCollectionConverter`2.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, TCollection& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.JsonCollectionConverter`2.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, TCollection& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.ContinueDeserialize(ReadBufferState& bufferState, JsonReaderState& jsonReaderState, ReadStack& readStack)
at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.DeserializeAsync(Stream utf8Json, CancellationToken cancellationToken)
at BaGetter.Protocol.HttpClientExtensions.GetFromJsonOrDefaultAsync[TResult](HttpClient httpClient, String requestUri, CancellationToken cancellationToken) in D:\Extern\BaGetter\src\BaGetter.Protocol\Extensions\HttpClientExtensions.cs:line 61
at BaGetter.Protocol.Internal.RawPackageMetadataClient.GetRegistrationIndexOrNullAsync(String packageId, CancellationToken cancellationToken) in D:\Extern\BaGetter\src\BaGetter.Protocol\PackageMetadata\RawPackageMetadataClient.cs:line 35
at BaGetter.Protocol.NuGetClientFactory.PackageMetadataClient.GetRegistrationIndexOrNullAsync(String packageId, CancellationToken cancellationToken) in D:\Extern\BaGetter\src\BaGetter.Protocol\PackageMetadata\PackageMetadataClient.cs:line 25
at BaGetter.Protocol.NuGetClient.GetPackageMetadataAsync(String packageId, CancellationToken cancellationToken) in D:\Extern\BaGetter\src\BaGetter.Protocol\NuGetClient.cs:line 213
at BaGetter.Core.V3UpstreamClient.ListPackagesAsync(String id, CancellationToken cancellationToken) in D:\Extern\BaGetter\src\BaGetter.Core\Upstream\Clients\V3UpstreamClient.cs:line 60
To Reproduce
Steps to reproduce the behavior:
- Using the currently lastest master version of BaGetter:
f2447c4
- Setup any Github Packages feed as upstream
- Configure the httpClient for auth parameters
https://github.com/bagetter/BaGetter/blob/main/src/BaGetter.Core/Extensions/DependencyInjectionExtensions.cs#L190
httpClient.DefaultRequestHeaders.Authorization = new("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes($"Username:PAT")));
- Request any package metadata from the upstream mirror through BaGetter
Expected behavior
The implementation should be able to pass both variations
PR
If you want I can contribute a fix PR for this with something like https://stackoverflow.com/a/59430729/2444047
Edit: i see you already have exactly this converter, just tested and adding the converter attribute fixes it
Thank you for bringing this up!
Can you create an PR with the change?