2

I'm working on a Xamarin.Forms PCL mobile app in Visual Studio 2017, using project.json for package management (I'm not using PackageReference, since Visual Studio 2017 is required for that, and some of our team are still using Visual Studio 2015). I have multiple projects within the solution, and I have multiple branches of the project, like so:

MobileApp/
    packages/ <<--- (I want nuget packages to be installed here)
    Branches/
        DevBranchSolution/
            MobileApp.sln
            nuget.config
            ProjectA/
            ProjectB/

I want all my (projects / solutions / branches) to be able to reference packages from a single location, so you'll notice I've added the packages folder at the root level in the MobileApp folder. I have a nuget.config file per solution that looks something like:

nuget.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <config>
        <add key="repositoryPath" value="..\..\packages" />
    </config>
    <packageSources>
        <clear />
        <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
        <add key="CustomPackagesLocation" value="..\..\packages" />
    </packageSources>
  <disabledPackageSources />
</configuration>

In Visual Studio when I right-click on the solution, click "Manage NuGet Packages For Solution...", and install a package (e.g. Newtonsoft.Json), I would expect that it would install those package files inside my MobileApp/packages/ folder, the location I set in the solution's nuget.config. But it doesn't. Instead the files are getting put into the global NuGet packages location, which is %USERPROFILE%\.nuget\packages.

Why? Shouldn't my nuget.config file be overriding that? I have verified that when I go to Package Manager Settings, the location of CustomPackagesLocation is correct, but apparently the repositoryPath setting doesn't seem to affect anything.

I also noticed that inside the project.json.lock and Project.nuget.targets files, the package folder is set to the global NuGet packages location (the %USERPROFILE%/.nuget/packages one). Why? Where is it pulling this value from??

jbyrd
  • 5,287
  • 7
  • 52
  • 86
  • Do your projects use PackageReferences? – Matt Ward Aug 10 '17 at 15:59
  • I wish - unfortunately, not all our team is on VS2015, so I didn't want to make VS2017 a requirement. I'm using project.json. – jbyrd Aug 10 '17 at 16:13
  • Have your tried this: https://stackoverflow.com/questions/7676640/how-do-i-specify-the-directory-where-nuget-packages-are-installed Or this: https://stackoverflow.com/questions/4092759/is-it-possible-to-change-the-location-of-packages-for-nuget – BikerDude Aug 10 '17 at 16:56
  • @BikerDude - yup. – jbyrd Aug 10 '17 at 17:27
  • OK so project.json will not put any packages into the solution packages directory. It behaves similar to how a PackageReference works with the NuGet packages only going into the packages folder under your user profile. If you want the packages into a folder relative to your solution you would need to use a packages.config file. Or you are left with changing the packages folder location globally for your entire machine. – Matt Ward Aug 10 '17 at 19:19
  • @MattWard - that must be it! In fact, at the end of the first paragraph [of this article](https://learn.microsoft.com/en-us/nuget/schema/project-json#projectlockjson), it says (referring to project.lock.json) "The build system uses this to choose packages from a global location that are relevant when building the project instead of depending on a local packages folder in the project itself." – jbyrd Aug 10 '17 at 20:23
  • 1
    @jbyrd You can also set the Global Package Folder path in the solution NuGet Config, then you should be able to achieve what you want. – imps Aug 10 '17 at 23:03
  • 1
    @jbyrd Sorry forgot to post the key. The key is globalPackagesFolder – imps Aug 10 '17 at 23:14
  • 2
    @imps - yup, that's it - the main take-away here is: projects that use packages.config use repositoryPath, while other projects (those that use project.json and those that use PackageReferences) use globalPackagesFolder. – jbyrd Aug 11 '17 at 12:09

2 Answers2

3

Why? Where is it pulling this value from??

The default packages directory for Project.json file is %USERPROFILE%/.nuget/packages and project.json project doesn't support repositoryPath config now. This is the reason why you have changed the repositoryPath, but NuGet still put packages into the global NuGet packages location. You can refer to the same issue on GitHub.

If you want to change packages default location for project.json, you can set "NUGET_PACKAGES" environment variable. Just Set "NUGET_PACKAGES" = "....\packages". Or you can place a NuGet.Config file next to the solution with the following content:

<?xml version="1.0" encoding="utf-8"?>
  <configuration>
    <config>
      <add key="globalPackagesFolder" value="..\..\packages" />
    </config>
 </configuration>

See NuGet.Config reference for details on config section.

Leo Liu
  • 71,098
  • 10
  • 114
  • 135
  • Thank you! Yes, this is what I discovered after the tip from @MattWard. It took me forever to hunt down this simple fact (that only packages.config projects use repositoryPath, and others use globalPackagesFolder). Perhaps if I had read the nuget.config docs a little more carefully I would've noticed that; but those facts were in parenthesis and formatted weird - inside a thin table column, so it made it bump down to 3 lines and easier to skip over). – jbyrd Aug 11 '17 at 12:06
0

I had a very similar problem where it wasn't using the packages folder for a class library. For some reason my csproj file had set for a few assemblies. I removed this line and did a update-package -reinstall -project myclasslibrary and it worked again just fine.

I'm not sure what set the HintPath in the first place.

Philip Johnson
  • 1,091
  • 10
  • 24