Building content only/dependency meta package using csproj and nuget (teamcity build) - nuget

I have a project that pulls in dependencies and adds some code templates, but isntalling the resulting nuget causes my project to get polluted by an empty dll.
I tried making a .nuspec, but I find the documentation lacking on this topic.
I ran nuget spec and deleted the irrelevant metadata, then added a files section, with a single file entry:
<file src="src/*.pp" target="dst/" />
But the resulting .nuget still contains an empty dll under lib/net462.
The pp file is placed into Content/src in the nuget, but I am guessing the target will be applied properly when installed.

Related

Nuget does not include ancillary (license) files in output

We are using nuget to package an older library (dll) file for use in our enterprise nuget share. We have done this successfully with numerous other libraries.
With the current one I'm packaging, there is a license file (.lic file) that must be copied along with the dll and xml files, but which is not getting included with the build output. Here is my <files> section from .nuspec:
<files>
<file src="Lic\test.lic" target="lib" />
<file src="net4.0\test.dll" target="lib" />
<file src="net4.0\test.XML" target="lib" />
</files>
This results in all three files being packaged in the lib folder of .nupkg file (as expected). However, when the consuming project is built, the .lic file is missing from the \bin folder:
licence file missing from output
I've tried many variations of the <file> tag, and have even tried variations of the <contentFiles><files...> tag.
Does anyone have any idea how to get the .lic file to be copied with the compiled output?
Edit 6/30/2020:
Ok I have tried the technique suggested by #thatguy, but it is not working. The .lic file is not getting included in the bin folder when the project is compiled; it is not even referenced in the .nupkg file when I unzip it.
I verified my visual studio project is using PackageReferences by opening the project file. That the .lic file is missing from the .nupkg suggests an error in the .nuspec file content. Here is screenshot of my nuspec file. Is there still something awry with the tags or content?
Screenshot of my .nuspec content
If you use PackageReference instead of packages.config, then you can use the contentFiles tag. It has to be contained in the metadata tag. Place content files like test.lic in a subfolders any\any\, otherwise it will not work. The following snippet will cause the content files to be copied to the output folder when building the project.
<contentFiles>
<files include="any/any/test.lic" buildAction="None" copyToOutput="true" />
</contentFiles>
You can upgrade existing .NET Framework projects to use PackageReference. .NET Core projects will have it by default. If you cannot upgrade or you do not want to use contentFiles because of its contraints, you can also use props and targets files for MS Build. One the one hand, it is much more complex to implement and get right, on the other hand, it offers maximum flexibility and enable you to use features of MS Build which is much more beyond copying files. You can find an example for your use-case here.

Nesting files in Nuget package without PowerShell

The title says it all. I have files that I want to nest during the installation of a NuGet package but can't use PowerShell scripts since they won't be run any longer (see here).
Are there any other ways to achieve this goal?
UPDATE: By nested I mean like *.resx and *.Designer.cs or *.xaml and code-behind files *.xaml.cs. I know I can achieve that by adding a <DependentUpon> element in the *.csproj file but I don't know how I can add that element without using PowerShell.
UPDATE2: init.ps1 runs the first time a package is installed in a solution. That won't cut it though. I would need the script to run when the package is installed into a project just like install.ps1 was run up to NuGet3.
UPDATE3: What I want to do is to add 3 files into the Properties folder of the target projects (Resources.resx, Resources.tt and Resources.Designer.cs). They are a replacement for the usual resources implementation. These files are installed by the nuget package when it is added to the project.
This is the part of the *.nuspec file that adds them to the Content folder of the package. As only one of them is actually content (the others being an Embedded Resource and Compile respectively) it would be nice to be able to set their build actions accordingly but one step at a time.
<files>
<file src="Properties\Resources.resx" target="content\Properties\Resources.resx" />
<file src="Properties\Resources.tt.pp" target="content\Properties\Resources.tt.pp" />
<file src="Properties\Resources.Designer.cs" target="content\Properties\Resources.Designer.cs" />
</files>
As these files are added to the projects I want the nesting inside the *.csproj file and not happen via a separate *.props file if that is somehow possible.
Packages can add MSBuild items like this to a project by using a .props file in the package. It would contain the same content that you would put into the .csproj file.
The down side of this is that the content cannot be modified by the user. If you need to modify the user's actual project file and copy content to the project folder you would have to include a .targets file in your package and set BeforeTargets="Build" on your target. This would give you a chance to run before build and make changes as needed.
The build folder works for both packages.config and PackageReference (NETCore SDK) projects. You can find more out about it here: https://learn.microsoft.com/en-us/nuget/create-packages/creating-a-package#including-msbuild-props-and-targets-in-a-package

Automated injection of props/targets files not working for native C++ project

I am using automatic package restore in NuGet v2.8.50506.491 with Visual Studio 2013.
I have added a build folder to my package with a {package ID}.props file. However, the file is apparently not being injected into the vcxproj at restore time. The package and all its content are being restored correctly but none of the definitions are visible in vcxproj properties. This may be expected if property injection occurs in memory, but the build fails due to paths that are clearly defined in the props not having been inherited.
If I add an explicit reference to the props file in my local packages repository, the project builds successfully, therefore there is no issue with the paths in props file.
I have also tried adding the props within a "native" subfolder under build, also to no avail.
An extract from the nuspec:
<file src="build\MyPackage.targets" target="build\MyPackage.targets" />
I have also tried a targets file instead of/as well as a props file, but this does not work either.
I should add that I have defined Nuget.config in the sln folder, with an absolute path to my packages repository:
<config>
<add key="repositoryPath" value="C:\Packages" />
</config>
I was having this problem today, and eventually I realized that the names of my .nuspec and .targets files were different than the id of my package, which is apparently a problem. Renaming the .nuspec and .targets files to match the package id made NuGet start injecting into the vcxproj correctly. I'm not sure which of the two files was the problem, or if it was both, but it's working correctly now that all three names match.
Injection of .targets and .props file references happens only at the time when you install the NuGet package. This is the same as with .NET projects where assembly references are created only at package install time.
Later when you build the project the package restore mechanism merely downloads and extracts the NuGet package so that the previously "dangling" .target / .props / assembly references become valid references.

Build a NuGet package from project but without any references

I have created a T4 template that I want to reuse in several projects using NuGet. This template is based on a custom class so I need to distribute a DLL with the template. The DLL is used by the template during generation, but is not used by the project itself so I do NOT want it added to the target project as a reference.
My .nuspec file includes my DLL and places it in the root of the package which will prevent it from creating a reference and everything works fine if I build my package by hand. Unfortunately, I want to use the "nuget pack" command to automatically pick up the version number. When I run this command and reference the project file, it includes my DLL twice, once in the root (as I specified in my nuspec file) and an additional time in the lib folder (along with everything in the bin folder).
How can I automatically build my NuGet package without including any references. It seems there are several solutions, but I can't figure any of them out:
Let nuget include my DLL in the lib folder, but prevent it from creating the reference. I know I can use the <references> section to reference some DLLs and not others, but in this case I don't want it to reference any. If I leave the <references> section blank it is either ignored or I get an error depending on what level I leave blank.
Prevent nuget from including any DLLs automatically and only include the files in the <files> section of the nuspec file. Unfortunately, I can't figure out how to build the package from the project file without it including my DLL automatically.
Any thoughts?
If you right-click the DLL, you'll probably see that its "build action" is set to "content". Try setting it to "none".

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.