Keeping packages.config and nuspec in sync - nuget

I've been resorting to manually modifying my .nuspec files every time I update packages. Is there an automatic way of doing this? I'd rather not have to create an additional build step that compares both files and syncs them.
I believe MyGet does this OOB, but unfortunately I can't use MyGet for this specific package.
(FWIW, I'm using VS2015 and Xamarin Studio)

Just call the nuget pack against the csproj instead of nuspec, for example:
nuget pack X.csproj
In addition, you'll have to remove the dependencies from the nuspec, otherwise nuget will get it from there instead of from packages.config.
BTW, check the created nupkg. It may have unwanted files added to it, like, for instance, txt files, if you happen to have any in your project.
If that's the case, you'll have to invoke nuget pack with the -Exclude parameter:
nuget pack X.csproj -Exclude **.txt

I ended up creating a quick C# script (LINQPad rules) that syncs .config and .nuspec using XDocument, NuGet.Core and LINQ. If anyone's interested, I'll post it as a gist.

Related

Should I publish the nuspec file in a repository?

When creating an open source library on GitHub or another public website, should I publish the .nuspec file that describes the corresponding NuGet package?
I've done this a couple of times (since no API key or other sensitive information is included in the .nuspec file) in order to allow myself to easily publish subsequent versions without keeping private file, and to allow other people to fork it and add their own descriptions easily. However, the developers of many top packages don't seem to publish .nuspec files in their repositories (sometimes they publish NuGet.exe along with a .targets file, and so on), so I'm thinking that maybe I'm doing something wrong.
The package authoring should be considered part of the source code since it is a required asset to build the fully usable output.
Some projects use special msbuild-based tooling to create the nuspec file during the build so it seems like there is none in the repository. the new "SDK-based" projects (e.g. .NET Standard libraries) have integrated nuget tooling to be able to create a nupkg file from the csproj without the need to create a nuspec file. This tooling is also being adopted by some popular packages (e.g. Newtonsoft.Json).

VSTS NuGet pack exclude test projects

I am using VSTS vNext build system to build a C# solution.
Below you can see the settings for the NuGet Packager. The path to nuspec files is set to reference the .csproj files.
However this includes all .csproj files; I need to exclude test projects. Ignoring 'Core.Test.csproj' but still packaging 'Core.csproj'.
I have tried '*.csproj;-:!*test.csproj' and other combinations but have had no luck figuring this out! Does anyone know how the pattern matching works for vNext build?
**\*.csproj;-:**\*test.csproj should do it (no exclaimation point needed). If not, we may have a bug, and you should file it on GitHub.
The latest version (2.x) of the NuGet task in VSTS and TFS 2018 uses a different pattern for excluding packages. Now you use ! instead of -:.
So **\*.csproj;-:**\*.Test.csproj changes to **\*.csproj;!**\*.Test.csproj.
Full pattern matching documentation can be found here.

Specify Octopack nuget package file's target path

I found OctoPack to be incredibly straight forward when creating .nupkg nuget package files, however I I'd like the .nuspec file included (currently is placed in another folder such as obj/octopackage or something), and all the dlls should be placed inside a lib/net452 folder so that the general structure appears as such:
Currently everything that should be in the lib/net452 folder is simply placed in the root, along with _rels and package, and as mentioned the .nuspec file is missing.
Either the documentation is a little sparse or I've completely missed how to do this in my debugging mental haze. Anyone know how to specify to OctoPack where, specifically, to place the compiled output within the .nupkg file?
To create your NuGet package, you should be using nuget.exe, not OctoPack. I'll explain why in a minute.
The .nuspec file serves as the "blueprint" for your NuGet package (.nupkg). So the short answer is to simply specify the location in your .nuspec file, using the target attribute of the <files> element. Details can be found on the NuGet site, but it would look something like this:
<files>
<file src="bin\$configuration$\*.dll" target="lib\net452\" />
</files>
There are a number of ways to call nuget.exe in a post-build step; many are explained on the NuGet site as well.
OctoPack is not meant to create packages for nuget.org; it is designed specifically to create packages for Octopus Deploy. It creates packages one of two ways:
If there is a web.config file present, OctoPack assumes that the project is a web project, and packages the output accordingly. It uses the project file to determine which items are marked as content, and which are not (although it will always grab web.config transformation files).
Otherwise, OctoPack assumes that the project is an executable, or a component, and simply packs whatever it finds in the output folder (usually \Debug\bin or \Release\bin). This is the behavior that you're seeing.
Since OctoPack uses nuget.exe under the hood, a .nuspec file will override both of the above cases. So while you could use OctoPack to create your NuGet package, it's more appropriate to use nuget.exe.

How to add a folder to a nuspec file

So I'm actually trying to package up a web site project (not web application so no csproj file) into a NuGet package ready for Octopus to consume but am running into one brick wall after another..
I looked into using OctoPack but it doesn't support web site projects only web application projects.
I am now trying to find a way of adding a folder (in my case a web site) into a Nuget package but Nuget doesn't allow this via the command line does it? It also requires a .csproj file!
I've also tried trying to create the NuGet spec files and pass it in a folder but not possible?
For the moment I may have to use the NuGet package explorer but I want to script this.
I've looked at this question but doesn't seem to handle my scenario
Can I create a nuget package without a project file
So does anyone know how to best add a folder to a NuGet package via the command line!?
I don't know OctoPack, but with nuget.exe, packaging is done in two steps:
Either create a .nuspec manually, or generate one from a .csproj or existing assembly (see nuget spec in the docs).
Call nuget pack with the .nuspec created in the previous step as a parameter.
Since you don't have a .csproj lying around, you're stuck creating the .nuspec manually (or with a GUI tool like NuGet Package Explorer).
You can read all about how to create a .nuspec file in the Nuspec Reference, specifically the section about Specifying Files to Include in the Package.
If you want to include a folder (recursively?) in the package, you need to add something like this to the XML:
<files>
<file src="bin\Release\**\*.*" target="content" />
</files>
This will take all the files and (recursive) sub-folders of the bin\Release folder and put them in the content folder of the NuGet package.
I have no idea what format OctopusDeploy expects in the packages, but that's how you include a folder in the package.
EDIT: There seems to be some documentation on this in the OctoPack README.

Multiple .nuspec files inside a project's directory?

Is it possible to have multiple nuspec files inside a single directory for the same project and still be able to merge the project and the specified nuspec file.
I wonder if something like this is possible:
nuget pack MyProject.csproj MyProject-x86.nuspec -prop Configuration=Release;Platform="x86"
nuget pack MyProject.csproj MyProject-AnyCpu.nuspec prop Configuration=Release
I need to be able to publish my project with more than one build configuration and thus I need to create different packages.
My very, very last resort will be to copy the csproj file at build time, rename it to "MyProject-x86.csproj" for example, run the nuget pack and then delete it. I would hate to do that and I am looking for alternatives.
Thanks.
When calling NuGet pack, you cannot pass more than a single csproj or nuspec file. Note the pipe in the command line help (to indicate one or the other):
usage: NuGet pack <nuspec | project> [options]
You could create another csproj stripped down to just an import element to the main csproj (i.e. the one you work from in Visual Studio), override the values of property group items as needed, and/or have matching .nuspec files.