NuGet / Home

Repo for NuGet Client issues
Other
1.5k stars 252 forks source link

Feature request: Installation of nuget packages with custom types #10468

Open augustoproiete opened 3 years ago

augustoproiete commented 3 years ago

Background

Currently, a NuGet package can have a custom PackageType defined by the package author, which is currently used for different purposes, including the filtering in the NuGet gallery as well as changing the behavior of the command palette (as it's the case with .NET Tools)

image

image

Problem statement

Installing a package that has an custom package type as of this writing (.NET v5.0.102, VS2019 v16.8.4, NuGet v5.8.1) works as following

NuGet Client Result
:white_check_mark: dotnet.exe Package installs normally with the same behavior as a Dependency package type
:white_check_mark: MSBuild.exe Package installs normally with the same behavior as a Dependency package type
:x: Visual Studio Package fails to install with error (screenshot below)
:x: nuget.exe Package fails to install with error (screenshot below)
:white_check_mark: Log output of `dotnet add package` to install work... (click to expand)

```powershell C:\augustoproiete\MyProject\MyClassLibrary>dotnet add package Cake.PackageType.Addin Determining projects to restore... Writing C:\Users\augustoproiete\AppData\Local\Temp\tmp9FAD.tmp info : Adding PackageReference for package 'Cake.PackageType.Addin' into project 'C:\augustoproiete\MyProject\MyClassLibrary\MyClassLibrary.csproj'. info : CACHE https://api.nuget.org/v3/registration5-gz-semver2/cake.packagetype.addin/index.json info : Restoring packages for C:\augustoproiete\MyProject\MyClassLibrary\MyClassLibrary.csproj... info : Package 'Cake.PackageType.Addin' is compatible with all the specified frameworks in project 'C:\augustoproiete\MyProject\MyClassLibrary\MyClassLibrary.csproj'. info : PackageReference for package 'Cake.PackageType.Addin' version '0.1.0' added to file 'C:\augustoproiete\MyProject\MyClassLibrary\MyClassLibrary.csproj'. info : Committing restore... info : Generating MSBuild file C:\augustoproiete\MyProject\MyClassLibrary\obj\MyClassLibrary.csproj.nuget.g.props. info : Writing assets file to disk. Path: C:\augustoproiete\MyProject\MyClassLibrary\obj\project.assets.json log : Restored C:\augustoproiete\MyProject\MyClassLibrary\MyClassLibrary.csproj (in 67 ms). ``` ```xml netstandard2.0 ```

:white_check_mark: Log output of MSBuild restore when using a custom package type... (click to expand)

```powershell C:\augustoproiete\MyProject\MyClassLibrary>msbuild /t:restore MyClassLibrary.csproj Microsoft (R) Build Engine version 16.8.3+39993bd9d for .NET Framework Copyright (C) Microsoft Corporation. All rights reserved. Build started 1/19/2021 7:37:00 PM. Project "C:\augustoproiete\MyProject\MyClassLibrary\MyClassLibrary.csproj" on node 1 (Restore target(s)). _GetAllRestoreProjectPathItems: Determining projects to restore... Restore: Restoring packages for C:\augustoproiete\MyProject\MyClassLibrary\MyClassLibrary.csproj... Committing restore... Generating MSBuild file C:\augustoproiete\MyProject\MyClassLibrary\obj\MyClassLibrary.csproj.nuget.g.props. Generating MSBuild file C:\augustoproiete\MyProject\MyClassLibrary\obj\MyClassLibrary.csproj.nuget.g.targets. Writing assets file to disk. Path: C:\augustoproiete\MyProject\MyClassLibrary\obj\project.assets.json Restored C:\augustoproiete\MyProject\MyClassLibrary\MyClassLibrary.csproj (in 337 ms). NuGet Config files used: C:\Users\augustoproiete\AppData\Roaming\NuGet\NuGet.Config C:\Program Files (x86)\NuGet\Config\Microsoft.VisualStudio.Offline.config Feeds used: https://api.nuget.org/v3/index.json C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\ Done Building Project "C:\augustoproiete\MyProject\MyClassLibrary\MyClassLibrary.csproj" (Restore target(s)). Build succeeded. 0 Warning(s) 0 Error(s) ``` ```xml netstandard2.0 ```

:x: Error message from Visual Studio when using a custom package type...

![image](https://user-images.githubusercontent.com/177608/104791117-edf25480-576f-11eb-8c49-eb5da81848e1.png) ![image](https://user-images.githubusercontent.com/177608/105105409-6b78d600-5a8a-11eb-8241-e2f5d881ed26.png)

:x: Error message from NuGet.exe when using a custom package type...

![image](https://user-images.githubusercontent.com/177608/105105785-2e611380-5a8b-11eb-85b2-3592f63cf9c0.png)


The documentation states that:

Any type other than Dependency and DotnetTool, however, are not recognized by the NuGet Package Manager in Visual Studio.

Which explains the error in Visual Studio, and NuGet.exe...

Goal

Enable package authors to be able to leverage the custom package type feature without losing the ability to install packages.

Proposal A

Update Visual Studio and NuGet.exe to ignore custom package types it doesn't know about, and execute the installation process for a Dependency package by default, as dotnet.exe and MSBuild.exe seem to be doing today.

Better yet, assume Dependency or DotnetTool depending on the command being executed (e.g. dotnet add package -> Dependency / dotnet tool install -> DotnetTool) for package types that are unknown to the client.

Proposal B

  1. Allow package authors to specify more than one package type, so that a package can be classified with a custom package type and, at the same time, be installed through the Visual Studio NuGet Package Manager UI as any other Dependency nuget package can be;

  2. Make the necessary updates as needed in the NuGet client, NuGet Package Manager UI, NuGet Gallery, to be able to handle multiple package types.

e.g.

<packageTypes>
  <packageType name="Dependency" /> <!-- known package type, used for install -->
  <packageType name="CakeAddin" /> <!-- custom package type, ignored by NPM UI, NuGet.exe, etc. -->
</packageTypes>

In this scenario, dependency package type should be allowed for installation even if you have an additional, unrecognized package type.


The examples above use a proof-of-concept package published on nuget.org with the ID Cake.PackageType.Addin which has its package type set to CakeAddin.


/cc @joelverhagen @anangaur, @jcjiang

zkat commented 3 years ago

cc @JonDouglas too

JonDouglas commented 3 years ago

Hey @augustoproiete!

We briefly reviewed this feature request alongside https://github.com/NuGet/NuGetGallery/issues/8381.

As mentioned on a tweet last month this is an area we're thinking about. NuGet hosts many different package types, and to support all of the package types today, we're working to understand the needs of each type such as Dependency, DotNetTool, and Template.

Custom types are an area we need to understand more. Packages are already multi-purpose. They can serve as a Dependency by default, but they can also serve as a tool/task/targets in certain ecosystems like Cake, Fake, etc. This is just one example as there are many other multi-purpose packages out there that could benefit from their own custom package types without installation behavior changing. This can be especially helpful for filtering purposes on various galleries or tooling.

We think the goal of your proposal resonates with many in the ecosystem & we're going to have to investigate these scenarios closer to see if there's future possibilities of backwards compatibility for the two scenarios you mentioned(VS & NuGet.exe).

Enable package authors to be able to leverage the custom package type feature without losing the ability to install packages.

I took an initial look at these two proposal scenarios & found some initial logic.

  1. Proposal A
  2. Proposal B

It seems that this InstallationCompatibility is the primary reason. dotnet CLI & MSBuild look like they use NuGet.CommandLine.XPlat under the hood where it doesn't really care about packageType. Perhaps we can do something similar to reduce compatibility checks or how DotNetTool checks for the specific package type being inside the list.

Regardless, we'll need a bit more time to see the feasibility of making packageType expand to these scenarios will be on the client side. I just wanted to reach out & say we took an initial look & will dive a bit deeper shortly as the client team hasn't had an opportunity to review this fully. Thought I'd provide a quick update in the meantime. Thanks again for the great contributions!

matkoch commented 3 years ago

Hi @JonDouglas, i hope this is the right place. One package type that I would really like to see is a Tool type, which reflects that a NuGet package has a ./tools directory inside. This would make it much easier for a package to be consumed / installed in the area of build automation. For nuke and bullseye it could confidently show the PackageDownload syntax that was introduced by @nkolev92 (kudos for this great idea again! love it). For Cake it could show the #tool preprocessor directive.

abatishchev commented 1 year ago

Any news on this proposal?

glopesdev commented 23 hours ago

It seems that "Proposal B" outlined in the original issue is already almost supported. Below is an outline of where I think we are:

I am a contributor in NuGet/NuGet.Client#5991 and will do my best to unblock that ASAP.

Not sure if @JonDouglas @nkolev92 @zivkan would agree, but it seems to me that if NuGet/NuGet.Client#5991 is unblocked then InstallationCompatibility could also be updated to simply check whether the list of package types contains "at least one" of the supported package types (rather than "exactly one").