Create NuSpec dependencies from project file/nuget metadata

Feb 10, 2011 at 3:42 PM

I'd like to automatically produce a package from our automated build. If i add/remove a depedent package from/to the project I want the build to update the nuspec dependency elements accordingly.

Has someone already done this?

Feb 10, 2011 at 4:22 PM

We are looking at making this really easy in a future version (probably in 1.2). Check out my screencast to get an idea what we're after.

Feb 11, 2011 at 8:43 AM

Looks great. Exactly what Im after. I assume you can tweak how the version dependency gets added to nuspec file(i.e. exact version, any version greater etc)

Is this in trunk or in a branch?

Feb 14, 2011 at 10:06 AM

I've just started using nuget and one of the first features I really wanted was to not have to maintain dependencies in the nuspec! Can't wait for this...

Feb 14, 2011 at 4:08 PM

I have some work in a fork waiting to be merged (slight core refactoring, enabling "Plugins" for NuGet.exe with MEF) and a custom Plugin that given a solution of class libraries (like a Core framework) builds a package for each Project where the contents are just the Project output assembly, and all the metadata is derived from running Mono.Cecil against the project output assembly.  Dependencies are figured out by looking at Project References, and packages.config for each Project.

We wrap this all up as part of our Team City build.

Hopefully my work will get merged sooner rather than later and I'll be able to open up that plugin.

Feb 18, 2011 at 7:58 AM

I was wondering if it would be worth writing a simple utility that replaces selected fields in a template .nuspec file with values from an assembly?

e.g. we have a MyLib.nuTemplate file:

  <version>$(FileVersion)</version> ...

The utility finds fields in the form $(fieldName) and matches to properties in FileVersionInfo for the target library. You pass the template file, the library (target DLL/EXE) file being generated by the compile and an output file which is the .nuspec file.

This could be written into the compile events post-success just before a NUGET PACK command that uses the generated .nuspec file; e.g.:

NUTEMPLATE.EXE MyLib.DLL MyLib.nuTemplate MyLib.nuspec
NUGET PACK MyLib.nuspec

Any comments?

Feb 18, 2011 at 3:35 PM

That could be cool, although I ran into some issues with FileVersionInfo.  I wasn't able to get to the plain AssemblyVersion.


The reason I like the solution I described is that it's all "on demand".  Version-ing your assembly and having the correct project / package references is all you need to get a fully formed package.  I know that when I look at SomeCoreSolution.ProjectA., that it really *is* version because I read that version directly from the assembly metadata.

Apr 28, 2011 at 1:15 PM

I would be nice if one could update the nuspec file from a project... version 1.3 supports creating a .nupkg file from a .csproj, which is nice because its automatically adds/updates other dependencies.

Hower, updating .nuspec file (only dependencies) would be better, because if you've customized the packages with code transformations, package transformation, powershell scripts, those customisations get lost...

So I would like something like :  nuget.exe updatespec myproject.csproj 
 it would update package dependencies for myproject.nuspec, but would not change any of the content, lib, ...

Apr 28, 2011 at 7:11 PM

@rekna: you should be able to achieve this. See "Step 6: specify additional metadata using a nuspec file" in my post. The idea is that you'd create a nuspec file that inherits all the metadata from the project, and just adds some extra dependencies. But note that in theory, the right  dependencies should already by inferred from the project.

Apr 28, 2011 at 8:35 PM

@davidebbo: ok, seems to be one step into the right direction... but how does one manage extra files like code transformation, config transformation, powershell scripts while keeping the ability to update the nuspec file from the project? I was thinking to create the nuspec file inside a release directory, but first of all, you can not specify where the nuspec file should be created (it is always created in the folder where the csproj is located)... Secondly, if it were possible to specify the destination folder of the nuspec file, it would probably also have to copy the dll into the lib folder of the release directory... maybe there is another solution I am overlooking?

Apr 28, 2011 at 8:45 PM

If you specify some files in the nuspec, they should get added to the package in addition to whatever it finds from the project.

Not fully understanding your comment about copying the dll to the lib. Running 'nuget pack' on the csproj should automatically put the DLL in the lib folder of the package.

Apr 28, 2011 at 8:53 PM

@davidebbo : package explorer (even the latest version, compatible with nuget 1.3) can not edit a nuspec file created with the command 'nuget spec', it is giving an error on the version ... (so I have to manually edit the nuspec file to add something), nor I'm I able to add files by putting them in folder by convention (even if it were possible, they would have to be in the project folder, since they have to be relative to the folder where the nuspec file is located). 

Apr 28, 2011 at 8:59 PM

@rekna: what is the error that you see in package explorer? can you let me know the steps that you did?

Apr 28, 2011 at 9:02 PM

The fact that package explorer can't edit those nuspec files that have replacement tokens is a separate thing, that ideally should be fixed. Can you file a bug for it?

Would you be able to give more details about an example of the exact layout you're trying to achieve in the package? Specifically, what are those extra files and where do you want them? I think with enough info, we can work toward a workflow that will cover more scenarios without too much pain :)

Apr 28, 2011 at 9:07 PM

@dotnetjunky: created a class library with one small class (myproject.csproj) and edited assemblyinfo.Cs, then open dos prompt in project folder and execute 'nuget.exe spec'
this creates a myproject.nuspec like this
<?xml version="1.0"?>
<package xmlns=""> 
When I try to open this file with package explorer, it gives an error (but it's in dutch:  De versietekenreeks is te kort of te lang), rougly translated: the versionstring is too long or too short...
I was hoping to be able to add content,  tools ... folder with package explorer, but it won't be possible, because when you save as nuspec, it does not contain the added files (tried this with new package)

Apr 28, 2011 at 9:21 PM

@davidebbo: ok, suppose I have a library project, and I want to add in content folder a with a web.config.transform, in the tools folder a init.ps1 script.
currently I have only one option: manualle edit the nuspec file created with 'nuget spec' and add those files (but being a good programmer, I don't like manually editing xml files :-) )
suppose one would have following project structure:
If I could run 'nuget spec' inside the \myproject folder, but be able to specify ..\..\Release as target dir, it would create myproject.nuspec inside the release folder.
Then running nuget pack -sym myproject.csproj -folder ..\..\Release would create/update package in release folder also picking up the content and tools folder (by convention) and the nupkg file would also be created inside the Release folder (don't like it being inside project folder)
Hope this make some sense ?

Apr 28, 2011 at 10:40 PM

Yep, I think this does make a lot of sense. The way I look at it, it's about creating the package by merging 3 different things:

  1. What the nuspec specifies
  2. What comes from the project file
  3. What comes from some extra folder, which is what we're missing today
Apr 28, 2011 at 10:44 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
May 8, 2011 at 1:21 PM

Can we expect this in the next version? This is currently the single item that prevents me from introducing nuget in our company, as it makes the workflow for creating packages so much more efficient if it would be implemented.