I just wrote about the switch from the MSBuild based “Enable Nuget Package Restore” option to the new and recommended “Automatic Package Restore.”
Not only did this not solve our problems, but it seems the solution involves returning to the “wrong” way at least based on pretty much everything I read on the topic:
http://docs.nuget.org/docs/workflows/migrating-to-automatic-package-restore
http://www.xavierdecoster.com/migrate-away-from-msbuild-based-nuget-package-restore
http://blog.davidebbo.com/2014/01/the-right-way-to-restore-nuget-packages.html
Our problem lies in the use of common projects in multiple solutions. Lets say you have SolutionA that contains AppA, ProjectX, ProjectY, and ProjectZ. SolutionB contains AppB, along with ProjectX, Y and Z as well. If you are working in SolutionA and you add a new Nuget package to ProjectX, then that package is downloaded to SolutionA/Packages/MyNewNugetPackage1.0/…/…/x.dll and ProjectX is given a hint path to search for that DLL reference at that file path.
Now what happens when your build server tries to build SolutionB (not SolutionA)? Nuget restore downloads all the necessary nuget packages into the SolutionB packages folder, but ProjectX fails to build because it expected to find x.DLL in the SolutionA packages folder, but that folder is empty (the SolutionB packages folder was the one that was just populated with nuget packages). So the build fails.
Because of the nature of how we store our projects in source control, if we could control the location of the packages folder it would solve our problem because we could use a common packages folder across all solutions.
What would this mean?
It means that all solutions in this source control repo would all end up downloading their nuget packages, and looking for their nuget references, in the same folder. This means that when SolutionA downloads it’s nuget packages, it the same spot where SolutionB would download it’s packages, so ProjectX will find what it needs not matter if it’s in SolutionA or SolutionB.
To make this work here is what I had to do. First I needed to return the solutions to the “wrong” way of doing package restore. This means right clicking on the solution in VS.Net and picking “Enable Nuget Package Restore”. This will create a .nuget folder under the solution which will contain a Nuget.config file. In this file you need to add the <config> node shown below.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<solution>
<add key="disableSourceControlIntegration" value="true" />
</solution>
<config>
<add key="repositoryPath" value="..\..\..\..\..\..\CommonPackages" />
</config>
</configuration>
Any change to Nuget.config requires a VS.Net restart to take effect. Once you restart VS.Net nuget will be looking in this new “CommonPackages” folder for it’s nuget packages. But your projects aren’t looking for their DLLs there. The easy way to solve this is to just run the Package Manager Console and issue the command:
update-package -reinstall
This will not only download all the nuget packages your solution references, but it will reassign those references so that they are now pointing to the new location, “CommonPackages” in this case.
I was not able to find a way to do anything equivalent using the nuget.exe program from outside visual studio. If that WERE possible, then I think this would have been a possible solution to my original problem, because unlike running “nuget.exe restore”, this command actually DOES change where the solution’s projects look for their DLLs.