How does NuGet contentFiles work? - nuget

I'm trying to create a nuget package with content which work with different kinds of projects.
TestSource.nuspec look like this:
<contentFiles>
<files include="cs\any\TestSource.cs" buildAction="Compile" />
</contentFiles>
</metadata>
<files>
<file src="TestFolder\TestSource.cs" target="content/TestFolder" />
</files>
(the file is available both as contentFiles\cs\any\TestSource.cs and TestFolder\TestSource.cs)
The created package works fine in a "normal" project but nothing happens in a packagereference project.
I assume I'm missing something simple

Found this out myself.
You need to add the file twice in the files section
<contentFiles>
<files include="cs\any\TestSource.cs" buildAction="Compile" />
</contentFiles>
</metadata>
<files>
<file src="TestFolder\TestSource.cs" target="content/TestFolder" />
<file src="TestFolder\TestSource.cs" target="contentFiles/cs/any" />
</files>
The package will then work for both normal and packagereference projects.

Related

nuget contentFiles: is a binary file instead of a text file

Adding a binary file to the "contentFiles" of my nuget package leads to a build error in my C# project.
CSC : error CS2015: '...\0.0.14\contentFiles\any\any\archive.7z' is a binary file instead of a text file [...]
My goal is to have this binary file in my build output folder after dotnet build and dotnet publish.
details:
# .nuspec
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
...
<contentFiles>
<files include="archive.7z" flatten="true" buildAction="None" copyToOutput="true" />
</contentFiles>
</metadata>
<files>
<file src="content/archive.7z" target="contentFiles\any\any" />
</files>
</package>
# folder structure
├───content
│ └───archive.7z
└───.nuspec
# .csproj file
<ItemGroup>
<PackageReference Include="my-nuget-package-name" Version="0.0.14" />
</ItemGroup>
Be sure to add the path to contentFiles "any/any/archive.7z"
<files include="any/any/archive.7z" flatten="true" buildAction="None" copyToOutput="true" />
so the correct .nuspec file should look like this:
# .nuspec
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
...
<contentFiles>
<files include="any/any/archive.7z" flatten="true" buildAction="None" copyToOutput="true" />
</contentFiles>
</metadata>
<files>
<file src="content/archive.7z" target="contentFiles\any\any" />
</files>
</package>

Copy files from the NuGet package to the destination project when installing the nuget package

I'm working on the packaging part of module development and I was able to successfully create the package and install it on the destination site.
But I have an issue with copying files to the module folder in the destination project when installing. It creates some references for folders, not real folders. There are no physical files created in the modules folder in the destination project. But we noticed that it was created in the global NuGet folder on my computer (C:\Users<User>.nuget\packages).
Check the following Screenshots
I'm using Package.nuspec file and .targets file as follows:
Package.nuspec
<?xml version="1.0"?>
<package >
<metadata xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<id>QBankModule6</id>
<version>6.0.74</version>
<title>QBank Module 6</title>
<authors>QBNK AB</authors>
<owners />
<iconUrl>http://nuget.episerver.com/Framework/Styles/images/icons/default_package_icon.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>QBank Module is a module for media support. The module includes a QBank tool for EPiServer.Cms.TinyMce 2.1.1.0 or higher versions and media references. IMPORTANT: After first install, go to Admin mode to initiate QBank.</description>
<tags>EPiServerModulePackage ThirdPartyAddOn Media Images DAM Mediabank Streaming QBank</tags>
<dependencies>
<group targetFramework="net5.0">
<dependency id="EPiServer.CMS.Core" version="[12.0.3, 13)" />
<dependency id="RestSharp" version="106.11.7" />
<dependency id="log4net" version="[2.0.0, 2.9999)" />
<dependency id="HtmlAgilityPack" version="[1.8.4.0, 1.8.4.9)" />
</group>
</dependencies>
<contentFiles>
<files include="any/any/modules/_protected/QBankModule/ClientResources/Scripts/Editors/QBankMediaPicker.js" buildAction="None" copyToOutput="true"/>
<files include="any/any/modules/_protected/QBankModule/ClientResources/Scripts/qbank-connector.js" buildAction="None" copyToOutput="true"/>
<files include="any/any/modules/_protected/QBankModule/ClientResources/Scripts/QBankResponsiveLight-1.0.js" buildAction="None" copyToOutput="true"/>
<files include="any/any/modules/_protected/QBankModule/ClientResources/Scripts/jquery.js" buildAction="None" copyToOutput="true"/>
<files include="any/any/modules/_protected/QBankModule/ClientResources/Styles/qbankplugin.css" buildAction="None" copyToOutput="true"/>
<files include="any/any/modules/_protected/QBankModule/TinyPlugin/editor_plugin.js" buildAction="None" copyToOutput="true"/>
<files include="any/any/modules/_protected/QBankModule/module.config" buildAction="None" copyToOutput="true"/>
<files include="any/any/modules/_protected/QBankModule/lang/QbankModule_lang.xml" buildAction="None" copyToOutput="true"/>
<files include="any/any/modules/_protected/QBankModule/QBankModule.zip" buildAction="None" copyToOutput="true"/>
<files include="any/any/web.config.install.xdt" buildAction="None" copyToOutput="true"/>
<files include="any/any/web.config.uninstall.xdt" buildAction="None" copyToOutput="true"/>
<files include="any/any/QbankApi.dll" buildAction="Compile" copyToOutput="true"/>
<files include="any/any/Qbank.Connector.Core.dll" buildAction="Compile" copyToOutput="true"/>
<files include="any/any/Qbank.Connector.EpiCore.dll" buildAction="Compile" copyToOutput="true"/>
<files include="any/any/Qbank.Connector.EpiCore11.dll" buildAction="Compile" copyToOutput="true"/>
<files include="any/any/Qbank.Connector.EpiServerModule5.dll" buildAction="Compile" copyToOutput="true"/>
</contentFiles>
</metadata>
<files>
<file src="Qbank.Connector.EpiServerModule5/build/QBankModule6.targets" target="lib/net5.0" />
<file src="Qbank.Connector.EpiServerModule5/bin/net5.0/QbankApi.dll" target="lib/net5.0" />
<file src="Qbank.Connector.EpiServerModule5/bin/net5.0/Qbank.Connector.Core.dll" target="lib/net5.0" />
<file src="Qbank.Connector.EpiServerModule5/bin/net5.0/Qbank.Connector.EpiCore.dll" target="lib/net5.0" />
<file src="Qbank.Connector.EpiServerModule5/bin/net5.0/Qbank.Connector.EpiCore11.dll" target="lib/net5.0" />
<file src="Qbank.Connector.EpiServerModule5/bin/net5.0/Qbank.Connector.EpiServerModule5.dll" target="lib/net5.0" />
<!--<file src="Qbank.Connector.EpiServerModule5/ClientResources/Images/qbank-loader.gif" target="contentFiles/any/any/modules/_protected/QBankModule/ClientResources/Images/qbank-loader.gif" />-->
<!--<file src="Qbank.Connector.EpiServerModule5/ClientResources/Images/qbankadd.png" target="contentFiles/any/any/modules/_protected/QBankModule/ClientResources/Images/qbankadd.png" />-->
<file src="Qbank.Connector.EpiServerModule5/ClientResources/Scripts/Editors/QBankMediaPicker.js" target="contentFiles/any/any/modules/_protected/QBankModule/ClientResources/Scripts/Editors/QBankMediaPicker.js" />
<file src="Qbank.Connector.EpiServerModule5/ClientResources/Scripts/qbank-connector.js" target="contentFiles/any/any/modules/_protected/QBankModule/ClientResources/Scripts/qbank-connector.js" />
<file src="Qbank.Connector.EpiServerModule5/ClientResources/Scripts/QBankResponsiveLight-1.0.js" target="contentFiles/any/any/modules/_protected/QBankModule/ClientResources/Scripts/QBankResponsiveLight-1.0.js" />
<file src="Qbank.Connector.EpiServerModule5/ClientResources/Scripts/jquery.js" target="contentFiles/any/any/modules/_protected/QBankModule/ClientResources/Scripts/jquery.js" />
<file src="Qbank.Connector.EpiServerModule5/ClientResources/Styles/qbankplugin.css" target="contentFiles/any/any/modules/_protected/QBankModule/ClientResources/Styles/qbankplugin.css" />
<file src="Qbank.Connector.EpiServerModule5/TinyPlugin/editor_plugin.js" target="contentFiles/any/any/modules/_protected/QBankModule/TinyPlugin/editor_plugin.js" />
<!--<file src="Qbank.Connector.EpiServerModule5/TinyPlugin/Img/qbank.png" target="contentFiles/any/any/modules/_protected/QBankModule/TinyPlugin/Img/qbank.png" />-->
<file src="Qbank.Connector.EpiServerModule5/module.config" target="contentFiles/any/any/modules/_protected/QBankModule/module.config" />
<file src="Qbank.Connector.EpiServerModule5/Lang/QbankModule_lang.xml" target="contentFiles/any/any/modules/_protected/QBankModule/lang/QbankModule_lang.xml" />
<file src="Qbank.Connector.EpiServerModule5/web.config.install.xdt" target="contentFiles/any/any"/>
<file src="Qbank.Connector.EpiServerModule5/web.config.uninstall.xdt" target="contentFiles/any/any"/>
<!--CDN Solution-->
<!--<file src="Qbank.Connector.EpiServerModule5/ClientResources/Images/qbankaudio.png" target="contentFiles/any/any/modules/_protected/QBankModule/ClientResources/Images/qbankaudio.png" />-->
<!--<file src="Qbank.Connector.EpiServerModule5/ClientResources/Images/qbankdocument.png" target="contentFiles/any/any/modules/_protected/QBankModule/ClientResources/Images/qbankdocument.png" />-->
<!--<file src="Qbank.Connector.EpiServerModule5/ClientResources/Images/qbankvideo.png" target="contentFiles/any/any/modules/_protected/QBankModule/ClientResources/Images/qbankvideo.png" />-->
<!--<file src="Qbank.Connector.EpiServerModule5/build/QBankModule6.props" target="build" />-->
<file src="Qbank.Connector.EpiServerModule5/build/QBankModule6.targets" target="build" />
<file src="Qbank.Connector.EpiServerModule5/QbankModule.zip" target="contentFiles/any/any/modules/_protected/QBankModule/QBankModule.zip" />
</files>
</package>
QBankModule6.targets
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<ItemGroup>
<SourceScripts Include="$(MSBuildThisFileDirectory)..\..\contentFiles\any\any\modules\_protected\**\*.*"/>
</ItemGroup>
<Target Name="CopyZipFiles" BeforeTargets="Build">
<Copy
SourceFiles="#(SourceScripts)"
DestinationFolder="$(MSBuildProjectDirectory)\modules\_protected\%(RecursiveDir)"
/>
</Target>
</Project>
Also, I found this post an implemented solutions mentioned in the post. But ended up with the same result.
Basically, I need to understand how to copy some files from the NuGet package to the destination project when installing the nuget package. And also the difference between <files> tag and <contentFiles> tag in nuspec file.
Any input from someone who has experience on this would be great!

nuget not installing file in project\bin directory

Working in VS 2019 .NET framework 4.8
For my C# class library project, I ran nuget spec to create a nuspec file for the dll and its dependencies:
<?xml version="1.0" encoding="utf-8"?>
<package >
<metadata>
<id>MyId</id>
<version>1.0.0</version>
<title>MyTitle</title>
<authors>Me</authors>
....
<dependencies>
<dependency id="dll1" version="1.0.0" />
<dependency id="dll2" version="2.0.0" />
</dependencies>
</metadata>
</package>
No problems building the nuget package. In my consuming project (MyProject), I installed that package, and after building MyProject, the class library dll and the dependency files are placed in the MyProject\bin directory. Great.
However I need to get another file into directory MyProject\bin, let's call that file MyFile.txt. I first tried using the element:
.....
<dependency id="dll2" version="2.0.0" />
</dependencies>
</metadata>
<files>
<file src="MyFile.txt" target="lib" />
</files>
</package>
No luck. While the file is in the packages\lib folder, it does not get placed in MyProject\bin.
I then removed the element and tried the element within the tag:
.....
<contentFiles>
<files include="MyFile.txt" buildAction="None" copyToOutput="true" flatten="true" />
</contentFiles>
</metadata>
</package>
No luck that way either. Is there a way to accomplish what I need to do? It looks like it may involve having some folders in my class library root folder, but not sure what folders (content?) or how to properly reference them in the nuspec file. Thanks.
Neglected to update this post with the answer I found.
Using the <files><file /></files> logic is what solved it. It involved the use of the target attribute and using the content keyword in the value:
<files>
<file src="content\bin\MyFile.txt" target="content\bin" />
</files>
It's in the documentation, I unfortunately missed that even upon multiple readings. See https://learn.microsoft.com/en-us/nuget/reference/nuspec#dependencies-element

Reference nuspec id elsewhere in the nuspec file?

I have a nuspec file defined like so:
<?xml version="1.0"?>
<package>
<metadata>
<id>PSP.Build.Vcs.Svn</id>
</metadata>
<files>
<file src="tools\**\**\**\PSP.Build.Vcs.Svn\Set-BuildNumber.psm1" target="tools" />
</files>
</package>
As you can see the id is "PSP.Build.Vcs.Svn" and that same literal is repeated in the file element. In the interests of DRY, is it possible to reference the id elsewhere in the nuspec file? I'm imagining something like the following (even though this didn't actually work):
<?xml version="1.0"?>
<package>
<metadata>
<id>PSP.Build.Vcs.Svn</id>
</metadata>
<files>
<file src="tools\**\**\**\$(id)\Set-BuildNumber.psm1" target="tools" />
</files>
</package>
I suspect the answer is no, but just thought I'd ask.
TIA
if you have setup your build process such as that the value of $id$ is PSP.Build.Vcs.Svn then you could replace that with $id$.
See http://docs.nuget.org/Create/Nuspec-Reference#replacement-tokens

Packaging SQL files only using Nuget.exe

Is there a way to package a folder of only .SQL files instead of having to add them to a project using Nuget.exe?
I know you can specify folders inside the nuspec, but what is the process of doing so? I've only been able to make packages from using .net project/applications.
For example, If I create a nuspec inside called Database.nuspec
F:\folder\trunk\Source\Database.nuspec
inside the folder
F:\folder\trunk\Source\Database
and I want to package up my patch scripts folder
F:\folder\trunk\Source\Database\Patch Scripts
and inside that folder I had
F:\folder\trunk\Source\Database\Patch Scripts\2.0
F:\folder\trunk\Source\Database\Patch Scripts\2.1
F:\folder\trunk\Source\Database\Patch Scripts\2.2
Would I need to include these folders inside of my nuspec or is nuget.exe smart enough to package them up for me?
E.G
Update:
Solution 1:
would be to include each folder to the nuspec
<files>
<file src="F:\folder\trunk\Source\Database\*.sql" target="Database" />
<file src="F:\folder\trunk\Source\Database\Patch Scripts\*.sql" target="Database\Patch Scripts\" />
<file src="F:\folder\trunk\Source\Database\Patch Scripts\2.0\*.sql" target="Database\Patch Scripts\2.0" />
</files>
But I have a lot of patch files and it will be quite tedious to write out about 40 into a nuspec, I will update if I find a work around.
Solution 2:
ufuk-haciogullari suggested using
*\*.sql
as the source since they are one level down, and this does what I want, but I need to keep the file structure intact, If i were to just write
<files>
<file src="F:\folder\trunk\Source\Database\*.sql" target="Database" />
<file src="F:\folder\trunk\Source\Database\Patch Scripts\*\*.sql" target="Database\Patch Scripts" />
</files>
it will store all the returns into the target Database\Patch Scripts\ and this isn't the structure I want.
Update:
<?xml version="1.0" encoding="utf-8" ?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>database</id>
<version>1.0.6</version>
<authors>me</authors>
<description>Description</description>
</metadata>
<files>
<file src="F:\folder\trunk\Source\Database\*.sql" target="Database\" />
<file src="F:\folder\trunk\Source\Database\Patch Scripts\**\*.sql" target="Database\Patch Scripts" />
</files>
This packages my solution and stores the files as they were in the previous format.
nuget.exe pack "F:\folder\trunk\Source\Database\database.nuspec" -OutputDirectory F:\NuGetStore
UPDATE:
Coming back to this, if you leave the target blank in it will re-create the same folder structure that is already in place, so you don't need to create directories.
<?xml version="1.0" encoding="utf-8" ?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>database</id>
<version>1.0.6</version>
<authors>me</authors>
<description>Description</description>
</metadata>
<files>
<file src="F:\folder\trunk\Source\Database\*.sql" target="" />
<file src="F:\folder\trunk\Source\Database\Patch Scripts\**\*.sql" target="" />
</files>
This packages my solution and stores the files.
nuget.exe pack "F:\folder\trunk\Source\Database\database.nuspec" -OutputDirectory F:\NuGetStore
You can create a nuspec file and state those files explicitly.
<?xml version="1.0" encoding="utf-8" ?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MyPackage</id>
<version>1.0.0</version>
<authors>me</authors>
<description>Description</description>
</metadata>
<files>
<file src="*.sql" target="Content\SqlFiles" />
</files>
</package>
Then run pack command on the nuspec file.
NuGet.exe pack MyPackage.nuspec