Skip to content

Commit a48def9

Browse files
committed
Fix package code for new NuGet.
The new NuGet uses tolower paths, and we need to react to it. Port dotnet#2722 Port dotnet#3554
1 parent d54bba9 commit a48def9

File tree

19 files changed

+150
-73
lines changed

19 files changed

+150
-73
lines changed

TestAssets/LockFiles/ExportFiles/valid/project.lock.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,9 @@
5757
"ClassLibrary2",
5858
"ClassLibrary3"
5959
]
60+
},
61+
"packageFolders": {
62+
"/foo/packages": {},
63+
"/foo/packages2": {}
6064
}
6165
}

src/Microsoft.DotNet.Cli.Utils/CommandResolution/ToolPathCalculator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public string GetLockFilePath(string packageId, NuGetVersion version, NuGetFrame
5555

5656
return Path.Combine(
5757
GetBaseToolPath(packageId),
58-
version.ToNormalizedString(),
58+
version.ToNormalizedString().ToLowerInvariant(),
5959
framework.GetShortFolderName(),
6060
"project.lock.json");
6161
}
@@ -65,7 +65,7 @@ private string GetBaseToolPath(string packageId)
6565
return Path.Combine(
6666
_packagesDirectory,
6767
".tools",
68-
packageId);
68+
packageId.ToLowerInvariant());
6969
}
7070

7171
private IEnumerable<NuGetVersion> GetAvailableToolVersions(string packageId)

src/Microsoft.DotNet.Compiler.Common/Executable.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ private void VerifyCoreClrPresenceInPackageGraph()
6767
.Any();
6868

6969
// coreclr should be present for standalone apps
70-
if (! isCoreClrPresent)
70+
if (!isCoreClrPresent)
7171
{
7272
throw new InvalidOperationException("Expected coreclr library not found in package graph. Please try running dotnet restore again.");
7373
}
@@ -94,7 +94,7 @@ private void MakeCompilationOutputRunnableForFullFramework()
9494
}
9595

9696
private void MakeCompilationOutputRunnableForCoreCLR(bool skipRuntimeConfig)
97-
{
97+
{
9898
WriteDepsFileAndCopyProjectDependencies(_exporter, skipRuntimeConfig);
9999

100100
var isRunnable = _compilerOptions.EmitEntryPoint ?? _context.ProjectFile.OverrideIsRunnable;
@@ -276,8 +276,16 @@ private void WriteDevRuntimeConfig()
276276

277277
private void AddAdditionalProbingPaths(JObject runtimeOptions)
278278
{
279-
var additionalProbingPaths = new JArray(_context.PackagesDirectory);
280-
runtimeOptions.Add("additionalProbingPaths", additionalProbingPaths);
279+
if (_context.LockFile != null)
280+
{
281+
var additionalProbingPaths = new JArray();
282+
foreach (var packageFolder in _context.LockFile.PackageFolders)
283+
{
284+
additionalProbingPaths.Add(packageFolder.Path);
285+
}
286+
287+
runtimeOptions.Add("additionalProbingPaths", additionalProbingPaths);
288+
}
281289
}
282290

283291
public void WriteDeps(IEnumerable<LibraryExport> runtimeExports, IEnumerable<LibraryExport> compilationExports)

src/Microsoft.DotNet.Configurer/NuGetCacheSentinel.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
using System.IO;
55
using Microsoft.DotNet.Cli.Utils;
66
using Microsoft.Extensions.EnvironmentAbstractions;
7-
using Microsoft.DotNet.ProjectModel.Resolution;
7+
using NuGet.Configuration;
88

99
namespace Microsoft.DotNet.Configurer
1010
{
@@ -23,7 +23,7 @@ private string NuGetCachePath
2323
{
2424
if (string.IsNullOrEmpty(_nugetCachePath))
2525
{
26-
_nugetCachePath = PackageDependencyProvider.ResolvePackagesPath(null, null);
26+
_nugetCachePath = NuGetPathContext.Create(new NullSettings()).UserPackageFolder;
2727
}
2828

2929
return _nugetCachePath;

src/Microsoft.DotNet.ProjectModel/Graph/LockFile.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public class LockFile
2020
public IList<LockFileProjectLibrary> ProjectLibraries { get; set; } = new List<LockFileProjectLibrary>();
2121
public IList<LockFileTarget> Targets { get; set; } = new List<LockFileTarget>();
2222
public ExportFile ExportFile { get; set; }
23+
public IList<LockFilePackageFolder> PackageFolders { get; set; } = new List<LockFilePackageFolder>();
2324

2425
public LockFile(string lockFilePath)
2526
{
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Copyright (c) .NET Foundation and contributors. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
namespace Microsoft.DotNet.ProjectModel.Graph
5+
{
6+
public class LockFilePackageFolder
7+
{
8+
public string Path { get; set; }
9+
}
10+
}

src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ private LockFile ReadLockFile(string lockFilePath, JObject cursor)
117117
lockFile.Targets = ReadObject(cursor.Value<JObject>("targets"), ReadTarget);
118118
lockFile.ProjectFileDependencyGroups = ReadObject(cursor.Value<JObject>("projectFileDependencyGroups"), ReadProjectFileDependencyGroup);
119119
ReadLibrary(cursor.Value<JObject>("libraries"), lockFile);
120+
lockFile.PackageFolders = ReadObject(cursor.Value<JObject>("packageFolders"), ReadPackageFolder);
120121

121122
return lockFile;
122123
}
@@ -194,6 +195,20 @@ private LockFileTarget ReadTarget(string property, JToken json)
194195
return target;
195196
}
196197

198+
private LockFilePackageFolder ReadPackageFolder(string property, JToken json)
199+
{
200+
var jobject = json as JObject;
201+
if (jobject == null)
202+
{
203+
throw FileFormatException.Create("The value type is not an object.", json);
204+
}
205+
206+
var packageFolder = new LockFilePackageFolder();
207+
packageFolder.Path = property;
208+
209+
return packageFolder;
210+
}
211+
197212
private LockFileTargetLibrary ReadTargetLibrary(string property, JToken json)
198213
{
199214
var jobject = json as JObject;

src/Microsoft.DotNet.ProjectModel/ProjectContextBuilder.cs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33

44
using System;
55
using System.Collections.Generic;
6-
using System.Diagnostics;
76
using System.IO;
87
using System.Linq;
9-
using System.Reflection;
108
using System.Text;
119
using Microsoft.DotNet.InternalAbstractions;
1210
using Microsoft.DotNet.ProjectModel.Graph;
1311
using Microsoft.DotNet.ProjectModel.Resolution;
12+
using NuGet.Common;
13+
using NuGet.Configuration;
1414
using NuGet.Frameworks;
1515

1616
namespace Microsoft.DotNet.ProjectModel
@@ -210,7 +210,6 @@ public ProjectContext Build()
210210
}
211211

212212
RootDirectory = globalSettings?.DirectoryPath ?? RootDirectory;
213-
PackagesDirectory = PackagesDirectory ?? PackageDependencyProvider.ResolvePackagesPath(RootDirectory, globalSettings);
214213

215214
FrameworkReferenceResolver frameworkReferenceResolver;
216215
if (string.IsNullOrEmpty(ReferenceAssembliesPath))
@@ -228,6 +227,17 @@ public ProjectContext Build()
228227

229228
ReadLockFile(diagnostics);
230229

230+
// some callers only give ProjectContextBuilder a LockFile
231+
ProjectDirectory = ProjectDirectory ?? TryGetProjectDirectoryFromLockFile();
232+
233+
INuGetPathContext nugetPathContext = null;
234+
if (ProjectDirectory != null)
235+
{
236+
nugetPathContext = NuGetPathContext.Create(ProjectDirectory);
237+
}
238+
239+
PackagesDirectory = PackagesDirectory ?? nugetPathContext?.UserPackageFolder;
240+
231241
var validLockFile = true;
232242
string lockFileValidationMessage = null;
233243

@@ -271,7 +281,7 @@ public ProjectContext Build()
271281
target = SelectTarget(LockFile, isPortable);
272282
if (target != null)
273283
{
274-
var nugetPackageResolver = new PackageDependencyProvider(PackagesDirectory, frameworkReferenceResolver);
284+
var nugetPackageResolver = new PackageDependencyProvider(nugetPathContext, frameworkReferenceResolver);
275285
var msbuildProjectResolver = new MSBuildDependencyProvider(Project, ProjectResolver);
276286
ScanLibraries(target, lockFileLookup, libraries, msbuildProjectResolver, nugetPackageResolver, projectResolver);
277287

@@ -377,6 +387,18 @@ public ProjectContext Build()
377387
diagnostics);
378388
}
379389

390+
private string TryGetProjectDirectoryFromLockFile()
391+
{
392+
string result = null;
393+
394+
if (LockFile != null && !string.IsNullOrEmpty(LockFile.LockFilePath))
395+
{
396+
result = Path.GetDirectoryName(LockFile.LockFilePath);
397+
}
398+
399+
return result;
400+
}
401+
380402
private void ReadLockFile(ICollection<DiagnosticMessage> diagnostics)
381403
{
382404
try

src/Microsoft.DotNet.ProjectModel/Resolution/PackageDependencyProvider.cs

Lines changed: 10 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,24 @@
88
using System.Reflection.Metadata;
99
using System.Reflection.PortableExecutable;
1010
using Microsoft.DotNet.ProjectModel.Graph;
11+
using NuGet.Common;
1112
using NuGet.Frameworks;
1213
using NuGet.Packaging;
1314

1415
namespace Microsoft.DotNet.ProjectModel.Resolution
1516
{
1617
public class PackageDependencyProvider
1718
{
18-
private readonly VersionFolderPathResolver _packagePathResolver;
19+
private readonly FallbackPackagePathResolver _packagePathResolver;
1920
private readonly FrameworkReferenceResolver _frameworkReferenceResolver;
2021

21-
public PackageDependencyProvider(string packagesPath, FrameworkReferenceResolver frameworkReferenceResolver)
22+
public PackageDependencyProvider(INuGetPathContext nugetPathContext, FrameworkReferenceResolver frameworkReferenceResolver)
2223
{
23-
_packagePathResolver = new VersionFolderPathResolver(packagesPath);
24+
if (nugetPathContext != null)
25+
{
26+
_packagePathResolver = new FallbackPackagePathResolver(nugetPathContext);
27+
}
28+
2429
_frameworkReferenceResolver = frameworkReferenceResolver;
2530
}
2631

@@ -40,8 +45,8 @@ public PackageDescription GetDescription(NuGetFramework targetFramework, LockFil
4045
var dependencies = new List<LibraryRange>(targetLibrary.Dependencies.Count + targetLibrary.FrameworkAssemblies.Count);
4146
PopulateDependencies(dependencies, targetLibrary, targetFramework);
4247

43-
var path = _packagePathResolver.GetInstallPath(package.Name, package.Version);
44-
var exists = Directory.Exists(path);
48+
var path = _packagePathResolver?.GetPackageDirectory(package.Name, package.Version);
49+
bool exists = path != null;
4550

4651
if (exists)
4752
{
@@ -155,35 +160,5 @@ public static bool IsPlaceholderFile(string path)
155160
{
156161
return string.Equals(Path.GetFileName(path), "_._", StringComparison.Ordinal);
157162
}
158-
159-
public static string ResolvePackagesPath(string rootDirectory, GlobalSettings settings)
160-
{
161-
// Order
162-
// 1. global.json { "packages": "..." }
163-
// 2. EnvironmentNames.PackagesStore environment variable
164-
// 3. NuGet.config repositoryPath (maybe)?
165-
// 4. {DefaultLocalRuntimeHomeDir}\packages
166-
167-
if (!string.IsNullOrEmpty(settings?.PackagesPath))
168-
{
169-
return Path.Combine(rootDirectory, settings.PackagesPath);
170-
}
171-
172-
var runtimePackages = Environment.GetEnvironmentVariable(EnvironmentNames.PackagesStore);
173-
174-
if (!string.IsNullOrEmpty(runtimePackages))
175-
{
176-
return runtimePackages;
177-
}
178-
179-
var profileDirectory = Environment.GetEnvironmentVariable("USERPROFILE");
180-
181-
if (string.IsNullOrEmpty(profileDirectory))
182-
{
183-
profileDirectory = Environment.GetEnvironmentVariable("HOME");
184-
}
185-
186-
return Path.Combine(profileDirectory, ".nuget", "packages");
187-
}
188163
}
189164
}

src/Microsoft.DotNet.ProjectModel/project.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"target": "project"
1010
},
1111
"Newtonsoft.Json": "9.0.1",
12+
"NuGet.Configuration": "3.5.0-rc1-1653",
1213
"NuGet.Packaging": "3.5.0-rc1-1653",
1314
"NuGet.RuntimeModel": "3.5.0-rc1-1653",
1415
"System.Reflection.Metadata": "1.3.0"

src/Microsoft.Extensions.DependencyModel/Resolution/PackageCacheCompilationAssemblyResolver.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ public bool TryResolveAssemblyPaths(CompilationLibrary library, List<string> ass
5353
if (ResolverUtils.TryResolvePackagePath(_fileSystem, library, _packageCacheDirectory, out packagePath))
5454
{
5555
var hashAlgorithm = library.Hash.Substring(0, hashSplitterPos);
56-
var cacheHashPath = Path.Combine(packagePath, $"{library.Name}.{library.Version}.nupkg.{hashAlgorithm}");
56+
var cacheHashFileName = $"{library.Name.ToLowerInvariant()}.{library.Version.ToLowerInvariant()}.nupkg.{hashAlgorithm}";
57+
var cacheHashPath = Path.Combine(packagePath, cacheHashFileName);
5758

5859
if (_fileSystem.File.Exists(cacheHashPath) &&
5960
_fileSystem.File.ReadAllText(cacheHashPath) == library.Hash.Substring(hashSplitterPos + 1))

src/Microsoft.Extensions.DependencyModel/Resolution/ResolverUtils.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ internal static class ResolverUtils
1212
{
1313
internal static bool TryResolvePackagePath(IFileSystem fileSystem, CompilationLibrary library, string basePath, out string packagePath)
1414
{
15-
packagePath = Path.Combine(basePath, library.Name, library.Version);
15+
packagePath = Path.Combine(
16+
basePath,
17+
library.Name.ToLowerInvariant(),
18+
library.Version.ToLowerInvariant());
19+
1620
if (fileSystem.Directory.Exists(packagePath))
1721
{
1822
return true;

src/dotnet-compile-fsc/Program.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
using Microsoft.DotNet.Cli.Utils;
1414
using Microsoft.DotNet.ProjectModel;
1515
using Microsoft.DotNet.ProjectModel.Resolution;
16+
using NuGet.Configuration;
1617

1718
namespace Microsoft.DotNet.Tools.Compiler.Fsc
1819
{
@@ -296,7 +297,7 @@ private static Command RunFsc(List<string> fscArgs, string temp)
296297

297298
private static FscCommandSpec ResolveFsc(List<string> fscArgs, string temp)
298299
{
299-
var nugetPackagesRoot = PackageDependencyProvider.ResolvePackagesPath(null, null);
300+
var nugetPackagesRoot = NuGetPathContext.Create(Directory.GetCurrentDirectory())?.UserPackageFolder;
300301
var depsFile = Path.Combine(AppContext.BaseDirectory, "dotnet-compile-fsc" + FileNameSuffixes.DepsJson);
301302

302303
var depsJsonCommandResolver = new DepsJsonCommandResolver(nugetPackagesRoot);

src/dotnet/commands/dotnet-run/RunCommand.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,13 +145,16 @@ private int RunExecutable()
145145
}
146146

147147
List<string> hostArgs = new List<string>();
148-
if (!_context.TargetFramework.IsDesktop())
148+
if (!_context.TargetFramework.IsDesktop() && _context.LockFile != null)
149149
{
150-
// Add Nuget Packages Probing Path
151-
var nugetPackagesRoot = _context.PackagesDirectory;
152-
var probingPathArg = "--additionalprobingpath";
153-
hostArgs.Insert(0, nugetPackagesRoot);
154-
hostArgs.Insert(0, probingPathArg);
150+
// Add Nuget Packages Probing Paths
151+
const string probingPathArg = "--additionalprobingpath";
152+
153+
foreach (var packageFolder in _context.LockFile.PackageFolders)
154+
{
155+
hostArgs.Insert(0, packageFolder.Path);
156+
hostArgs.Insert(0, probingPathArg);
157+
}
155158
}
156159

157160
// Now launch the output and give it the results

test/Microsoft.DotNet.ProjectModel.Tests/LockFilePatchingTests.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,17 @@ public void TestMissmatchingFileVersionsUnderDesignTime()
120120
Assert.NotNull(LockFileReader.Read(lockFilePath, designTime: true));
121121
}
122122

123+
[Fact]
124+
public void TestPackageFoldersLoadCorrectly()
125+
{
126+
var lockFilePath = GetLockFilePath("valid");
127+
var lockFile = LockFileReader.Read(lockFilePath, designTime: false);
128+
129+
Assert.Equal(2, lockFile.PackageFolders.Count);
130+
Assert.Equal("/foo/packages", lockFile.PackageFolders[0].Path);
131+
Assert.Equal("/foo/packages2", lockFile.PackageFolders[1].Path);
132+
}
133+
123134
private static int LibraryNumberFromName(Microsoft.DotNet.ProjectModel.Graph.LockFileTargetLibrary library)
124135
{
125136
var libraryName = library.Name;

0 commit comments

Comments
 (0)