NuGet / NuGetGallery

NuGet Gallery is a package repository that powers https://www.nuget.org. Use this repo for reporting NuGet.org issues.
https://www.nuget.org/
Apache License 2.0
1.55k stars 644 forks source link

[NuGet V3 API] Need Assembly version in packageEntries present in catalogEntry #9304

Open harshsikhwal opened 2 years ago

harshsikhwal commented 2 years ago

NuGet Product(s) Involved

Other/NA

The Elevator Pitch

Currently there is no way to decode assembly version published in NuGet package.

There are cases sometimes where application crashes, due to a change of packages in one module, as the build system has its own assembly set defined. We are not able to resolve NuGet packages with the assembly version. Having a section about version would be an amazing add on.

Additional Context and Details

I have recently published my NuGet package dependency tool: NuGet-Visualizer

The reason I created this was to know about all the dependencies, for both NuGet packages as well as Solution/Projects.

Also, I would want to add the assembly version, so that anyone who scans for a NuGet package, can also see the related assembly information, which would be hugely helpful.

joelverhagen commented 2 years ago

Hey @harshsikhwal, @donnie-msft moved this issue from NuGet/Home to NuGet/NuGetGallery since this appears to be more about the server API (NuGet V3 API) instead of a NuGet client feature. Let's move forward under that assumption but please correct if you're actually asking for a NuGet client feature (CLI, VS, nuget.exe, etc).

It is indeed confusing sometimes when the package version != assembly version != assembly file version. There's a lot of nuance there but suffice it to say that you're right. Runtime problems often show the assembly version but the fix is actually sometimes changing the package version (which in turn pulls in the proper assembly version).

Regarding the add-on you're talking about: where are you proposing this information is surfaced? Which NuGet V3 API?

By the way, modeling the assembly to package version is more complex than some one-to-one mapping. For example, not all packages have a single assembly, even a single assembly per target framework! You could have assembly version X on DLL Y under TFM Z and a totally different DLL and version under a different TFM. Granted, this is an edge case but we'd need to make sure these edge cases work or at least can be safely ignored when modeling this data you're talking about.

Stepping away from the theoretical for one moment, could you provide a concrete example (screenshot, API response, mock-up) of where you'd like to see this information surfaced? How would a user interact with this "add-on"?

harshsikhwal commented 2 years ago

Hi @joelverhagen

I have requested this feature for NuGet V3 API.

I was checking for a mapping systems, package version -> assembly version. I was playing around with the NuGet APIs and I found assembly related entries:

image

It would be good if there can be another attribute: version for each entry that would represent the assembly version.

I understand the complications, like how there can be multiple assemblies, and are based on the framework. But I think the Framework + Assembly Name would be the unique ID here (fullName from JSON) (correct me if I am wrong). I mean the assembly name would be the same, irrespective of the framework but there might be different versions of the same assembly.

So for an entry (Taken from Microsoft.CodeAnalysis.CSharp):

{ "@id": "https://api.nuget.org/v3/catalog0/data/2022.09.30.17.11.14/microsoft.codeanalysis.csharp.4.3.1.json#lib/netcoreapp3.1/es/Microsoft.CodeAnalysis.CSharp.resources.dll", "@type": "PackageEntry", "compressedLength": 107945, "fullName": "lib/netcoreapp3.1/es/Microsoft.CodeAnalysis.CSharp.resources.dll", "length": 400520, "name": "Microsoft.CodeAnalysis.CSharp.resources.dll" }

there can be a version as well as a framework mapping. Considering the fullName is always unique, anyone who wants to access the mapping can scan through this model, check for the desired framework and get the version of the DLL.

When I was building my tool, I wanted to map the NuGet packages with the assembly version, but since the entries are missing I used the NuGet version as the labels. For instance the tool generates the following graph for microsoft.codeanalysis.csharp, version=3.5.0, framework = .NETStandard2.0:

image

Here, I can add the assembly version in the label itself, which will give a better idea of the package and its mapping with assembly version.

The tool also generates deep dependencies of a .NET solution as well. With this, the users can generate graphs for all the related packages and check the assembly version, and can drill down on the nodes using the node identifiers.

The addition would help the end users, or anyone working with some tool to know more about the relation, based on the framework as an input. Do let me know your thoughts on this.

joelverhagen commented 1 year ago

NuGet tooling today does not treat assembly versions as anything special (except some old flows that updated binding redirects in packages.config days ... I think...). We speak only in terms of package versions. Said another way, it's not really part of the model today, so adding it to our V3 protocol would only be for external tool usages like your tool. (Neat looking tool by the way!)

In general, as folks want to build out new "projections" or read-only views of NuGet.org data, I recommend one of the two flows first, before a feature is promoted to support on NuGet.org itself. For example, JetBrains Rider/ReSharper did this for a .NET type search: https://blog.maartenballiauw.be/post/2019/07/30/indexing-searching-nuget-with-azure-functions-and-search.html. You'll be able to iterate and "prove" the scenario without being blocked by NuGet.org.

Two options:

  1. Build a catalog listener which follows the NuGet.org V3 catalog API, analyzing each package as it is published/listed/unlisted and building its own index. Imagine a catalog listener that downloads the .nupkg from the package content API, identifies the assembly version, and then adds this data to a DB of your own creation. You can run your own web service to serve up the custom DB, etc. etc. Here's a walkthrough on how to use the catalog: https://learn.microsoft.com/en-us/nuget/guides/api/query-for-all-published-packages.
  2. Use NuGet.Insights, specifically the PackageAssemblies data file, to generate this data yourself and dump that data file into whatever system you need (e.g. your tool). This internally is essentially option 1 above but a lot of the work is done for you already.

In the short term, I don't think the team will be able to justify adding this to our public API since the use-case is so specific. That being said, I'm happy to leave this issue open to gather upvotes or other related feature requests and we'll reconsider as the situation develops.