Copy files to bin folder with .nuspec files - nuget

I have .nuspec file to create my package which contains nothing but a folder with text and other format files. I pack the folder like this:
<files>
<file src="myData\**\*.*" target="content" copyToOutput="true" />
</files>
When I install the nuget package I want this folder to be in my bin folder/output folder so that my program can relatively reference the files present. How can I achieve this since my nuget package doesn't have any .csproj to have .target file to copy files?

This isn't the exact answer to your question, but I am not sure if you can achieve this without a .target file. As a workaround, you can create an empty .csproj with a .target file which shall copy the items of your content folder:
<Project>
<Target Name="CopyToDeployFolder" AfterTargets="Build">
<Exec Command="xcopy.exe $(MSBuildThisFileDirectory)\..\content $(OutputPath) /e /y /i /r" />
</Target>
<Target Name="CopyToPublishFolder" AfterTargets="Publish">
<Exec Command="xcopy.exe $(MSBuildThisFileDirectory)\..\content $(PublishDir) /e /y /i /r" />
</Target>
</Project>

Related

Include non-Solution items in Nuget package

I have created a Nuspec file with the following files elements:
<files>
<file src="lib\" target="lib" />
<file src="tools\" target="tools" />
<file src="content\" target="content" />
<file src="other-stuff\" target="content" />
</files>
When I restore this Nuget package to any project, the contents of the other-stuff folder is added to the project (as expected).
Is there any way to ensure this content is placed on the filesystem, but not added to the project / solution? I don't want this content to show in Visual Studio.
There is no way to create a folder with no content in the nuspec file. However, you can definitely do this using a install.ps1 file. You can find many examples by searching for "nuget install.ps1" and utilizing powershell code to create a directory.

Add install.ps1 on Class Library (.NET Standard) Project

I have migrate my .NET Framework project to a .NET Standard project.
In the .NET Framework project i have a .nuspec file with additional file config and create the nuget package with "NuGet.exe pack"
<files>
<file src="Install.ps1" target="tools\Install.ps1" />
</files
In the .NET Standard project i have not longer a nuspec file and switch to "msbuild -t:Pack" to create the nuget package. I have try to set the install.ps1 to (BuildAction = Content) but then i see a warning in the log "Issue: PowerShell file out side tools folder." And in the nupkg file the directory is "content\tools\Install.ps1" i need "tools\Install.ps1".
To get file into a different path in the package you can use the <PackagePath> element in the <Content> element like this:
<ItemGroup>
<Content Include="install.ps1">
<PackagePath>tools\</PackagePath>
</Content>
</ItemGroup>
(providing the install.ps1 is in the root of your project, otherwise you'll have to adjust the Include attribute value)
For more information check out the docs about the pack MsBuild Target here:
https://github.com/NuGet/Home/wiki/Adding-nuget-pack-as-a-msbuild-target
I have try to set the install.ps1 to (BuildAction = Content) but then i see a warning in the log "Issue: PowerShell file out side tools folder." And in the nupkg file the directory is "content\tools\Install.ps1" i need "tools\Install.ps1"
When you use msbuild -t:Pack to create the nuget package, msbuild/VS expects the files to be in content folder. But if you still want to the install.ps1 file in the tools directory, you can still use the .nuspec file and nuget.exe to pack the package.
The detail steps to pack package:
Create the .nuspec as below settings:
<?xml version="1.0"?>
<package >
<metadata>
<id>TestInstall.ps1</id>
<version>1.0.0</version>
<authors>Test</authors>
<owners>Test</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Package description</description>
<releaseNotes>Summary of changes made in this release of the package.</releaseNotes>
<copyright>Copyright 2017</copyright>
<tags>Tag1 Tag2</tags>
</metadata>
<files>
<file src="Install.ps1" target="tools" />
<file src="bin\Debug\netstandard1.4\TestInstall.ps1.dll" target="lib\netstandard1.4" />
</files>
</package>
Then use the command line: nuget.exe pack xxx.nuspec to pack the package, you will get the package with Install.ps1 in the tools directory:

Copy only modified and new files from source to destination in nant script

Currently we are using copy command to copy files from one location to other, but it is coping all files over and again. Here I want to copy only modified and new files from source to destination.
Can any one please help me in this?
Here is sample code:
<copy overwrite="true" todir="destination">
<fileset basedir="source">
<include name="**/*"/>
</fileset>
</copy>
This would copy only modified files from source folder to destination folder:
<exec program="C:\Windows\System32\xcopy.exe" failonerror="false" >
<arg line="${source} ${destination} /D /E /C /Q /H /R /Y /K" />
</exec>

How to avoid xml document generation when using nuget pack

I'm creating the package for my assembly but I dont' want to include the docs/*.xml files in my nuget package. I have tried the -Exclude switch of the pack command and the exclude property for the files section in the nuspec file to explictly excluding these files. None of these worked. So every time I generate my nuget package and then test it by installing it in the target project it always adds a docs folder with all the xml files. How can I avoid that the xml files are included into the nuget package? Any help would be highly appreciated.
To exclude all .xml files you should use the **\*.xml wildcard. I am guessing that you are using *.xml which will not work.
To exclude all .xml files you could use a nuget command line similar to the following:
nuget.exe pack MyPackage.nuspec -Exclude **\*.xml
If you only need to exclude .xml files in the docs directory then you can use a nuget command line similar to the following:
nuget.exe package MyPackage.nuspec -Exclude **\docs\*.xml
The wildcards seem to work relative to the folder that your .nuspec file is in.So if you have an .xml file in a docs subfolder relative to the .nuspec file then a wildcard if docs*.xml should work too.
Thank you Matt, I'm already doing what you mentioned but seems to me that Nuget does some other things by convention. Even if I use the exclude just like you said the docs folder is included. I resolved the issue by generating the nuspec file with the -a switch (I was using my .csproj file). I also had to copy the .dll file to a folder outside of my solution's folder. This way everything worked fine and as expected.
Anyway your answer is accurate but in my scenario it wasn't working. Not sure if this is by design.
Here's my final msbuild file which I'm currently using to generate the package. Hopefully Nuget soon will add more switches to the spec command so we won't have to modify so much the nuspec file afterwards.
<Project DefaultTargets="NugetPackage" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<OutputPathCore>NugetPkgs\$(Configuration)\My.Assembly</OutputPathCore>
<NuGetExePath>assets\nuget.exe</NuGetExePath>
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
<Import Project="$(MSBuildExtensionsPath)\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks"/>
<Target Name="NugetPackage" DependsOnTargets="PackageClean;BuildNugetPackageMyAssembly">
<Target Name="PackageClean">
<RemoveDir Directories ="NugetPkgs\$(Configuration)" ContinueOnError ="true"/>
<Target Name="BuildNugetPackageMyAssembly">
<MakeDir Directories="$(OutputPathCore)" />
<MakeDir Directories="$(OutputPathCore)\Package" />
<MakeDir Directories="$(OutputPathCore)\lib\net40" />
<MakeDir Directories="$(OutputPathCore)\lib\net20" />
<MakeDir Directories="$(OutputPathCore)\lib\net20-cf" />
<Copy
DestinationFolder="$(OutputPathCore)\lib\net40"
SourceFiles="Source\My.Assembly\bin\$(Configuration)\My.Assembly.dll" />
<Copy
DestinationFolder="$(OutputPathCore)\lib\net20"
SourceFiles="VS2008\Source\My.Assembly\bin\$(Configuration)\My.Assembly.dll" />
<Copy
DestinationFolder="$(OutputPathCore)\lib\net20-cf"
SourceFiles="VS2008\Source\My.Assembly.CF\bin\$(Configuration)\My.Assembly.CF.dll" />
<Copy DestinationFolder="$(OutputPathCore)\content" SourceFiles="CHANGES" />
<Copy SourceFiles="Release Notes.txt" DestinationFiles="$(OutputPathCore)\Readme.txt" />
<Exec Command=""$(NuGetExePath)" spec -a "$(OutputPathCore)\lib\net40\My.Assembly.dll"" />
<XmlUpdate Namespace="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd" XmlFileName="My.Assembly.nuspec" XPath="//package/metadata/licenseUrl" Value="http://someurl" />
<XmlUpdate Namespace="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd" XmlFileName="My.Assembly.nuspec" XPath="//package/metadata/projectUrl" Value="http://someurl" />
<XmlUpdate Namespace="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd" XmlFileName="My.Assembly.nuspec" XPath="//package/metadata/iconUrl" Value="http://somenice.png" />
<XmlUpdate Namespace="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd" XmlFileName="My.Assembly.nuspec" XPath="//package/metadata/tags" Value="My.Assembly" />
<XmlUpdate Namespace="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd" XmlFileName="My.Assembly.nuspec" XPath="//package/metadata/releaseNotes" Value="Review readme.txt for details." />
<ItemGroup>
<file Include="Source\My.Assembly\bin\$(Configuration)\My.Assembly.dll"/>
<file Include="VS2008\Source\My.Assembly\bin\$(Configuration)\My.Assembly.dll"/>
<file Include="$(OutputPathCore)\Readme.txt"/>
</ItemGroup>
<MSBuild.ExtensionPack.Xml.XmlFile TaskAction="RemoveElement" File="My.Assembly.nuspec" Element="dependencies" XPath="//package/metadata/dependencies" />
<MSBuild.ExtensionPack.Xml.XmlFile TaskAction="AddElement" File="My.Assembly.nuspec" Key="" Value="" Element="files" XPath="//package" InsertAfterXPath="//package" />
<MSBuild.ExtensionPack.Xml.XmlFile TaskAction="AddElement" File="My.Assembly.nuspec" Key="src" Value="%(file.Identity)" Element="file" XPath="//package/files" />
<MSBuild.ExtensionPack.Xml.XmlFile TaskAction="AddAttribute" File="My.Assembly.nuspec" XPath="//package/files/*[1]" Key="target" Value="lib\net40" />
<MSBuild.ExtensionPack.Xml.XmlFile TaskAction="AddAttribute" File="My.Assembly.nuspec" XPath="//package/files/*[2]" Key="target" Value="lib\net20" />
<MSBuild.ExtensionPack.Xml.XmlFile TaskAction="AddAttribute" File="My.Assembly.nuspec" XPath="//package/files/*[3]" Key="target" Value=""/>
<Exec Command=""$(NuGetExePath)" pack My.Assembly.nuspec -OutputDirectory "$(OutputPathCore)\Package" -NoPackageAnalysis" />
<Delete Files ="My.Assembly.nuspec" />
Another thing I can think of is
Create a nuspec file and edit it. this needs to be done only once (could be checked in as well). Any reasons you are editing the nuspec file while doing build?
use files element in nuspec file to copy files to destination folders
<files>
<file src="bin\Debug\*.dll" target="lib" />
<file src="bin\Debug\*.pdb" target="lib" />
<file src="tools\*\.*" exclude="*\.log" />
</files>
3. pack command can remain to be done at build time.
more details for files can be found here http://docs.nuget.org/docs/reference/nuspec-reference

NuGet package dll's + content files = fail?

I created a nuget package. I put some files and folders in a "content" folder and it worked great. So I added a bin folder with dll's and put this in my nuspec file :
<files>
src="bin\*.dll" target="lib" />
</files>
dll's are nicely put in the reference, but the content isn't copied anymore.
How can I manage to get them both working ?
#Edit
I know have this:
<file src="content\Controllers\*.*" target="Controllers" />
<file src="content\Views\Account\*.*" target = "Views\Account" />
<file src="bin\*.dll" target="lib" />
The package contains the right structure and files, but the files are not copied into my project.
The files are in a folder structure. When I put them directly into my content folder the are copied to the root of my project ...
When you define a files section in the nuspec we no longer do "automatic" / "Convention" based package creation. We see it as you are telling us what to include so we don't include things not in the list. Simply add the content folder to that list and it will work.
Edit to include comments from answerer's comment below
The NuSpec file "files" section tell NuGet where to put the files in the package not in sln/proj when it its unpacked. you want to write it like this:
<file src="content\Controllers*.*" target="content\Controllers" />
<file src="content\Views\Account*.*" target = "content\Views\Account" />
<file src="bin*.dll" target="lib" />