Shared NuGet Package Across Multiple Projects and Solutions
Asked Answered
R

3

9

What's the current preferred method for setting up NuGet to have a common package directory across all solutions in a project? Also is there a way I can include PCL packages in a common folder across different projects (so that packages can be shared across projects that target different platforms). I've seen similar questions asked before but I cannot find a clear answer that pertains to a recent version of NuGet.

Romberg answered 6/4, 2016 at 20:54 Comment(1)
Let me know if my solution worked for you or if you have any questions :)Emanate
E
8

If you include a nuget.config file at a directory which is a common ancestor of all of your solutions, then when you open any those solutions withing Visual Studio it will use this configuration file to configure NuGet.

One of the things nuget.config configures is the location for the nuget packages folder for the solution.

Reference: https://docs.nuget.org/consume/nuget-config-file

Sample nuget.config: note that the repositoryPath is with respect to the location of the nuget.config file.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageRestore>
    <add key="enabled" value="True" />
  </packageRestore>
  <config>
    <add key="repositoryPath" value="packages" />
  </config>
</configuration>
Emanate answered 6/4, 2016 at 21:7 Comment(8)
I have NuGet.Config files in all soltuions with the disableSourceControlIntegration option set to true. Do I still need to keep these config files or can I get rid of them and just use the config in the root directory?Romberg
you only need one. If you need a different configuration for just one of the solutions, though, include a nuget.config file in that solution's directory ONLY with just the setting that you want to be different. All of the rest of the configuration settings will come from the one one in the root directory.Emanate
Ok I see. I only ask because this line from docs.nuget.org/consume/package-restore confused me: "This nuget.config file does not have to be added to your solution file, but it must be put in the $(SolutionDir)\.nuget folder to be taken into account as it works at the solution level."Romberg
Also I assume I need to place it in a .nuget file? Do I need to include NuGet.exe and NuGet.targets file or are they unnecessary?Romberg
The rule is here under the section "Chaining multiple configuration files". "In general the NuGet.config file closest to the folder nuget.exe runs from wins, the section below walks through the details." The rule for "closest" changes when you're running from VS or from the command line. In VS, the current directory is where the solution is located, and from the command line, it's within the .nuget folder.Emanate
NuGet.exe is necessary because it's the executable that runs to get packages from the NuGet server that the packages are hosted at. Depending on your setup, I don't think you'd need a NuGet.exe in every solution location, though.Emanate
No it hasn't fully worked yet for me. The issue is that all of project files need to be updated to remove references to target files and hint paths. I tried using a migration script but it didn't fully work for me. I'm still getting build errors for the solutions I've tested. I'll probably have to write my own script or manually edit the project files. But thank you for your answer. It definitely got me on the right track.Romberg
Try using Update-package <package name> -reinstall in these cases. That's worked for me.Emanate
R
0

In case anyone else comes across this, here is how I solved the problem: John Carpenter steered me in the right direction. There is also some information I found on Nuget's wesite: https://docs.nuget.org/consume/package-restore/migrating-to-automatic-package-restore

In order to accomplish this I edited Owen Johnson's Powershell migration script here's a link to his script: https://github.com/owen2/AutomaticPackageRestoreMigrationScript

For me the script was not quite exhaustive enough and it didn't correct the hintpaths in the project files (which is a problem). *Note make sure you DO NOT RUN THIS if you don't have a copy of your code saved somewhere or in source control. No guarantees if this screws up your projects. Here's the script I used:

########################################
# Regex Patterns for Really Bad Things!
$listOfBadStuff = @(
    #sln regex
    "\s*(\.nuget\\NuGet\.(exe|targets)) = \1",
    #*proj regexes
    "\s*<Import Project=""(\$\(SolutionDir\))?(\d|\w|\s|\.|\\)*(\.nuget|package).*?/>",
    "\s*<Target Name=""(EnsureNuGetPackageBuildImports|EnsureBclBuildImported)""(.|\n)*?>(.|\n)*?</Target>",
    "\s*<RestorePackages>\w*</RestorePackages>",
    #HintPaths
    "\s*<HintPath>(\$\(SolutionDir\))?(\d|\w|\s|\.|\\)*package.*?</HintPath>"

)

#######################
# Delete NuGet.targets and package folders

ls -Recurse -include 'NuGet.exe','NuGet.targets','NuGet.config' |
  foreach { 
    remove-item $_ -recurse -force
    write-host deleted $_
}

#########################################################################################
# Fix Project and Solution Files to reverse damage done by "Enable NuGet Package Restore

ls -Recurse -include *.csproj, *.sln, *.fsproj, *.vbproj, *.wixproj, *.vcxproj |
  foreach {
    sp $_ IsReadOnly $false
    $content = cat $_.FullName | Out-String
    $origContent = $content
    foreach($badStuff in $listOfBadStuff){
        $content = $content -replace $badStuff, ""
    }
    if ($origContent -ne $content)
    {   
        $content | out-file -encoding "UTF8" $_.FullName
        write-host messed with $_.Name
    }           
}

I added a command to remove the hintpaths. After running the script you may get some Nuget errors because some packages need a hintpath. In order to fix these you need to reinstall those packages. The following link on Nuget Website shows you how to do this: http://blog.nuget.org/20121231/a-quick-tutorial-on-update-package-command.html

So the steps I took to perform the full migration: 1) Run the Powershell script at the root level of your code base. 2) Add your NuGet.config file to the root of your code base (use the one John Carpenter provided as a template) 3) Reinstall any packages that need to have a hintpath (should fix any Nuget errors you have). 4) Now when you build any solution, Nuget should place your packages in your central package folder.

Romberg answered 3/5, 2016 at 0:50 Comment(0)
T
0

My solution is different from the traditional ones here which add/edit the Nuget.config file. For my case, configuration to Nuget.config files to find the necessary packages didn't help any projects I had and the problem still persisted with all the namespace libraries not being found even with the common System library.

So, for some projects that can't locate the packages folder which was put directly under the solution folder, I did some tweaking and found out that the code script for the project file "{project-name}.csproj" mentions where the package is located.

However, the path was set relatively to the project file I assumed and hence, it kept looking for packages folder under this project directory instead of the root solution container.

An example from my case (You can open the script for these files through VSCode or other text editors than Microsoft VS):

before fix, project file script -> package path locater

after fix, project file script -> package path locater

From above example, I've added "..\" prior to most "packages\{package-name}" to locate the path from the root of the solution instead (assumption here but it worked).

Important Note: add the prefix "..\" to "packages\{package-name}" to all occurrence of packages in the file EXCEPT FOR: package.config file here not a path

For me, it helped all the projects with issues in that solution folder to find and recognize packages in package folder after it was moved. Hopefully, this answer will help someone that has a similar struggle with me. Have fun coding guys!

Tritium answered 9/10, 2022 at 21:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.