How to prevent nuspec token replacement on package install - nuget

I have a nuspec template file (template.nuspec.pp) in the content folder of a Nuget package. When the package is installed, I modify the name of the nuspec file using an install.ps1 script to match the targeted assembly. I want the contents of the nuspec file to remain unchanged:
<?xml version="1.0"?>
<package>
<metadata>
<id>$rootnamespace$</id>
<version>$version$</version>
<title>$rootnamespace$</title>
<authors>$author$</authors>
<!--<iconUrl></iconUrl>-->
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>$rootnamespace$</description>
<copyright>$copyright$</copyright>
<tags></tags>
</metadata>
</package>
The replacement tokens are replaced immediately on installation, however - I was under the impression this should happen only when nuget pack is called. Why is this happening, and what need I do to prevent it?
In case folks wonder, my install.ps1 file is not touching the contents of the nuspec template.

Looks like the whole point of the .pp suffix is to denote that any variable enclosed by $ is replaced on package install. When I removed the .pp suffix, the files were then ignored by Nuget and not added to the content folder. In order to circumvent this, I had to add a non .pp suffix to the file (I used .txt) and then renamed it using an install.ps1 script in my tools folder.

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.

Output Directory of native dll bundled with NuGet

I am trying to build a NuGet package that includes native DLLs which are to be placed in the output folder when a project uses the package. I have tried to use the several suggestions from this question, but I am always running in the same problem.
My current NuGet package layout is like this:
\build
packageId.targets
file1.dll
file2.dll
\lib
\netstandard1.4
assembly.dll
The contents of packageId.targets is:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<NativeLibs Include="$(MSBuildThisFileDirectory)\*.dll"/>
<None Include="#(NativeLibs)" Link="$(RecursiveDir)$(Filename)$(Extension)">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
This should, according to the answers of the other questions, lead to my DLLs being placed in the bin\Debug directory of the project using the package. However, they are not. Instead, they are placed in bin\Debug\packages\packageId\build.
Now I have experimented a lot, and I noticed more and more strange behavior which I cannot make any sense of:
If I move the DLLs to the root of the NuGet package (like one answer suggests) and change the .targets file accordingly, they are not copied at all. There also is no error message.
If I change the .targets file to only reference file1.dll in both Include= and Link=, both files get copied anyway.
So I wondered if some policy just ignores the .targets file and copies whatever is in build to that path in the output folder, but when I remove the .targets file, the DLL files will not get copied anymore.
Now I understand even less what's happening.
What do I need to change to get the DLLs copied right into bin\Debug?
The new way to handle runtime-specific assents in NuGet is to use the runtimes folder to place native assets:
\lib
\netstandard2.0
ManagedWrapper.dll
\runtimes
\win-x86
\native
NativeThing.dll
\win-x64
\native
NativeThing.dll
\linux-x64
\native
libNativeThing.so
\osx-x64
\native
libNativeThing.dylib
If the package is consumed from a .NET Framework project, you may need to add a reference to the Microsoft.NETCore.Platforms package wich provides the runtime graph (runtimes.json) for NuGet to provide proper RID mappings if you don't use base RIDs (e.g. win10-x64 falls back to win-x64 resources).

Is there an alternative to contentFiles with projects that use packages.config?

I have a nuget package with content that I want to be copied to the build output when users install my package. There is support for this: NuGet ContentFiles Demystified in NuGet v3.3. However, it only works in projects that use project.json. The contentFiles are not copied to my build output when I have a project that uses packages.config.
Is there an alternative or workaround I could use in order to make my NuGet package work on projects that use either a project.json or packages.config?
A quick search on StackOverflow reveals the following question which I think covers what you are asking for:
Set content files to "copy local : always" in a nuget package
You can put your files inside a Content directory inside the NuGet package.
In your .nuspec file:
<file src="css\mobile\*.css" target="content\css\mobile" />
When you install that into your project it will add the css\mobile directory to your project and the files inside that directory.
However that only adds the files to the project. In order to get them to be copied to your output directory you would either need to use a PowerShell script to modify the project item's copy local information.
An alternative, possibly a better way, would be to use a custom MSBuild .targets file. This will be added as an import to your project and then inside your .targets file you can add the files you want and specify the copy to output information directly as though it was part of your project. NuGet .nupkg file content:
\build
\Net45
\MyPackage.targets
\Foo.txt
MyPackage is the id of the NuGet package above.
Inside the .targets file you specify the files (e.g. Foo.txt).
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<None Include="Foo.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

Suppress warning output from Nuget.exe

I'm wondering if I can suppress warning messages in the output from the nuget.exe pack command? Specific messages would be awesome, but I can live with suppressing all of them.
The nuget command line documentation mentions a Verbosity flag, but never really specifies what the valid values for that are. I've tried the following:
nuget pack mypackage.nuspec -Verbosity Quiet
But doesn't seem to do anything.
Here is an example of the nuspec I'm trying to pack:
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>MyPackage</id>
<version>1.0.0</version>
<authors>Administrator</authors>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>My package description.</description>
</metadata>
<files>
<file src="mysourcepath\foo.dll" target="mytargetpath\foo.dll" />
</files>
</package>
The warning message I get is this:
WARNING: 1 issue(s) found with package 'MyPackage'.
Issue: Assembly outside lib folder.
Description: The assembly 'mytargetpath\foo.dll' is not inside the 'lib' folder and hence it won't be added as a reference when the package is installed into a project.
Solution: Move it into the 'lib' folder if it should be referenced.
I'm creating a nuget package that will be deployed as an application via an Octopus server. The assemblies in this dll do NOT need to be referenced by anything - this package should never be referenced as part of a build (we have other more logical packages for that).
I want to suppress this warning because the actual package I'm creating has thousands of files, none of which are in the lib folder. The output noise from this one warning is making it difficult to see any other legitimate warnings I might be interested in.
UPDATE: This package is packed from a custom nuspec file - it consists of the output of hundreds of projects, so specifying a project file is not a viable option for eliminating the warning. FWIW, specifying a project file does eliminate the warning, because it ends up putting the project output into a lib folder - which is what I'm trying to avoid.
TIA for any input.
First of all, nuget reference clearly specifies what the valid values are for Verbosity.In the link you have provided under the pack command section:
Display this amount of details in the output: normal, quiet, (v2.5) detailed.
Try packing your project file instead of .nuspec file if possible, use lowercase for quiet flag and use -NoPackageAnalysis:
nuget pack myproject.proj -Verbosity quiet -NoPackageAnalysis
The -nopackageanalysis flag will suppress the warning, even when using a .nuspec file.
You might also consider using Octopack, if it's an option. Octopack was designed to create packages specifically for Octopus Deploy (i.e., no lib folder, no spurious warning messages, etc.) It uses NuGet under the hood so you can still use it with a .nuspec file as well.
You can pass specific properties into the NuGet CLI, including "NoWarn":
nuget.exe pack package.nuspec -Properties NoWarn=NU5104
https://learn.microsoft.com/en-us/nuget/reference/cli-reference/cli-ref-pack#suppressing-pack-warnings

nuget pack with symbols is missing "content" directory

I'm using nuget to package up some assemblies and additional files.
I need to keep the symbols separate, so I'm using "nuget pack -symbols" which creates two separate nupkg files.
The problem I have is that the .symbols.nupkg package only contains the "lib" directory (with PDBs and DLLs). It is missing "tools" and "content".
This means when someone installs the .symbols.nupkg, they don't get the extra files underneath "content". And because .symbols.nupkg has the exact same package id as the main .nupkg, nuget won't ever install the main package which does have "content" in it.
It's the same nuspec file which creates both packages, so I can't control it there.
Am I doing something wrong, or misunderstanding how the symbols package should be used?
The problem is - *.symbols.pckg are meant to be kept on www.symbolsource.org ( or a local symbols feed)
Sumbols.pckg does not replace a real package. It's an addon.
Publish your package to nuget feed and symbol package to symbols feed.
But you actually can include pdb files in packet. Add this to nuspec file
<files>
<file src="bin\$configuration$\$id$.pdb" target="lib\net45\" />
</files>