nuspec contentFiles Example - nuget

Yesterday NuGet 3.3 was released (release notes) and there is a new contentFiles element supported (docs). However, I can't seem to get this working.
I'm using the NuGet.exe as the build process. It is updated to v3.3. I have also updated my Visual Studio to 2015 Update 1 and rebooted.
Here is my nuspec file (Hello.world.nuspec):
<?xml version="1.0" encoding="utf-8"?>
<package>
<metadata minClientVersion="3.3">
<id>Hello.world</id>
<version>1.0.0</version>
<title>Greeting library</title>
<authors>Timothy Klenke</authors>
<description>Greetings for the world</description>
</metadata>
<contentFiles>
<files include="*" />
</contentFiles>
</package>
I run from the command line using the following:
nuget.exe update -Self
nuget.exe pack Hello.world.nuspec
And I get the following:
MSBuild auto-detection: using msbuild version '14.0' from 'C:\Program Files (x86)\MSBuild\14.0\bin'. Attempting to build package from 'Hello.world.nuspec'. The element 'package' in namespace 'http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd' has invalid child element 'contentFiles' in namespace 'http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd'. List of possible elements expected: 'files' in namespace 'http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd'.
I think I am running all the latest versions that should support the new contentFiles XML element, but the tools don't seem to know about it. What am I missing? I know the files include attribute is garbage, but does someone have a full example nuspec file using the new contentFiles element?

Element <contentFiles> has to be inside <metadata> according to NuSpec reference. So it should look like this:
<?xml version="1.0" encoding="utf-8"?>
<package>
<metadata minClientVersion="3.3">
<id>Hello.world</id>
<version>1.0.0</version>
<title>Greeting library</title>
<authors>Timothy Klenke</authors>
<description>Greetings for the world</description>
<contentFiles>
<files include="*" />
</contentFiles>
</metadata>
</package>

#Timothy,
You were right. It is a combination having a metadata/contentFiles element as well as a definition in the files element. I have a C# test utility library that needs to include PowerShell files in a projects output/bin folder when it is referenced using a PackageReference. I will include the XML below for you. I think you will be able to derive what you need from it.
Special Note:
Be sure to get your language and framework values right in the path (i.e. yours will something like cs/net45/YourFile.cs). I'm using any/any/MyFile.psm1 because I want the file to be treated as language and platform agnostic. If I don't, I get code analysis errors on build.
Additionally, placing the files in a 'contentFiles' directory is important.
(language and framework options defined in the .nuspec reference documentation)
https://learn.microsoft.com/en-us/nuget/reference/nuspec#including-content-files
<package>
<metadata>
<id>SomeLibrary</id>
<version>$version$</version>
<title>SomeLibrary</title>
<authors>Somebody</authors>
<owners>Somebody</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Some library that does things I enjoy.</description>
<releaseNotes />
<copyright>Copyright 2017</copyright>
<tags>PowerShell Testing</tags>
<contentFiles>
<files include="any/any/SomePS.psd1" buildAction="none" copyToOutput="true" />
<files include="any/any/SomePS.psm1" buildAction="none" copyToOutput="true" />
</contentFiles>
</metadata>
<files>
<file src="*.dll" target="lib\net461" />
<file src="*.pdb" target="lib\net461" />
<file src="SomePS.psd1" target="contentFiles\any\any" />
<file src="SomePS.psm1" target="contentFiles\any\any" />
</files>
</package>

The "/" matters in the node. It will not work if used:
<files include="any/any/x.dll" buildAction="None" copyToOutput="true" flatten="true" />
It must be:
<files include="any\any\x.dll" buildAction="None" copyToOutput="true" flatten="true" />
But it doesn't work for .NET framework??!

Related

Getting the contents files of the nuget package copied to the output directory

Requirement:
We've set of pdf files which should be copied to build directory. We're trying to make a nuget package with these files.
nuspec file used for generating the nuget package:
`<package>
<metadata>
<id>PACKAGE</id>
<version>1.0.2</version>
<title></title>
<authors>AUTHOR</authors>
<owners>OWNER</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description></description>
<contentFiles>
<files include="contentfiles/*.pdf" buildAction="None" copyToOutput="true" />
</contentFiles>
</metadata>
<files>
<file src=".\*.pdf" target="contentFiles" />
</files>
</package>`
Nuget.exe version used for packing: 4.8.1.5435
Methods we tried:
Using Install.ps1 & Uninstall.ps1 powershell scripts (Seems like its not supported now)
Playing around with buildAction attribute and copyToOutput attribute
** We won't specify these in lib directory since these are plain files which is required in different apps targeting different .net frameworks and .net core.

Nuspec buildAction not applying to contentFiles

I've been recently trying to create a .nuspec file that attaches a .dll file as an Embedded Resource. To do so, I've used the contentFiles tag on metadata, setting the buildAction="EmbeddedResource", as described in the section Example contentFiles section on the official documentation.
Below you can see my .nuspec file content:
<package>
<metadata>
<id>MyPackage</id>
<version>1.0.0.0</version>
<title>MyPackage</title>
<authors>Matias G Henschel</authors>
<owners>Matias G Henschel</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>My package description</description>
<copyright>2017</copyright>
<contentFiles>
<files include="myDllFile.dll" buildAction="EmbeddedResource" />
</contentFiles>
</metadata>
<files>
<file src="content\myDllFile.dll" target="contentFiles" />
</files>
</package>
This package correctly copies the file inside the target project, but it doesn't apply the Build Action to it, which is crucial for me.
I've also tried using a .targets file, with no success.
If you want to see more, I've also created an Issue on the GitHub page.
PS: IMHO, both documentation on contentFiles and .targets files require some rework, they aren't clear enough and .targets' lacks examples.
You also need a file entry to actually copy the file to the correct contentFiles folder:
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
<metadata>
…
<contentFiles>
<files include="any/any/MyEmbeddedFile.txt" buildAction="EmbeddedResource" />
</contentFiles>
</metadata>
<files>
<file src="path/to/MyEmbeddedFile.txt" target="contentFiles/any/any/MyEmbeddedFile.txt" />
</files>
</package>
Note that this will only work in NuGet 3.3+ with project.json based projects and NuGet 4+ for PackageReference based projects. For projects using this package via packages.config, you will still need to add the file to the content folder and add a custom target to make it the right item type.

NuGet does not copy content and does not run install.ps1

I am trying to create a Nuget package using NuGet.exe 1.2.20311.3, and the following specification:
<?xml version="1.0" encoding="utf-8"?>
<package xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<metadata>
<id>SharedWebsitesMvc</id>
<version>1.0.16</version>
<authors>Ted</authors>
<owners>Ted</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Shared Websites Mvc Library</description>
<frameworkAssemblies>
<frameworkAssembly assemblyName="mscorlib" targetFramework=".NETFramework4.6" />
<frameworkAssembly assemblyName="System" targetFramework=".NETFramework4.6" />
<frameworkAssembly assemblyName="System.Core" targetFramework=".NETFramework4.6" />
<frameworkAssembly assemblyName="Microsoft.CSharp" targetFramework=".NETFramework4.6" />
</frameworkAssemblies>
</metadata>
<files>
<file src="D:\Projects\Websites\SharedWebsitesMvc.dll" target="lib\net46\SharedWebsitesMvc.dll" />
<file src="D:\Projects\Websites\SharedWebsitesMvc.xml" target="lib\net46\SharedWebsitesMvc.xml" />
<file src="D:\Projects\Websites\Scripts\backtalk.js" target="js\backtalk.js" />
<file src="D:\Projects\Websites\Scripts\shared.js" target="js\shared.js" />
<file src="D:\Projects\Websites\SharedWebsitesMvcInstall.ps1" target="tools\Install.ps1" />
</files>
Nuget generates a package, and package explorer shows the following:
js
backtalk.js
shared.js
lib
net46
SharedWebsitesMvc.dll
SharedWebsitesMvc.xml
tools
Install.ps1
The Install.ps1 looks like this:
param($installPath, $toolsPath, $package, $project)
Write-Host "hello from install.ps1"
When I install this package into an MVC project, the script files are not copied and no output is displayed from the script in the package console. I am using Visual Studio 2016.
What is wrong with my NuGet specification?
The JavaScript files need to have a target that starts with Content:
<file src="D:\Projects\Websites\Scripts\backtalk.js" target="Content\js\backtalk.js" />
<file src="D:\Projects\Websites\Scripts\shared.js" target="Content\js\shared.js" />
The above does not support project's that use a project.json file. For those you need to use a ContentFiles section in your .nuspec file:
<contentFiles>
<files include="D:\Projects\Websites\Scripts\backtalk.js" buildAction="None" />
</contentFiles>
The .nuspec file looks OK for the install.ps1 PowerShell script for projects that use a packages.config file. Note that install.ps1 is not supported in projects that use project.json files.

How to include content files in project if resources are specified in nuspec file?

I am creating a nuget package definition to include a whole bunch of DLLs. Some of them are needed only at design time, so according to the Nuspec Reference I created a references section to specify which assemblies should be referenced by the project.
I also specified a list of files to be included. Some of these files being the libraries, one is a PowerShell script that gets executed during package installation and one is simply a content file that should be added to the project lateron.
These are the relevant sections of my nuspec file:
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<!-- Most of the metadata stuff left out for brevity -->
<dependencies />
<references>
<reference file="MyComponent.dll" />
<reference file="MyComponent.Data.dll" />
<reference file="MyComponent.Other.dll" />
</references>
</metadata>
<files>
<file src="MyPackage.install.ps1" target="tools\install.ps1" />
<file src="MyComponent.ReadMe.txt" target="ReadMe.txt" />
<file src="C:\Some\Path\MyComponent.*.dll" target="lib\net45" />
<file src="C:\Some\Path\MyComponent.*.xml" target="lib\net45" />
<file src="C:\Some\Other\Path\*.dll" target="lib\net45" />
</files>
</package>
Now here is my problem: The licenses.licx file does not get included in the project when the package is being installed. What must I change to achieve this?
Adding it to the references section does not work, because, well, it is no library...
I found out what was wrong. To include a file into the targeted project the file needs to be placed in a sub-folder named content in the package's folder structure:
The correct files section of the nuspec file would then look like this:
<files>
<!-- other files omitted for brevity -->
<file src="MyComponent.ReadMe.txt" target="content\ReadMe.txt" />
</files>

Issue with nuget config transformation files

I am creating a nuget package that besides other files contains also configuration files such as: f1.config, f2.config etc. These configuration files are in turn referenced in the web.config file.
As these configuration files may or may not exist in the project where this package would be installed, I have renamed them to f1.config.transform, f2.config.transform.
While the installation of the package runs flawlessly in all possible scenarios, uninstalling is not working as expected in one particular case. Namely, if let say the config file f2.config did not exist in the project before the installation, it will not be removed when uninstalling the package.
Any ideas?
EDIT: NuGet spec file
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>WCFServicesProxyPackage</id>
<version>1.0.3</version>
<title />
<authors>Shkelzen a. Saraqini</authors>
<owners>Shkelzen a. Saraqini</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>WCF services proxy package.</description>
<language>en-CA</language>
<references>
<reference file="WCFServices.Proxy.dll" />
</references>
</metadata>
<files>
<file src="content\config\system.serviceModel.behaviors.Local.config.transform" target="content\config\system.serviceModel.behaviors.Local.config.transform" />
<file src="content\config\system.serviceModel.behaviors.Production.config.transform" target="content\config\system.serviceModel.behaviors.Production.config.transform" />
<file src="content\config\system.serviceModel.behaviors.QA.config.transform" target="content\config\system.serviceModel.behaviors.QA.config.transform" />
<file src="content\config\system.serviceModel.bindings.Local.config.transform" target="content\config\system.serviceModel.bindings.Local.config.transform" />
<file src="content\config\system.serviceModel.bindings.Production.config.transform" target="content\config\system.serviceModel.bindings.Production.config.transform" />
<file src="content\config\system.serviceModel.bindings.QA.config.transform" target="content\config\system.serviceModel.bindings.QA.config.transform" />
<file src="content\config\system.serviceModel.client.Local.config.transform" target="content\config\system.serviceModel.client.Local.config.transform" />
<file src="content\config\system.serviceModel.client.Production.config.transform" target="content\config\system.serviceModel.client.Production.config.transform" />
<file src="content\config\system.serviceModel.client.QA.config.transform" target="content\config\system.serviceModel.client.QA.config.transform" />
<file src="content\Web.config.transform" target="content\Web.config.transform" />
<file src="lib\net40\WCFServices.Proxy.dll" target="lib\net40\WCFServices.Proxy.dll" />
</files>
</package>
How do you install/uninstall the config files? Could you share some PowerShell snippets from your scripts (assuming you're using PowerShell install.ps1/uninstall.ps1 scripts in your package)?
Maybe you can force the removal of the files: http://www.timvw.be/2011/10/18/force-the-removal-of-a-file-with-powershell/
Also, it is likely this functionality will be improved in the future, if and when XDT becomes OSS for NuGet to benefit from it.