nuget command line update doesn't detect all packages.config which need to be updated - nuget

We have a build step that installs and updates the nuget packages in a solution on out build server (TeamCity). Recently this has stopped doing the updates correctly. I have investigated this and found that the problem seems to be that the update command in nuget is not updating all the projects in the soltution. I can replicate this on my local machine.
When I run this command:
.nuget\NuGet.exe update Our.Company.sln -Source http:/ourTcServer:8888/guestAuth/app/nuget/v1/FeedService.svc -RepositoryPath packages -verbosity detailed
I get this a list of 10 projects it is going to update
Found 10 projects with a packages.config file. (
Company.Project1.csproj,
Company.Project2.csproj,
Company.Project3.csproj,
Company.Project4.csproj,
Company.Project4.SubProject1.csproj,
Company.Project4.SubProject2.csproj,
Company.Project1.SubProject1.csproj,
Company.Project1.SubProject2.csproj,
Company.Project2.SubProject1.csproj,
Company.Project2.SubProject1.FurtherSubProject1.csproj)
However the solution contains 13 projects and these all contain packages.config files and as far as I can tell are no different to any of the other projects. The projects are a single project and its subprojects and our projects directory structure matches the projects names (so project1.subproject1 implies that subproject1 is in a folder inside project1) in case that is important. The projects with the issue are all in a project which has the specific names like :
Company.Something.SomethingElse.Routing
Company.Something.SomethingElse.Routing.Tests
Company.Something.SomethingElse.Routing.Tests.Specifications
In case the routing part of the name causes a problem (we had a problem before using the word Resources at the end of our package name)
We have 50+ solutions that all use the same build configuration and steps and it works fine for all of them. This solution seems to be the only one which is not updating correctly.
Does anyone know why this might be the case? Or does anyone know what the code that finds packages in a solution does which might cause it not to find some packages.config files? Or anything that might help track down this issue?

Ok so the issue was that we had renamed some of our projects and so the .csproj files and had not removed to old, unused project files and nuget has a piece of code which finds the projectfile into which it it going to update the references of the updated packages. It does this by finding all the files which are .csproj (or whatever project file flavour you are using) in the same directory as the packages.config. If this does not result in exactly 1 file then it throws an exception, which is subsequently caught and ignored and nothing is logged, so you are non the wiser.
Hopefully this will help someone else in the future. Maybe me.

I found that the problem I ran into was that my projects were not in the same directory tree of the solution.
The nuget.exe update command when given solution file searches for packages.config files using the solution directory as the starting point instead of looking at each project file in the solution.
From the nuget code on GitHub:
string[] packagesConfigFiles = Directory.GetFiles(
solutionDir, "*.config", SearchOption.AllDirectories);
You can see that they are just looking for *.config files starting in the solution directory.
My projects and solutions are organized like this:
/Libraries/Shared/Shared.csproj
/Programs/NTService/NTService.csproj
/Programs/NTService.sln
In this case, if I run update on the NTService.sln file it will only update the NTService.csproj references because it is in the same directory tree as the NTService.sln file.
Since it just looks at all packages in the whole tree, I just put a solution file at the root of my repository and then run the update on that. It doesn't matter what projects are in that solution file.

Related

Why are there similar Nuget package folders in .nuget\Packages directory?

Under c:\Users\<USER NAME>\.nuget\packages\ directory, there are some folders looks similar, for example:
System.IO.FileSystem.4.3.0
system.io.filesystem (and there are sub-folder "4.3.0" under it)
See attached figure.
My question: why are there similar Nuget package folders in .nuget\Packages directory? Can I delete one of them?
Possibly you used an old version of NuGet or Visual Studio on your machine, which used the old format. The other option is that you have a nuget.config that forces that solution packages folder to be your user profile's global packages folder. I really don't recommend this.
Maybe starting with NuGet 3.0 (Visual Studio 2015), NuGet uses the tolower(packageid)\tolower(packageversion)\ folder structure. I'm too lazy to test old versions to validate that earlier versions used something different. Or maybe NuGet has always used the same format for the global packages folder, making the packages.config answer the only possibility. But I really think that lowercase normalisation was something that was added and didn't always exist.
projects that use packages.config have always used the unmodified PackageId.PackageVersion format in the solution packages folder. I believe it was deemed too risky as a breaking change that some customers depend on to change in the solution packages folder. So, if anyone had the misguided idea that they could save disk space by making all their solutions share the same packages folder by using the same one for all solutions, and the folder they used is the global packages folder, then the two different parts of NuGet which intentially use different folder naming conventions, will write to the same directory.
As long as you're not in the middle of a build, it's always safe to delete folders in any packages folder (global packages, as your question is about, or a solution packages folder). If a project needs a package that was deleted, NuGet will download it again, so if you have a download quota, or a slow internet connection, maybe be mindful. Otherwise you can be as liberal with deleting folders as you like. Just make sure to delete the entire folder. There's only one file NuGet looks for when restoring, so if you delete other files but leave that one, NuGet will think it's downloaded and extracted properly, but your machine will behave differently to other machines.

Nuget update fails when there is more than one solution file pointing to the same package.config

I'm having more than one solution file for my project each pointing to a different target frameworks.
I'm able to restore the nugets for each solution using nuget restore command.
The problem arises when i try to use the update command.
Found multiple project files for package warning is shown and my packages are not updated to the latest version.
Am i doing anything wrong here?

Ripple to Paket -- is there a better way?

I'm in the process of converting a handful of projects from ripple to Paket. The way I do this is install Paket, then take my ripple.config and copy my sources and nugets over to my paket.dependencies, taking care to == the versions that I have fixed. Then I .paket/paket install over and over and over again trying to resolve versioning errors that come up from that.
After that, I open all my .csproj files and add an extra ..\ to all the HintPaths before opening my project and manually resolving whatever errors pop up.
Is there a better way to do this? I know there's a ripple-to-paket converter but I not only couldn't get it to work, but many people I work with say that it's terrible.
Thank you.
1 add a paket.references file in each project's folder
In each of your project files' folder, you should create a paket.references and list there the package name (only, the other info is kept consistent in your paket.dependencies in your root folder).
2 make sure the actual reference are handled with paket
you can manually remove the reference in the project files (either from VS or edit the project file), and call paket install which will add them (according to paket.references in the project's folder) with an additional <Paket>True</Paket> node (making it clear that this reference is handled by paket itself)
I think this is it.

NuGet package files not being copied to project content during build

I am building an MVC4 web application with VS2012 professional with NuGet Package Manager version 2.2.31210. I have multiple projects in my solution, all sharing various packages I installed using NuGet. One of my projects is an MVC4 web application where I am using packages such as bootstrap, jquery UI, etc, all installed using NuGet.
When I clone a fresh copy of my entire solution from my repository and build my MVC4 project, the package restore feature seems to be working: it creates the packages directory under the solution direcotry and populates it will all the versions of the packages I expect to see. However, the content files do not get copied to the appropriate places in the MVC app directory. The weird thing is that it does create directories for the content, but does not copy the content files themselves.
For example, I am using the Twitter Bootstrap package which appears in the packages/Twitter.Bootstrap.2.2.2. In the MVC project a directory called bootstrap (containing css, img, and js directories) gets created in the Content directory. But, no css or js files are copied into those directories!
Does anyone have a clue what magic incantation I must utter to get the build to copy these content files from the NuGet packages directory?
This is a very common issue we are all having. I've created an MSBuild Task NugetContentRestoreTask that will do this trick for you. Run the following command in the Package Manager Console:
Install Nuget Content Restore MSBuild Targets
PM> Install-Package MSBuild.NugetContentRestore
The only thing left is to call it from your BeforeBuild Target with something like this:
Project File Targets
<Target Name="BeforeBuild">
<NugetContentRestoreTask SolutionDir="$(SolutionDir)" ProjectDir="$(ProjectDir)" />
</Target>
You can take a look at the source repo and find it on nuget.org
Additional Content Folders
This nuget only includes the default folders scripts, images, fonts, and content, it is not a recursive directory includes. For additional content subfolders - you must assign the property AdditionalFolders.
<Target Name="BeforeBuild">
<NugetContentRestoreTask SolutionDir="$(SolutionDir)" ProjectDir="$(ProjectDir)"
AdditionalFolders="less;sass;common" />
</Target>
I have found a workaround, but it is ugly. By executing the following command in the NuGet Package Manager Console: Update-Package -Reinstall all the files are indeed copied to their proper places within the Mvc project Content and Scripts directories.
Unfortunately, this is risky because you are likely to end up with the wrong versions of certain packages. For example, in my case after the command finishes executing (which takes quite a while by the way), I end up with jQuery version 1.4.4. This is way old, and I assume it must be an explicit dependency of some other package that is being updated. So it appears that the order in which the packages actually get updated by NuGet is significant (it does not appear to parse the entire dependency tree for all packages and pick only the latest versions from the union of all dependencies, which seems like it would be the preferred behavior). Rather, as the command executes I see it replacing the jQuery package several times with different versions as it works its way through all the packages and their dependencies, only to end up with a very old version.
A similar approach is the execute the Update-Package -Reinstall command explicitly for each package that is causing my problem, but this is incredibly tedious and error prone.
The NuGet Package Restore feature should yield the same result as manually executing the Install-Package or Update-Package -Reinstall command for a package, but it does not.
I don't like to have the thirdparty JavaScript files under source control either. Thats why I've followed Jeff Handley advice in http://nuget.codeplex.com/workitem/2094 to create a solution my self. I didn't go the executable way, but created a nuget solution level package which does the trick.
http://www.nuget.org/packages/Baseclass.Contrib.Nuget.GitIgnoreContent/
It's tied to git, as it automatically updates the .gitignore file.
Short description:
Ignore nuget content files in git:
Generate entries in the .gitignore file to exclude nuget content files from the source repository
Restore nuget content files before building (Automatically in VS and manually with a powershell script
I've written a blog post describing how to use it.
http://www.baseclass.ch/blog/Lists/Beitraege/Post.aspx?ID=9&mobile=0
In Visual Studio 2015 Update 1, they now support contentFiles. The caveat with this is that it only works in projects that use project.json.
In reference to the problem that you are having, there is a good blog post that explains why you see this behaviour: NuGet Package Restore Common Misconceptions.
For my projects it turned out that content files work with PackageReferences only:
Existing project with nuget references via packages.config
Installed NuGet package with content files
Build project
No content files in output directory
Conversion of packages.config to PackageReferences
Build project
Content files have been copied to output directory
IDE is Visual Studio 2017. The project is an application project which means it is in the old csproj format.

How to use Nuget with more than one solution

I have a number of solutions which share the same projects in different folders, for example,
Common folder
- common 1
- common 2
Contracts folder
- contracts for project A
- contracts for Project B
Application 1 folder (in this folder I have my solution file)
- Solution A
- nuget creates packages folder there
Application 2 folder
- Solution B
- nuget creates packages folder there
packages folder( I need this folder at top level, so all projects can reference it)
With this structure Nuget creates two packages folder inside of Application 1 and Application 2
But all of this projects and solutions related to each other, so logically it's better to have only one packages folder.
Is it possible to set in nuget only one folder and use that folder for all solutions?
Or should I structure my solutions and projects another way?
You can do this by adding nuget.config files to each solution with following contents
<settings>
<repositoryPath>..\Packages</repositoryPath>
</settings>
Make sure that they all point to the same folder.
When you make this file, you have to restart Visual Studio to make it use this setting ( or at least close and open the solution).
But more practical would be to create just one nuget.config that all solutions make use of. Just make sure it resides on a folder higher then any solution file you wish to include. When restoring, the nuget manager searches for this file, starting from next to the solution file and if not found, start looking higher up the folder structure.
Sharing a repository between 2 solutions isn't really possible, as if you update a package in solution A the projects in solution b won't be updated unless they're also in solution A (and may have their package automatically deleted because solution A doesn't use them anymore). Basically meaning having 2 solution files is redundant or you're going to break the other solution with no way of knowing.
How are the solutions related to each other? Maybe there's another way to solve the problem if we have a bit more information.