nuget pack ignores package.config dependencies - nuget

I cannot get nuget pack X.csproj to recognize package dependencies in a project. Amazingly, when packaging, the diagnostic message “Found packages.config. Using packages listed as dependencies” is printed, but in the end the <dependencies/> tag in the .nuspec file inside the package is empty.
The packages.config for the project does indeed contain references:
<packages>
<package id="SmartAction.Logger" version="1.0.2.0" targetFramework="net40" />
<package id="SmartAction.Pervasive" version="1.0.1.0" targetFramework="net40" />
</packages>
To narrow the problem down, I removed my own parallel .nuspec file, and mostly all switches from the nuget pack command:
> nuget pack libToneDetection.csproj -prop Configuration=Release
MSBuild auto-detection: using msbuild version '14.0' from 'C:\Program Files (x86)\MSBuild\14.0\bin'.
Attempting to build package from 'libToneDetection.csproj'.
Packing files from '[snip]\Core\ToneDetection\libToneDetection\bin\Release'.
Found packages.config. Using packages listed as dependencies
Successfully created package '[snip]\Core\ToneDetection\libToneDetection\SmartAction.Audio.ToneDetection.1.0.0.0.nupkg'.
NuGet Version: 3.3.0.212
The only difference I can spot with this project is that its name is different from package name (I am trying to maintain them in sync but this is older stuff I am repackaging).
I doubt I had ever seen this before. I am finding questions on SO from people trying to prevent references in packages.config from becoming dependencies of the package, but none from those trying, like me, to beat the reverse problem. Help!
Addendum. I copied the project out of the solution with other projects to a temporary directory and rebuilt the package from there. Now one of the two dependencies from packages.config was added to the package:
<dependencies>
<dependency id="SmartAction.Logger" version="1.0.2.0" />
</dependencies>
Thinking of the differences between the two, the SmartAction.Logger package depends on SmartAction.Pervasive. But the package I am compiling really uses both.
To me, either behavior looks incorrect. Am I hitting a nuget bug, or a cryptic complex feature?
Xref: Opened https://github.com/NuGet/Home/issues/1867

Related

Is there a way to control Nuget's over-eager references?

I'm just getting started with Nuget, and moving much of my team's intra-team and interdepartmental references into packages on a private nuget feed. The thing I'm observing though is that when my packages have their own dependencies, those secondary dependencies get added to my projects as references as though the projects are using them directly.
This works from a build & release perspective since the dependencies get packaged up correctly, but for larger projects the references list gets rather bloated compared to the assemblies actually referenced in code. In a hypothetical cleanup exercise, it seems like it would be difficult to determine which assemblies were this type of secondary dependency and which were simply no longer used.
Is this just an unfortunate consequence of Nuget works? Is there a different way to use Nuget that doesn't result in these noisy references?
For example: I have project MyProject, which uses assembly DependencyA directly. DependencyA references assembly LibraryX and as such LibraryX is required at runtime for MyProject, even though MyProject doesn't use it directly. For the sake of the example let's say LibraryX is distinct enough for it to be its own package.
In this scenario, prior to Nuget, the assemblies would live in source control, and could be packaged up during build/publish/deploy without needing an assembly reference in MSBuild. In this case MyProject has an MSBuild assembly reference to DependencyA, but not to LibraryX.
However, upon migrating to Nuget and consuming these dependencies via packages, the nuspec for DependencyA expresses a dependeny on LibraryX:
<package >
<metadata>
<id>DependencyA</id>
<version>1.0.0</version>
<authors>Initech</authors>
<owners>Initech</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<license type="expression">MIT</license>
<description>A Dependency</description>
<tags>Dependency A</tags>
<dependencies>
<group targetFramework="net40" >
<dependency id="LibraryX" version="1.0.0" />
</group>
</dependencies>
</metadata>
</package>
When installing the DependencyA package on MyPrject, Nuget adds an MSBuild assembly reference for LibraryX to MyProject even though MyProject doesn't actually directly reference LibraryX.
You can control which assets are allowed to flow up the dependency chain using PrivateAssets, which I think is what you mean.
By default everything flows up though, so you can use packages you only depend on transitively in your code - in other words, the distinction between compile and runtime dependencies you mentioned in your comment doesn't exist by default.

NuGet Pack -- Failed to retrieve information from remote source

I am trying to run:
nuget pack project.csproj
but because of the directory structure of the project:
A\B\C\Project
it keeps saying:
NuGet.Protocol.Core.Types.FatalProtocolException: Failed to retrieve information from remote source 'A\B\Packages', which it really should be 'A\Packages'. How do I change where NuGet looks for packages while establishing dependencies.
I have tried putting a NuGet.config in both the project directory as well as the Solution (in .nuget). I added this to the file:
<config>
<add key="repositoryPath" value="A\Packages" />
</config>
in both places and it made no difference (it always says A\B\Packages).
VisualStudio 2019: Tools > Nuget Package Manager > Package Sources:
Select nuget.org and specifically unselect the others options
Add NuGet.org reference in the package source
Go to tools -> NuGet package manager-> package manager settings
Select NuGet Package manager and then Package sources
Add the following source library.
Name: NuGet.org
Source: {"\Https://api.nuget.org/v3/index.json}
The error is a bit weird, but is already mentioned here.
It looks like NuGet by default expects a packages folder at the same location as the .csproj file.
I also had a custom project structure where the .sln was located in another folder.
At least I worked around this by creating a Symbolic link like this (open cmd with admin rights):
cd <your .csproj location>
mklink /d packages "C:\path\to\actual\packages"
This way NuGet thinks the packages folder exists and should be able to create your package.
For me it worked by adding NuGet.config in solution folder.
I was facing similar issue with core 3.1 and trying to upgrade package 'Swashbuckle.AspNetCore.SwaggerGe'.I found that i was doing typo in Package source url. I have corrected it [Tools => Nuget Package manager => Package manager setting => Package Source ] and issue got resolved.
If you use packages that have Semantic Versioning 2.0.0, please make sure that you are using the V3 feed, https://api.nuget.org/v3/index.json, in the NuGet configuration.
The issue may be caused by the way the nuget looks for the packages folder. It looks for a .sln file by traversing up the directory structure. If, in your case, directory A\B contains a .sln file then nuget will assume the packages folder would also be there.
On OSX you can add a symlink to trick nuget into building.
Run the following in the project folder to make nuget read from the parent (solution) directory that have a packages folder:
ln -s ../packages packages
In my case, I unchecked ALL the package sources except the one that I needed which was NuGet.org from NuGet Package Manager >> Package Sources. After this, the NU1301 error was gone.
In the case of Rider IDE another problem could cause this error:
if you configure your NuGet sources in the project let the Username and Password in the Rider Ui empty and instead add manually this section (packageSourceCredentials) to your NuGet.Config in the project folder:
<configuration>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="YourNuget" value="<your_nuget_url>" />
</packageSources>
<packageSourceCredentials>
<YourNuget>
<add key="Username" value="<Username>" />
<add key="ClearTextPassword" value="<Password>" />
</YourNuget>
</packageSourceCredentials>
</configuration>

Nuget package content

I downloaded the Nuget package
microsoft.aspnet.webapi.5.2.0.nupkg
but there are no dlls in there. How does this nuget package work ? Was excepting dlls in side.
Whilst Microsoft.AspNet.WebApi 5.2.0 does not contain any dlls itself it depends on the Microsoft.AspNet.WebApi.WebHost NuGet package which does contain dlls. The Microsoft.AspNet.WebApi.WebHost also depends on other NuGet packages, and so on.
In the Microsoft.AspNet.WebApi.5.2.0.nupkg there is a .nuspec file which defines the dependencies:
<dependencies>
<dependency id="Microsoft.AspNet.WebApi.WebHost" version="[5.2.0, 5.3.0)" />
</dependencies>
If you install the NuGet Package Explorer it will be easier to see how this works. The NuGet Package Explorer allows you to find, download and look inside NuGet packages without having to download and unzip them manually.

Creating NuGet package with reference to a non-NuGet reference

I am creating a Class Library that builds 2 dlls into a NuGet package. It has a few references to dlls that currently do not have a NuGet package to be referenced from.
How should I make my NuGet package dependent on those dlls that are currently unavailable via NuGet?
If I bundle them up as well, what happens if a project that already has a reference to these dlls, pulls down my NuGet package, what happens to that reference?
Should I just create a NuGet package for each dll reference and make my NuGet package dependent on these?
You can bundle the DLLs into your NuGet package with no ill effects. A project that already has those DLLs in some /libs (or whatever) folder will continue to reference them from there. Assemblies in your NuGet package will reference the bundled DLLs that are pulled into /packages.
In your nuspec file, use the <file> element to include the internal DLLs, as such:
<package>
<metadata>
...
</metadata>
<files>
<file src="PATH_TO_BIN\DependencyOne.dll" target="mylibs" />
<file src="PATH_TO_BIN\DependencyTwo.dll" target="mylibs" />
</files>
</packages>
This will result in the following file structure when the NuGet package is pulled:
PATH_TO_PROJECT/packages/YOUR_NUGET_PACKAGE/mylibs/DependencyOne.dll
PATH_TO_PROJECT/packages/YOUR_NUGET_PACKAGE/mylibs/DependencyTwo.dll
The target attribute can specify any arbitrary path relative to your package root.

Packing NuGet projects compiled in release mode?

Is there some way to make a NuGet package using code compiled in release mode? Or is there some reason I should only publish (make available locally, in this case) packages compiled in debug mode?
Every time I call nuget pack from my project directory, where I have the nuspec file below, on code I have only compiled in release mode, it complains about not finding the DLL in the debug folder ("\bin\Debug\SomeProject.dll"). If I compile it in debug mode, those files are there and it packs them up as it should.
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>$id$</id>
<version>$version$</version>
<authors>$author$</authors>
<owners>$author$</owners>
<iconUrl>http://somewhere/project.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>$description$</description>
</metadata>
</package>
You can solve it like this:
NuGet.exe pack Foo.csproj -Prop Configuration=Release
(reference)
If you are using a post-build event and you want to create a package whether using Debug or Release configuration you can setup the post-build event commandline like so:
"<path to nuget tools>\NuGet.exe" pack "$(ProjectPath)" -Prop Configuration=$(ConfigurationName)
To have NuGet automatically use Release mode when you run nuget pack, do the following:
Open your .csproj file in a text editor.
Find the following line:
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
In this line, replace Debug with Release.
Save changes.
The answers here are good, but I was having a lot of problems with this for a .NET Standard project. I had a project that was only going to publish Release binaries, but it wasn't respecting my default build output path.
I added this to my CSProj which then enabled me to use the accepted answer here.
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<OutputPath>$(SolutionDir)bin\$(PlatformTarget)\Release</OutputPath>
</PropertyGroup>
Chiming in here.
My build profile would build the DLLs to bin\<arch>\Debug|Release.
I was able to point to my folders by running the nuget command as follows:
Notice how I used the -p option.
PS > nuget pack -p Configuration="x64\Release"
Attempting to build package from ...
...
Found packages.config. Using packages listed as dependencies
...
- Add a dependency group for .NETFramework4.7.2 to the nuspec
Successfully created package...