NuGet / Home

Repo for NuGet Client issues
Other
1.49k stars 250 forks source link

nuget pack is ignoring dependencies when using PackageReference instead of packages.config #5979

Closed rafaelromao closed 6 years ago

rafaelromao commented 6 years ago

NuGet dev edit: Duplicate of https://github.com/NuGet/Home/issues/4491

Details about Problem

NuGet product used: nuget.exe

NuGet version: 4.3.0.4406

.NET Framework v4.5 (Full Framewok project, not a dotnet core project)

VS version: 15.3.3

Worked before, when using packages.config instead of PackageReference.

Detailed repro steps

  1. Configure Visual Studio 2017 to use PackageReference instead of packages.config.

  2. Create a new C# Class Library (.NET Framework) targeting .NET Framework 4.5.

  3. Reference some package, like Newtonsoft.json, for example.

  4. Not that no packages.config file will be created and the referenced package will be included in the csproj file.

  5. Create a valid nuspec file without specifying any dependencies (they should be inferred and included automatically)

  6. Run nuget pack and check the .nuspec file included in the generated .nupkg file. If should list the dependency packages, in this case Newtonsoft.json, in the dependencies tag, but no dependencies is listed.

...

Sample Project

https://github.com/rafaelromao/nuget_pack_with_PackageReference

In the sample projects, ClassLibrary1 was created with Visual Studio configured to use PackageReference instead of packages.config. You can see in the .nupack generated by running nuget pack .\ClassLibrary1.csproj that the .nuspec file in it does not include any dependencies, while in the ClassLibrary2 project, created using packages.config, the dependencies are included.

rohit21agrawal commented 6 years ago

nuget.exe pack currently doesn't support package reference based projects.

To package your C# Class Library which manages your dependencies via PackageReference in the csproj itself, please add a reference to NuGet.Build.Tasks.Pack ( https://www.nuget.org/packages/NuGet.Build.Tasks.Pack/) and run msbuild /t:pack from the command line.

we are still actively working on improving this scenario, please let us know whatever you find missing.

rafaelromao commented 6 years ago

I will try that. Thanks, @rohit21agrawal.

rafaelromao commented 6 years ago

@rohit21agrawal , my project is .NET 4.5. msbuild /t:pack says the target framework version is invalid. I tried 4.6.2 just to test and received the same error. I also tried a similar package named NuGet.Build.Packaging, but it did not produce any output. Probably I'm missing something. Can you point me to some resources that explain how to configure my project to use NuGet.Build.Tasks.Pack?

rohit21agrawal commented 6 years ago

@rafaelromao oh sorry, i forgot to specify - you will have to add a property <TargetFramework>net462</TargetFramework> in your csproj (doesn't have to be net462, can be net45 if that's what you are targeting) .

rohit21agrawal commented 6 years ago

if it also complains about Authors, then set a property for <Authors> as well.

rafaelromao commented 6 years ago

I could make a PoC work by running: msbuild.exe -t:Pack -p:Configuration=Release -p:TargetFramework=net45 -p:Authors=test. Now I will follow this guideline https://docs.microsoft.com/en-us/nuget/schema/msbuild-targets to make it work as I need. I will configure the properties in csproj as you suggests. Thanks

rohit21agrawal commented 6 years ago

Awesome! Please note that this scenario is still a work in progress (original msbuild /t:pack was designed to work with NETCore SDK based projects identified by having <Project Sdk="Microsoft.NET.Sdk"> at the top of the project file) and we would appreciate any feedback that you have for this scenario.

rafaelromao commented 6 years ago

Sure. I will comment here if I have any issues implementing that. Thanks

rohit21agrawal commented 6 years ago

we already have a tracking issue for this effort : https://github.com/NuGet/Home/issues/5918 . I am going to close this issue and would appreciate if you can comment on the tracking issue.

ADD-Juan-Perez commented 6 years ago

We have added a reference to NuGet.Build.Tasks.Pack in a .NET 4.6.1 project.

If we configure the TargetFramework property in csproj an error occurs:

The project system has enountered an error.

'dimensionValuesMap' must contain at least one element. Parameter name: dimensionValuesMap

But if we set the TargetFramework property through the command line works fine: msbuild.exe -t:Pack -p:Configuration=Release -p:TargetFramework=net461

Thanks in advance

marvel16 commented 6 years ago

Why was this issue closed??? Still having this issue with nuget pack using nuget 4.6.2

marvel16 commented 6 years ago

@rafaelromao @rohit21agrawal

We have converted our projects under .NET Framework 4.7 from packages.config to packagereferences, but when we published nuget package for one of projects it lacks nuget dependencies. Is there any solution how to fix this preserving packagereference style as it works a waaay faster for restoring and updating. We are using VSTS to build and publish packages???

If there is no solution, is there only 1 way to get back to packages config by deleting all package references and adding them via Nuget package manager?

Thanks, Waiting for answer!

SimonSDA commented 6 years ago

Been struggling with this one for a while... the only solution I've found which works is to manually add the dependencies into the .nuspec file and use nuget.exe pack. Using msbuild with NuGet.Build.Tasks.Pack does include dependencies but ignore info in the AssemblyInfo.cs so I end up with defaults e.g version 1.0.0. You can use msbuild to generate the package and copy/paste the dependencies into the .nuspec file but this is still a pain.

rohit21agrawal commented 6 years ago

@simonSDA with the NuGet.Build.Tasks.Pack package, all the attributes in AssemblyInfo.cs can be mapped to appropriate properties in the csproj file which the pack task will pick up. Would that solve the issue for you?

https://docs.microsoft.com/en-us/nuget/reference/msbuild-targets#pack-target

rohit21agrawal commented 6 years ago

@marvel16 does the following not work for you:

To package your C# Class Library which manages your dependencies via PackageReference in the csproj itself, please add a reference to NuGet.Build.Tasks.Pack ( https://www.nuget.org/packages/NuGet.Build.Tasks.Pack/) and run msbuild /t:pack from the command line.

SimonSDA commented 6 years ago

@rohit21agrawal I've been trying to avoid editing the csproj files as we have over 350 projects :(. I ended up ditching nuget.build.tasks.pack and writing a utility to scan the csproj file and generate the dependencies group, then paste it into the nuspec file. Any internal solution project references I add into the files section which also seems to work. It is a pain that it is still a manual process.

Rzpeg commented 6 years ago

@rohit21agrawal I have a solution with 2 projects (net461), let's say LibA (assembly version 2.0.0) and LibB (assembly version 1.5.0). LibA depends on LibB and on Newtonsoft.Json10.0.0.nupkg. In the end, I need 2 nuget packages, 1 for each project, with the same versioning. LibA2.0.0.nupkg and LibB1.5.0.nupkg, where LibA2.0.0.nupkg depends on LibB1.5.0.nupkg and on Newtonsoft.Json10.0.0.nupkg.

With packages.config and nuget pack I was able to achieve this by passing the -IncludeReferencedProjects argument. All dependencies were correctly built. I can't get the same result with after migrating to PackageReference and msbuild /t:pack. I have installed NuGet.Build.Tasks.Pack into both projects, and by running msbuild /t:pack LibA.csproj /p:PackageVersion=2.0.0, the generated dependency requires LibB2.0.0.nupkg instead of the 1.5.0 that's actually referenced by the project.

Any advice? Any

rohit21agrawal commented 6 years ago

@Rzpeg Can you try the following:

1) Restore the sln or both the projects using msbuild /t:restore or nuget.exe restore. 2) Look in the project.assets.json file on LibA (under the obj folder) under the targets section for LibB/ .

If the version listed in 2) above is 1.5.0 instead of 2.0.0, it's because msbuild /t:pack is also causing a rebuild/restore and passing in 2.0.0 as a version for LibB as well. You can avoid this by passing /p:NoBuild=true when packing.

pantonis commented 6 years ago

@rohit21agrawal did you fix the issue where nuget.exe pack supports packagerefence missing dependencies?

SuperJMN commented 6 years ago

How is this fixed? I still have the same problem with a 4.6.1 library. Nuget doesn't add the referenced packages as dependencies to the resulting nuspec /nupkg.

pantonis commented 6 years ago

same problem here

rohit21agrawal commented 6 years ago

no one said this is fixed, it has been duped against : https://github.com/NuGet/Home/issues/4491

liushuanggang commented 6 years ago

@rohit21agrawal, Thank you for the workaround:

"To package your C# Class Library which manages your dependencies via PackageReference in the csproj itself, please add a reference to NuGet.Build.Tasks.Pack ( https://www.nuget.org/packages/NuGet.Build.Tasks.Pack/) and run msbuild /t:pack from the command line."

It works for me. But after pack my package, I found the dependency NuGet.Build.Tasks.Pack was also included in the the package as a dependency. What I want to know is that must I include the NuGet.Build.Tasks.Pack dependency in my package? Is there any way to exclude it except move it manually? Thanks.

rohit21agrawal commented 6 years ago

you can set PrivateAssets=all on the PackageReference, and that will prevent it from being included as a dependency

edufur commented 5 years ago

no one said this is fixed, it has been duped against : #4491

But this is NOT a dupe. Those are different problems. This needs to be re-opened as I am having the same problem. I had to switch back to packages.config to solve mine.

qidydl commented 5 years ago

Not only does this problem still exist in NuGet version 4.9.3 despite closing the issue, the recommended solution of using the NuGet.Build.Tasks.Pack package and MSBuild does not work; the "pack" target is not made available by the addition of this package.

JGCreator commented 5 years ago

Not only does this problem still exist in NuGet version 4.9.3 despite closing the issue, the recommended solution of using the NuGet.Build.Tasks.Pack package and MSBuild does not work; the "pack" target is not made available by the addition of this package.

All my projects referencing NuGet.Build.Tasks.Pack and building with msbuild /t:Pack /p:TargetFramework=net471 /p:Authors=CI /p:PackageOutputPath="../Packages" are working fine.

Rzpeg commented 5 years ago

@rohit21agrawal I don't get why the issue has been closed. This still doesn't work. With NuGet 5. Even with NuGet.Build.Tasks.Pack. And it is very easy to reproduce: Two .Net 4.6.1 Library Projects in 1 Solution SomeLib.sln: SomeLib.Core (AssemblyVersion 1.5.0) and SomeLib.EntityFramework (AssemblyVersion 2.0.0). Both with NuGet.Build.Tasks.Pack 5.0.0 installed.. SomeLib.EntityFramework references SomeLib.Core project and EntityFramework Package (PackageReference).

Running:

  1. nuget restore SomeLib.sln
  2. msbuild SomeLib.sln /p:Configuration="Release"
  3. msbuild SomeLib.EntityFramework\SomeLib.EntityFramework.csproj /t:Pack /p:Configuration=Release /p:Authors=test /p:NoBuild=true /p:PackageVersion=2.0.0 /p:PackageOutputPath=.

Results in a SomeLib.EntityFramework.nupkg package, which references v. 2.0.0 of SomeLib.Core, not v. 1.5.0 specified in AssemblyInfo. adding nuget restore SomeLib.EntityFramework\SomeLib.EntityFramework.csproj after building the solution, but before packing doesn't help.

Instead of fixing nuget pack you guys keep closing every ticket about the topic. By the way, NuGet task pack on Azure Pipelines has the same issues. It doesn't work.

Basically, we are forced to use this ugly workaround to pack nugets on Azure Pipelines

  1. nuget restore SomeLib.sln
  2. PowerShell script

    Get-ChildItem -recurse | 
    Where-Object {$_.extension -eq ".nuspec"} |
    Foreach-Object {
        $PathToCsproj = $_.DirectoryName + "\" + $_.BaseName + ".csproj"
        $PathToNuSpec = $_.DirectoryName + "\" + $_.BaseName + ".nuspec"
        $csproj = [xml](Get-Content $PathToCsproj)
        $packageDependency = $csproj.Project.ItemGroup.PackageReference | Where-Object { $null -ne $_ }
        $nuspec = [xml](Get-Content $PathToNuSpec)
    
        $dep = $nuspec.CreateElement('dependencies', $nuspec.package.metadata.NamespaceURI)
    
        $packageDependency | ForEach-Object {
          $onedependency = $dep.AppendChild($nuspec.CreateElement('dependency', $nuspec.package.metadata.NamespaceURI))
          $onedependency.SetAttribute('id', $_.Include)
          $onedependency.SetAttribute('version', $_.Version)
        }
    
        $nuspec.package.metadata.AppendChild($dep)
    
        $nuspec.Save($PathToNuSpec)
    
        Write-Host $PathToCsproj
    
        nuget pack $PathToCsproj -NonInteractive -OutputDirectory . -IncludeReferencedProjects -Verbosity Detailed -Properties Configuration=Release -Properties Build=false
    }
nkolev92 commented 5 years ago

@Rzpeg

The steps you are describing are not equivalent. -IncludeReferencedProjects is not supported for PackageReference.

Please create an issue and provide a repro zip of your scenario. (all the steps you are taking) and we can conclusively tell you the expectation.

last-Programmer commented 5 years ago

It is been two years and the issue still exists. damn. come on microsoft you can do better. are you expecting every one to migrate to .Net Core?

qidydl commented 5 years ago

@rbmanian75 To be fair, the answer to that question is clearly "yes", hence the .NET 5 announcement.

edufur commented 5 years ago

I agree that this should NOT be closed. None of the alternatives work completely and it seems MS is closing every variant of this problem report that they can. I logged an issue in the Dev Community for azure devops since this was evident in that process. They closed that board item but one of their devs agreed this was a bug and logged it here: https://github.com/Microsoft/azure-pipelines-tasks/issues/10301

Hopefully, that one won't get closed until they ACTUALLY solve the problem. We need to keep them accountable. This problem has gone on way too long.

edufur commented 5 years ago

@rbmanian75 To be fair, the answer to that question is clearly "yes", hence the .NET 5 announcement.

If you ask me, this is more of a convergence to bring core back to .NET than it is .NET to core. It is all going to be one big happy family now. And hopefully, this problem gets solved before then.

patrickkrootjes commented 5 years ago

to solve this problem I'm using a post built event and a PowerShell script (NuGetPackDependencies.ps1) and this solved the problem for me:

 <PostBuildEvent>
echo ***** nuget package post build event *****
echo ***** configuration: $(ConfigurationName) *****
echo ***** platform: $(PlatformName) *****
if  $(ConfigurationName) == Release (
  if $(PlatformName) == AnyCPU (
    echo ***** change to project directory *****
    cd $(ProjectDir)
   echo ***** run powershell script *****
   powershell -ExecutionPolicy Unrestricted NugetPackDependencies.ps1
    echo ***** create nuget package *****
    nuget pack Common.Logging.csproj -prop configuration=release -prop platform=AnyCPU -IncludeReferencedProjects
  ) else echo ***** not release AnyCPU, so no package is build *****
) else echo ***** not release AnyCPU, so no package is build *****</PostBuildEvent>

NuGetPackDependencies.zip

last-Programmer commented 5 years ago

@patrickkrootjes this wont work for packagereference which have dependencies installed from nuget.

patrickkrootjes commented 5 years ago

@rbmanian75 I'm not sure what you mean by "this wont work for packagereference which have dependencies installed from nuget.". I'm using PackageReference for my projects. The way I use it, is that the PowerShell script NuGetPackDependencies.ps1 looks for dependencies inside .csproj and adds those dependencies to .nuspec file. The nuget pack command then produces a NuGet package with the wanted dependencies. This basically solves the problem descibed in this issue. The only problem of this approach is that I have to add the PowerShell script to every project that create a nuget package, but this was manageable. Since it was already clear Microsoft was not going to solve this issue and package config was also no longer maintainable, this was the best approach for me.

edufur commented 5 years ago

@patrickkrootjes Does this work with nested dependencies?

last-Programmer commented 5 years ago

@patrickkrootjes Sorry i have overlooked your solution without looking into what you done in powershell. Your solution for adding the dependencies using powershell script works great. But i was facing a small issue when i try to execute the powershell script. I was getting the error

Method invocation failed because [System.Xml.XPathNodeList] does not contain a method named 'AppendChild'. At NuGetPackDependencies.ps1:96 char:1

But changing the line 87 to

$metaDataElement = $xmlNuspec.package.metadata

made it work.

Thank You Very Much.

last-Programmer commented 5 years ago

@edufur i hope it will work for nested dependencies also. Because nusepc contains the dependencies the dependencies will also have dependencies specified in nuspec file and so on. So all dependencies will be installed.

johnhamm commented 4 years ago

This needs to be reopened as the issue still persists.

nkolev92 commented 4 years ago

@johnhamm

It's duped to https://github.com/NuGet/Home/issues/4491

https://github.com/NuGet/Home/issues/5979#issuecomment-404612702

GiampaoloGabba commented 3 years ago

any hope this will ever be fixed? sigh...

aortiz-msft commented 3 years ago

@GiampaoloGabba - Is there a reason why you can't use dotnet.exe pack as per https://github.com/NuGet/Home/issues/4491?

cc: @JonDouglas

edufur commented 3 years ago

Is there a reason they choose not to solve the issue?

-Eric

On Mon, Oct 26, 2020, 6:23 PM Arturo Ortiz notifications@github.com wrote:

@GiampaoloGabba https://github.com/GiampaoloGabba - Is there a reason why you can't use dotnet.exe pack?

cc: @JonDouglas https://github.com/JonDouglas

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/NuGet/Home/issues/5979#issuecomment-716916434, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEUXN5KY4EHTUS4EZA2MM33SMYOH7ANCNFSM4D5NES2A .

edufur commented 3 years ago

This needs to be re-opened. 3 years have gone by and this is still a problem. dotnet pack is not a useful option unless they library is dotnetcore... which in my case, it is not.

qidydl commented 3 years ago

I'm guessing the intended solution is for people to get off legacy .NET Framework projects and onto .NET 5, 6, and up from there. It's clear that .NET Framework is a dead end at this point.

ericnewton76 commented 11 months ago

Just converted Net framework 472 projecst from packages.config to PackageReference in prep for trying to move to NetCore (we cant ATM due to a particular dependency) and its amazing how an issue from 6 years ago is still an issue.

Good job Nuget team. Thanks for fking us over. In the meantime this stackoverflow is a decent workaround: https://stackoverflow.com/a/59662812/323456

It involves a powershell script that reads your CSPROJ/VBPROJ file for the PackageReference nodes and writes them into the nuspec file. Amazing how the Nuget team cant figure out how to do this.

I have defended the Nuget problem for years... its complicated to maintain NetFramework NetCore, dependencies of libraries over time, the Fusion runtime's idiotic assembly version binding scheme being exact-match (that needs to be changed to SemVer) and etc but y'all honestly have hit my last nerve with this extremely common scenario.