NuGet package dependency source files are not embedded in project - nuget

We create and host NuGet packages in-house, with source code and deep dependency trees. I'm having some issues getting dependencies to "behave".
For clarity, this is specifically installing packages via VS or Rider into a .Net Core / PackageReference project. I don't expect it to be a VS/Rider/etc bug, so much as we're doing something slightly wrong.
Scenario:
Create “Package A” using the PackageReference style compilation of
“contentFiles/any/any”.
Create a sub-folder under “contentFiles/any/any” called “Source”.
Place source code files in the “Source” folder.
Have a dependency on “Package B”.
Create “Package B”, again using the PackageReference style, with a “Source” subfolder.
Place source code files in its “Source” folder.
Pack and publish both.
Expectation:
Install “Package A” (using the built-in NuGet package manager UI).
Your project gains a “Source” folder.
A’s source files are referenced into the new “Source” folder and compile with the project.
“Package B” is also installed, since it’s a dependency.
B’s source files are also referenced into the “Source” folder and compile with the project.
Package A is immediately consumable by the project because all of its code, and all of its dependency’s code, is present.
Actual:
Install “Package A”.
Your project gains a “Source” folder.
A’s source files are referenced into the new “Source” folder and compile with the project.
“Package B” is also installed, since it’s a dependency.
B’s source files are not referenced into the “Source” folder.
Package A code cannot be compiled because the source for B is not in the project.
Manually install “Package B”, same as you did for “A”.
B’s source files are referenced into the new “Source” folder in the project.
Now “Package A” can be compiled and consumed.
If sample nuspec files are needed, etc. please let me know.
Thanks
(This is a cross-post from https://github.com/NuGet/Home/issues/8858. No replies for a week)

The post to NuGet's github (listed above) ended up with the solution. When declaring the dependency in the nuspec, set the include to "Runtime,Compile,Native,ContentFiles,BuildTransitive" (or some combination thereof) and your dependency's files will correctly embed. I'm still working through the differences between the options, but there you have it.

Related

Nuget Package Without Lib-Ref-Content Folders

I have downloaded an open source project, made changes to it and then created a nuget package from this new code. The package actually functions as a post-build target. It just runs an exe. That is why it does not contain a lib folder. There is a tools folder and files are copied under this folder. The other folders are: build, buildCrossTargeting, package, _rels. .But when I try to install this local nuget package to a .net 4.6.1 project, I get the following error in Visual Studio:
You are trying to install this package into a project that targets
'.NETFramework,Version=v4.6.1', but the package does not contain any
assembly references or content files that are compatible with that
framework.
When I open and inspect the original nuget package downloaded from nuget.org, I see the same structure. But somehow it installs fine while this locally created one raises error.
What can be done about it?
With the information you provided, I can only guess (please see How to create a Minimal, Reproducible Example). My guess is that you changed the name (id) of the package, but didn't change the name of the target or props files in the build directory. As the docs say, the name of the targets and props file must match the package id exactly, so if you change the package id, you must rename those files.

How can I deploy a PS1 script with a nuget package

I have a PS1 script that I use in all my projects to sign the assemblies. Until now I copied this file over to all my projects. Now I wanted to create a nuget package with the PS1 file.
I created a nuspec file and put the file in "content". Unfortunately nothing happened. Then I tried to put it in lib. Still noting happened. When I restore the package in my project no files where created in this project.
When I analyst the nupkg file with my 7-Zip the file looks OK. The ps1 file was in content, lib respectively.
I didn't found anything to this topic online. Can someone explain to me, how to create such a NuGet-Package?
When a project using packages.config installs a NuGet package, the package's tools\install.ps1 script will run. However, this no longer happens when the project using the package uses PackageReference (such as SDK style projects, used by .NET Core).
Similarly, the files in the content folder of the nupkg are copied into the project on install, but only when the project uses packages.config. PackageReference projects use the contentFiles folder in the nupkg, however the behaviour is different. Those files are copied only on build, not install, for .NET Framework projects and on publish for .NET Core projects. Probably not what you want for signing assemblies.
The feature you probably want to use is including MSBuild props and targets in your package. Note that the props and targets file names must match the package id exactly for NuGet to use them. You probably want to use afterTargets="build" at a guess.

Installing NuGet packages to custom folder in a project in Visual Studio 2015

I have a Visual Studio 2015 solution with many projects. For one of the projects I would like the files from NuGet to download to a specific folder in my project. For example, I intend to use Bootstrap and also Signalr. I would like Bootstrap to download everything into one folder in my application, and not create folders within my project root. For example, I have a folder called 'Libs' in the project and would like those libraries to use 'Libs' as their root folder. This is due to an external build solution that handles everything in the 'Libs' folder.
I've found these docs about using a NuGet.config folder for the solution, but this does not handle my problem. Any ideas?
As far as I'm aware, this isn't possible. Each Nuget package is written with specific instructions on how to install into a project. One of those instructions is where to put files, another example would be what transform to apply to the web.config. Nuget doesn't specify a way to modify these instructions. The only thing you could do would be to modify the packages yourself - download the .nupkg file and open it up as a zip file, you will be able to edit the folder structure from there.

Add reference to same Nuget package but for different targets

I have a solution in Visual Studio 2013 with more C# project files that have source code in common but are targeting for different platforms (.Net, WinRT, .Net Micro Framework and so on).
All the csproj files are under the same directory.
These projects use a Nuget package that is available for all the above platforms itself.
If I add this Nuget package for one of the project (ex. .Net), the package.config file is created and inside has reference to that target (ex. .Net). The package is downloaded in the packages folder.
If I try to add the same package but for a different target to another project in the solution, the UI tells me that the package is already installed. It's true because a package.config file is already there but I'd like to have the same package for a different target.
So my question is the following : how can I add the same Nuget package to all different projects but with different targets ?
Thanks,
Paolo
Unfortunately, I don't think NuGet supports your scenario.
NuGet expects the packages.config file to be in the same folder as the .csproj file. There should be a 1-to-1 relation between these files. You should create a separate folder for each project rather than keep all .csproj files in the same folder.
If you want to share code across multiple projects, the easiest way is to use the new Shared Project support in Visual Studio. Normally this only applies to Universal Projects, but there is an extension[1] that you can install that enables Shared Projects for all project types.
Simply create a new Shared Project. Add all you common code to it. Then in your platform specific projects, you can simply Add Shared Project Reference.
Since each project is now independent, NuGet will add the appropriate package.
Hope this helps. Good luck!
[1] Shared Project Reference Manager https://visualstudiogallery.msdn.microsoft.com/315c13a7-2787-4f57-bdf7-adae6ed54450

NuGet package files not being copied to project content during build

I am building an MVC4 web application with VS2012 professional with NuGet Package Manager version 2.2.31210. I have multiple projects in my solution, all sharing various packages I installed using NuGet. One of my projects is an MVC4 web application where I am using packages such as bootstrap, jquery UI, etc, all installed using NuGet.
When I clone a fresh copy of my entire solution from my repository and build my MVC4 project, the package restore feature seems to be working: it creates the packages directory under the solution direcotry and populates it will all the versions of the packages I expect to see. However, the content files do not get copied to the appropriate places in the MVC app directory. The weird thing is that it does create directories for the content, but does not copy the content files themselves.
For example, I am using the Twitter Bootstrap package which appears in the packages/Twitter.Bootstrap.2.2.2. In the MVC project a directory called bootstrap (containing css, img, and js directories) gets created in the Content directory. But, no css or js files are copied into those directories!
Does anyone have a clue what magic incantation I must utter to get the build to copy these content files from the NuGet packages directory?
This is a very common issue we are all having. I've created an MSBuild Task NugetContentRestoreTask that will do this trick for you. Run the following command in the Package Manager Console:
Install Nuget Content Restore MSBuild Targets
PM> Install-Package MSBuild.NugetContentRestore
The only thing left is to call it from your BeforeBuild Target with something like this:
Project File Targets
<Target Name="BeforeBuild">
<NugetContentRestoreTask SolutionDir="$(SolutionDir)" ProjectDir="$(ProjectDir)" />
</Target>
You can take a look at the source repo and find it on nuget.org
Additional Content Folders
This nuget only includes the default folders scripts, images, fonts, and content, it is not a recursive directory includes. For additional content subfolders - you must assign the property AdditionalFolders.
<Target Name="BeforeBuild">
<NugetContentRestoreTask SolutionDir="$(SolutionDir)" ProjectDir="$(ProjectDir)"
AdditionalFolders="less;sass;common" />
</Target>
I have found a workaround, but it is ugly. By executing the following command in the NuGet Package Manager Console: Update-Package -Reinstall all the files are indeed copied to their proper places within the Mvc project Content and Scripts directories.
Unfortunately, this is risky because you are likely to end up with the wrong versions of certain packages. For example, in my case after the command finishes executing (which takes quite a while by the way), I end up with jQuery version 1.4.4. This is way old, and I assume it must be an explicit dependency of some other package that is being updated. So it appears that the order in which the packages actually get updated by NuGet is significant (it does not appear to parse the entire dependency tree for all packages and pick only the latest versions from the union of all dependencies, which seems like it would be the preferred behavior). Rather, as the command executes I see it replacing the jQuery package several times with different versions as it works its way through all the packages and their dependencies, only to end up with a very old version.
A similar approach is the execute the Update-Package -Reinstall command explicitly for each package that is causing my problem, but this is incredibly tedious and error prone.
The NuGet Package Restore feature should yield the same result as manually executing the Install-Package or Update-Package -Reinstall command for a package, but it does not.
I don't like to have the thirdparty JavaScript files under source control either. Thats why I've followed Jeff Handley advice in http://nuget.codeplex.com/workitem/2094 to create a solution my self. I didn't go the executable way, but created a nuget solution level package which does the trick.
http://www.nuget.org/packages/Baseclass.Contrib.Nuget.GitIgnoreContent/
It's tied to git, as it automatically updates the .gitignore file.
Short description:
Ignore nuget content files in git:
Generate entries in the .gitignore file to exclude nuget content files from the source repository
Restore nuget content files before building (Automatically in VS and manually with a powershell script
I've written a blog post describing how to use it.
http://www.baseclass.ch/blog/Lists/Beitraege/Post.aspx?ID=9&mobile=0
In Visual Studio 2015 Update 1, they now support contentFiles. The caveat with this is that it only works in projects that use project.json.
In reference to the problem that you are having, there is a good blog post that explains why you see this behaviour: NuGet Package Restore Common Misconceptions.
For my projects it turned out that content files work with PackageReferences only:
Existing project with nuget references via packages.config
Installed NuGet package with content files
Build project
No content files in output directory
Conversion of packages.config to PackageReferences
Build project
Content files have been copied to output directory
IDE is Visual Studio 2017. The project is an application project which means it is in the old csproj format.