Maybe I'm pushing the envelope here, but I'm desperate to leverage NuGet to ease the DLL Hell that I've found myself in.
We have 4 main products that all live in interrelated Mercurial repositories. All of them "share" 3 core assemblies and then everything else is pretty much product-specific. It's become very difficult to manage now because one product has been upgraded to .NET 4.0 and is using external dependencies that require .NET 4.0, while another product is stuck in .NET 3.5 for reasons I don't even want to get into.
So, we have lost our ability to merge differences between products.
To fix it, I want to take out the 3 main assemblies, and turn them into their own project with their own release cycle, and take the care to make sure they can compile against both .NET 3.5 and 4.0, and then turn those into NuGet packages containing multiple framework versions.
BUT, I also want developers to be able to browse the source of these projects.
So I set up a private NuGet server and a private SymbolSource server. Then I carefully merged all the changes from all repositories together, and threw out everything except my core assemblies. Then I painstakingly hand-edited the .csproj files so that instead of the AnyCPU platform, each project has platform targets of 3.5 and 4.0, which specifies conditional constants (to control platform-specific features like System.Dynamic) and sets the framework version.
Then I set up solution configurations for "3.5 Debug", "3.5 Release", "4.0 Debug", and "4.0 Release". Each one targets the appropriate Configuration (Debug or Release) and Platform (3.5 or 4.0).
I can build everything fine within Visual Studio for any platform. Now I have a problem when it comes to NuGet, because there are two ways to create a package, and both have a weakness, unless I'm missing something:
Package by Project File
nuget pack MyProject.csproj -Build -Symbols -Version <insert-from-build-server> -Properties "Configuration=Release;Platform=3.5;"
The problems with this are:
- While the 3.5 version is built and packaged, the output says "Building projecct for target framework '.NETFramework,Version=v4.0'."
- If I unpack the resulting packages, the assemblies are under
lib\net40
which is wrong. - I don't think there is any way to package 2 framework targets this way, you have to do it the other way with folders and conventions.
- I am willing to accept that you can't package the frameworks together and make 2 packages called MyProject (which I would do as 4.0) and MyProject.V35 ... however I can't figure out how to have the same project and nuspec and wind up with 2 different results with different ids.
Package by Nuspec File
With this method, I have to do all the msbuilding myself and then do a bunch of file copying to set up a folder structure like
* MyProject.nuspec
* net40
* MyProject.dll
* MyProject.pdb
* net35
* MyProject.dll
* MyProject.pdb
Then I can run nuget pack MyProject.nuspec
but then there is no source to go with the symbols, because without the .csproj file, NuGet has no way to figure out where to get all the source files, and I don't see any documentation on how to do this using directory conventions either.
So my questions are:
- Is there a way to add source files to a convention-based package?
- Is there a way to package a project-based package twice with different ids?
- Is there another avenue that perhaps I haven't considered?
Any thoughts would be much appreciated.