Fix package code for new NuGet.

The new NuGet uses tolower paths, and we need to react to it.

Port https://github.com/dotnet/cli/pull/2722
Port https://github.com/dotnet/cli/pull/3554
This commit is contained in:
Eric Erhardt 2016-07-26 13:20:23 -05:00
parent d54bba96cd
commit a48def9ade
19 changed files with 150 additions and 73 deletions

View file

@ -57,5 +57,9 @@
"ClassLibrary2",
"ClassLibrary3"
]
},
"packageFolders": {
"/foo/packages": {},
"/foo/packages2": {}
}
}

View file

@ -55,7 +55,7 @@ namespace Microsoft.DotNet.Cli.Utils
return Path.Combine(
GetBaseToolPath(packageId),
version.ToNormalizedString(),
version.ToNormalizedString().ToLowerInvariant(),
framework.GetShortFolderName(),
"project.lock.json");
}
@ -65,7 +65,7 @@ namespace Microsoft.DotNet.Cli.Utils
return Path.Combine(
_packagesDirectory,
".tools",
packageId);
packageId.ToLowerInvariant());
}
private IEnumerable<NuGetVersion> GetAvailableToolVersions(string packageId)

View file

@ -67,7 +67,7 @@ namespace Microsoft.DotNet.Cli.Compiler.Common
.Any();
// coreclr should be present for standalone apps
if (! isCoreClrPresent)
if (!isCoreClrPresent)
{
throw new InvalidOperationException("Expected coreclr library not found in package graph. Please try running dotnet restore again.");
}
@ -276,8 +276,16 @@ namespace Microsoft.DotNet.Cli.Compiler.Common
private void AddAdditionalProbingPaths(JObject runtimeOptions)
{
var additionalProbingPaths = new JArray(_context.PackagesDirectory);
runtimeOptions.Add("additionalProbingPaths", additionalProbingPaths);
if (_context.LockFile != null)
{
var additionalProbingPaths = new JArray();
foreach (var packageFolder in _context.LockFile.PackageFolders)
{
additionalProbingPaths.Add(packageFolder.Path);
}
runtimeOptions.Add("additionalProbingPaths", additionalProbingPaths);
}
}
public void WriteDeps(IEnumerable<LibraryExport> runtimeExports, IEnumerable<LibraryExport> compilationExports)

View file

@ -4,7 +4,7 @@
using System.IO;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.Extensions.EnvironmentAbstractions;
using Microsoft.DotNet.ProjectModel.Resolution;
using NuGet.Configuration;
namespace Microsoft.DotNet.Configurer
{
@ -23,7 +23,7 @@ namespace Microsoft.DotNet.Configurer
{
if (string.IsNullOrEmpty(_nugetCachePath))
{
_nugetCachePath = PackageDependencyProvider.ResolvePackagesPath(null, null);
_nugetCachePath = NuGetPathContext.Create(new NullSettings()).UserPackageFolder;
}
return _nugetCachePath;

View file

@ -20,6 +20,7 @@ namespace Microsoft.DotNet.ProjectModel.Graph
public IList<LockFileProjectLibrary> ProjectLibraries { get; set; } = new List<LockFileProjectLibrary>();
public IList<LockFileTarget> Targets { get; set; } = new List<LockFileTarget>();
public ExportFile ExportFile { get; set; }
public IList<LockFilePackageFolder> PackageFolders { get; set; } = new List<LockFilePackageFolder>();
public LockFile(string lockFilePath)
{

View file

@ -0,0 +1,10 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace Microsoft.DotNet.ProjectModel.Graph
{
public class LockFilePackageFolder
{
public string Path { get; set; }
}
}

View file

@ -117,6 +117,7 @@ namespace Microsoft.DotNet.ProjectModel.Graph
lockFile.Targets = ReadObject(cursor.Value<JObject>("targets"), ReadTarget);
lockFile.ProjectFileDependencyGroups = ReadObject(cursor.Value<JObject>("projectFileDependencyGroups"), ReadProjectFileDependencyGroup);
ReadLibrary(cursor.Value<JObject>("libraries"), lockFile);
lockFile.PackageFolders = ReadObject(cursor.Value<JObject>("packageFolders"), ReadPackageFolder);
return lockFile;
}
@ -194,6 +195,20 @@ namespace Microsoft.DotNet.ProjectModel.Graph
return target;
}
private LockFilePackageFolder ReadPackageFolder(string property, JToken json)
{
var jobject = json as JObject;
if (jobject == null)
{
throw FileFormatException.Create("The value type is not an object.", json);
}
var packageFolder = new LockFilePackageFolder();
packageFolder.Path = property;
return packageFolder;
}
private LockFileTargetLibrary ReadTargetLibrary(string property, JToken json)
{
var jobject = json as JObject;

View file

@ -3,14 +3,14 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using Microsoft.DotNet.InternalAbstractions;
using Microsoft.DotNet.ProjectModel.Graph;
using Microsoft.DotNet.ProjectModel.Resolution;
using NuGet.Common;
using NuGet.Configuration;
using NuGet.Frameworks;
namespace Microsoft.DotNet.ProjectModel
@ -210,7 +210,6 @@ namespace Microsoft.DotNet.ProjectModel
}
RootDirectory = globalSettings?.DirectoryPath ?? RootDirectory;
PackagesDirectory = PackagesDirectory ?? PackageDependencyProvider.ResolvePackagesPath(RootDirectory, globalSettings);
FrameworkReferenceResolver frameworkReferenceResolver;
if (string.IsNullOrEmpty(ReferenceAssembliesPath))
@ -228,6 +227,17 @@ namespace Microsoft.DotNet.ProjectModel
ReadLockFile(diagnostics);
// some callers only give ProjectContextBuilder a LockFile
ProjectDirectory = ProjectDirectory ?? TryGetProjectDirectoryFromLockFile();
INuGetPathContext nugetPathContext = null;
if (ProjectDirectory != null)
{
nugetPathContext = NuGetPathContext.Create(ProjectDirectory);
}
PackagesDirectory = PackagesDirectory ?? nugetPathContext?.UserPackageFolder;
var validLockFile = true;
string lockFileValidationMessage = null;
@ -271,7 +281,7 @@ namespace Microsoft.DotNet.ProjectModel
target = SelectTarget(LockFile, isPortable);
if (target != null)
{
var nugetPackageResolver = new PackageDependencyProvider(PackagesDirectory, frameworkReferenceResolver);
var nugetPackageResolver = new PackageDependencyProvider(nugetPathContext, frameworkReferenceResolver);
var msbuildProjectResolver = new MSBuildDependencyProvider(Project, ProjectResolver);
ScanLibraries(target, lockFileLookup, libraries, msbuildProjectResolver, nugetPackageResolver, projectResolver);
@ -377,6 +387,18 @@ namespace Microsoft.DotNet.ProjectModel
diagnostics);
}
private string TryGetProjectDirectoryFromLockFile()
{
string result = null;
if (LockFile != null && !string.IsNullOrEmpty(LockFile.LockFilePath))
{
result = Path.GetDirectoryName(LockFile.LockFilePath);
}
return result;
}
private void ReadLockFile(ICollection<DiagnosticMessage> diagnostics)
{
try

View file

@ -8,6 +8,7 @@ using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using Microsoft.DotNet.ProjectModel.Graph;
using NuGet.Common;
using NuGet.Frameworks;
using NuGet.Packaging;
@ -15,12 +16,16 @@ namespace Microsoft.DotNet.ProjectModel.Resolution
{
public class PackageDependencyProvider
{
private readonly VersionFolderPathResolver _packagePathResolver;
private readonly FallbackPackagePathResolver _packagePathResolver;
private readonly FrameworkReferenceResolver _frameworkReferenceResolver;
public PackageDependencyProvider(string packagesPath, FrameworkReferenceResolver frameworkReferenceResolver)
public PackageDependencyProvider(INuGetPathContext nugetPathContext, FrameworkReferenceResolver frameworkReferenceResolver)
{
_packagePathResolver = new VersionFolderPathResolver(packagesPath);
if (nugetPathContext != null)
{
_packagePathResolver = new FallbackPackagePathResolver(nugetPathContext);
}
_frameworkReferenceResolver = frameworkReferenceResolver;
}
@ -40,8 +45,8 @@ namespace Microsoft.DotNet.ProjectModel.Resolution
var dependencies = new List<LibraryRange>(targetLibrary.Dependencies.Count + targetLibrary.FrameworkAssemblies.Count);
PopulateDependencies(dependencies, targetLibrary, targetFramework);
var path = _packagePathResolver.GetInstallPath(package.Name, package.Version);
var exists = Directory.Exists(path);
var path = _packagePathResolver?.GetPackageDirectory(package.Name, package.Version);
bool exists = path != null;
if (exists)
{
@ -155,35 +160,5 @@ namespace Microsoft.DotNet.ProjectModel.Resolution
{
return string.Equals(Path.GetFileName(path), "_._", StringComparison.Ordinal);
}
public static string ResolvePackagesPath(string rootDirectory, GlobalSettings settings)
{
// Order
// 1. global.json { "packages": "..." }
// 2. EnvironmentNames.PackagesStore environment variable
// 3. NuGet.config repositoryPath (maybe)?
// 4. {DefaultLocalRuntimeHomeDir}\packages
if (!string.IsNullOrEmpty(settings?.PackagesPath))
{
return Path.Combine(rootDirectory, settings.PackagesPath);
}
var runtimePackages = Environment.GetEnvironmentVariable(EnvironmentNames.PackagesStore);
if (!string.IsNullOrEmpty(runtimePackages))
{
return runtimePackages;
}
var profileDirectory = Environment.GetEnvironmentVariable("USERPROFILE");
if (string.IsNullOrEmpty(profileDirectory))
{
profileDirectory = Environment.GetEnvironmentVariable("HOME");
}
return Path.Combine(profileDirectory, ".nuget", "packages");
}
}
}

View file

@ -9,6 +9,7 @@
"target": "project"
},
"Newtonsoft.Json": "9.0.1",
"NuGet.Configuration": "3.5.0-rc1-1653",
"NuGet.Packaging": "3.5.0-rc1-1653",
"NuGet.RuntimeModel": "3.5.0-rc1-1653",
"System.Reflection.Metadata": "1.3.0"

View file

@ -53,7 +53,8 @@ namespace Microsoft.Extensions.DependencyModel.Resolution
if (ResolverUtils.TryResolvePackagePath(_fileSystem, library, _packageCacheDirectory, out packagePath))
{
var hashAlgorithm = library.Hash.Substring(0, hashSplitterPos);
var cacheHashPath = Path.Combine(packagePath, $"{library.Name}.{library.Version}.nupkg.{hashAlgorithm}");
var cacheHashFileName = $"{library.Name.ToLowerInvariant()}.{library.Version.ToLowerInvariant()}.nupkg.{hashAlgorithm}";
var cacheHashPath = Path.Combine(packagePath, cacheHashFileName);
if (_fileSystem.File.Exists(cacheHashPath) &&
_fileSystem.File.ReadAllText(cacheHashPath) == library.Hash.Substring(hashSplitterPos + 1))

View file

@ -12,7 +12,11 @@ namespace Microsoft.Extensions.DependencyModel.Resolution
{
internal static bool TryResolvePackagePath(IFileSystem fileSystem, CompilationLibrary library, string basePath, out string packagePath)
{
packagePath = Path.Combine(basePath, library.Name, library.Version);
packagePath = Path.Combine(
basePath,
library.Name.ToLowerInvariant(),
library.Version.ToLowerInvariant());
if (fileSystem.Directory.Exists(packagePath))
{
return true;

View file

@ -13,6 +13,7 @@ using Microsoft.DotNet.Cli.Compiler.Common;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.ProjectModel;
using Microsoft.DotNet.ProjectModel.Resolution;
using NuGet.Configuration;
namespace Microsoft.DotNet.Tools.Compiler.Fsc
{
@ -296,7 +297,7 @@ namespace Microsoft.DotNet.Tools.Compiler.Fsc
private static FscCommandSpec ResolveFsc(List<string> fscArgs, string temp)
{
var nugetPackagesRoot = PackageDependencyProvider.ResolvePackagesPath(null, null);
var nugetPackagesRoot = NuGetPathContext.Create(Directory.GetCurrentDirectory())?.UserPackageFolder;
var depsFile = Path.Combine(AppContext.BaseDirectory, "dotnet-compile-fsc" + FileNameSuffixes.DepsJson);
var depsJsonCommandResolver = new DepsJsonCommandResolver(nugetPackagesRoot);

View file

@ -145,13 +145,16 @@ namespace Microsoft.DotNet.Tools.Run
}
List<string> hostArgs = new List<string>();
if (!_context.TargetFramework.IsDesktop())
if (!_context.TargetFramework.IsDesktop() && _context.LockFile != null)
{
// Add Nuget Packages Probing Path
var nugetPackagesRoot = _context.PackagesDirectory;
var probingPathArg = "--additionalprobingpath";
hostArgs.Insert(0, nugetPackagesRoot);
hostArgs.Insert(0, probingPathArg);
// Add Nuget Packages Probing Paths
const string probingPathArg = "--additionalprobingpath";
foreach (var packageFolder in _context.LockFile.PackageFolders)
{
hostArgs.Insert(0, packageFolder.Path);
hostArgs.Insert(0, probingPathArg);
}
}
// Now launch the output and give it the results

View file

@ -120,6 +120,17 @@ namespace Microsoft.DotNet.ProjectModel.Tests
Assert.NotNull(LockFileReader.Read(lockFilePath, designTime: true));
}
[Fact]
public void TestPackageFoldersLoadCorrectly()
{
var lockFilePath = GetLockFilePath("valid");
var lockFile = LockFileReader.Read(lockFilePath, designTime: false);
Assert.Equal(2, lockFile.PackageFolders.Count);
Assert.Equal("/foo/packages", lockFile.PackageFolders[0].Path);
Assert.Equal("/foo/packages2", lockFile.PackageFolders[1].Path);
}
private static int LibraryNumberFromName(Microsoft.DotNet.ProjectModel.Graph.LockFileTargetLibrary library)
{
var libraryName = library.Name;

View file

@ -3,6 +3,7 @@ using Microsoft.DotNet.ProjectModel.Graph;
using Microsoft.DotNet.ProjectModel.Resolution;
using Microsoft.DotNet.TestFramework;
using Microsoft.DotNet.Tools.Test.Utilities;
using NuGet.Configuration;
using NuGet.Frameworks;
using NuGet.Versioning;
using Xunit;
@ -15,7 +16,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
[Fact]
public void GetDescriptionShouldNotModifyTarget()
{
var provider = new PackageDependencyProvider("/foo/packages", new FrameworkReferenceResolver("/foo/references"));
var provider = new PackageDependencyProvider(NuGetPathContext.Create("/foo/packages"), new FrameworkReferenceResolver("/foo/references"));
var package = new LockFilePackageLibrary();
package.Name = "Something";
package.Version = NuGetVersion.Parse("1.0.0");
@ -46,7 +47,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
[Fact]
public void HasCompileTimePlaceholderChecksAllCompileTimeAssets()
{
var provider = new PackageDependencyProvider("/foo/packages", new FrameworkReferenceResolver("/foo/references"));
var provider = new PackageDependencyProvider(NuGetPathContext.Create("/foo/packages"), new FrameworkReferenceResolver("/foo/references"));
var package = new LockFilePackageLibrary();
package.Name = "Something";
package.Version = NuGetVersion.Parse("1.0.0");
@ -74,7 +75,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
[Fact]
public void HasCompileTimePlaceholderReturnsFalseIfEmpty()
{
var provider = new PackageDependencyProvider("/foo/packages", new FrameworkReferenceResolver("/foo/references"));
var provider = new PackageDependencyProvider(NuGetPathContext.Create("/foo/packages"), new FrameworkReferenceResolver("/foo/references"));
var package = new LockFilePackageLibrary();
package.Name = "Something";
package.Version = NuGetVersion.Parse("1.0.0");

View file

@ -19,7 +19,7 @@ namespace Microsoft.Extensions.DependencyModel.Tests
[Fact]
public void SholdUseEnvironmentVariableToGetDefaultLocation()
{
var result = PackageCacheCompilationAssemblyResolver.GetDefaultPackageCacheDirectory(GetDefaultEnviroment());
var result = PackageCacheCompilationAssemblyResolver.GetDefaultPackageCacheDirectory(GetDefaultEnvironment());
result.Should().Be(CachePath);
}
@ -55,10 +55,10 @@ namespace Microsoft.Extensions.DependencyModel.Tests
[Fact]
public void ChecksHashFile()
{
var packagePath = Path.Combine(CachePath, F.DefaultPackageName, F.DefaultVersion);
var packagePath = GetPackagesPath(F.DefaultPackageName, F.DefaultVersion);
var fileSystem = FileSystemMockBuilder.Create()
.AddFile(
Path.Combine(packagePath, $"{F.DefaultPackageName}.{F.DefaultVersion}.nupkg.{F.DefaultHashAlgoritm}"),
GetHashFilePath(packagePath),
"WRONGHASH"
)
.AddFiles(packagePath, F.DefaultAssemblies)
@ -74,10 +74,10 @@ namespace Microsoft.Extensions.DependencyModel.Tests
[Fact]
public void ResolvesAllAssemblies()
{
var packagePath = Path.Combine(CachePath, F.DefaultPackageName, F.DefaultVersion);
var packagePath = GetPackagesPath(F.DefaultPackageName, F.DefaultVersion);
var fileSystem = FileSystemMockBuilder.Create()
.AddFile(
Path.Combine(packagePath, $"{F.DefaultPackageName}.{F.DefaultVersion}.nupkg.{F.DefaultHashAlgoritm}"),
GetHashFilePath(packagePath),
F.DefaultHashValue
)
.AddFiles(packagePath, F.TwoAssemblies)
@ -98,10 +98,10 @@ namespace Microsoft.Extensions.DependencyModel.Tests
[Fact]
public void FailsWhenOneOfAssembliesNotFound()
{
var packagePath = Path.Combine(CachePath, F.DefaultPackageName, F.DefaultVersion);
var packagePath = GetPackagesPath(F.DefaultPackageName, F.DefaultVersion);
var fileSystem = FileSystemMockBuilder.Create()
.AddFile(
Path.Combine(packagePath, $"{F.DefaultPackageName}.{F.DefaultVersion}.nupkg.{F.DefaultHashAlgoritm}"),
GetHashFilePath(packagePath),
F.DefaultHashValue
)
.AddFiles(packagePath, F.DefaultAssemblyPath)
@ -117,13 +117,23 @@ namespace Microsoft.Extensions.DependencyModel.Tests
.And.Contain(library.Name);
}
private IEnvironment GetDefaultEnviroment()
private IEnvironment GetDefaultEnvironment()
{
return EnvironmentMockBuilder.Create()
.AddVariable("DOTNET_PACKAGES_CACHE", CachePath)
.Build();
}
private static string GetPackagesPath(string id, string version)
{
return PackageResolverTest.GetPackagesPath(CachePath, id, version);
}
private static string GetHashFilePath(string packagePath)
{
return Path.Combine(
packagePath,
$"{F.DefaultPackageName.ToLowerInvariant()}.{F.DefaultVersion.ToLowerInvariant()}.nupkg.{F.DefaultHashAlgoritm}");
}
}
}

View file

@ -17,7 +17,7 @@ namespace Microsoft.Extensions.DependencyModel.Tests
private static string PackagesPath = Path.Combine("package", "directory", "location");
[Fact]
public void SholdUseEnvironmentVariableToGetDefaultLocation()
public void ShouldUseEnvironmentVariableToGetDefaultLocation()
{
var environment = EnvironmentMockBuilder.Create()
.AddVariable("NUGET_PACKAGES", PackagesPath)
@ -29,7 +29,7 @@ namespace Microsoft.Extensions.DependencyModel.Tests
[Fact]
public void SholdUseNugetUnderUserProfileOnWindows()
public void ShouldUseNugetUnderUserProfileOnWindows()
{
var environment = EnvironmentMockBuilder.Create()
.AddVariable("USERPROFILE", "User Profile")
@ -40,7 +40,7 @@ namespace Microsoft.Extensions.DependencyModel.Tests
}
[Fact]
public void SholdUseNugetUnderHomeOnNonWindows()
public void ShouldUseNugetUnderHomeOnNonWindows()
{
var environment = EnvironmentMockBuilder.Create()
.AddVariable("HOME", "User Home")
@ -53,7 +53,7 @@ namespace Microsoft.Extensions.DependencyModel.Tests
[Fact]
public void ResolvesAllAssemblies()
{
var packagePath = Path.Combine(PackagesPath, F.DefaultPackageName, F.DefaultVersion);
var packagePath = GetPackagesPath(F.DefaultPackageName, F.DefaultVersion);
var fileSystem = FileSystemMockBuilder.Create()
.AddFiles(packagePath, F.TwoAssemblies)
.Build();
@ -73,7 +73,7 @@ namespace Microsoft.Extensions.DependencyModel.Tests
[Fact]
public void FailsWhenOneOfAssembliesNotFound()
{
var packagePath = Path.Combine(PackagesPath, F.DefaultPackageName, F.DefaultVersion);
var packagePath = GetPackagesPath(F.DefaultPackageName, F.DefaultVersion);
var fileSystem = FileSystemMockBuilder.Create()
.AddFiles(packagePath, F.DefaultAssemblyPath)
.Build();
@ -87,5 +87,15 @@ namespace Microsoft.Extensions.DependencyModel.Tests
.Contain(F.SecondAssemblyPath)
.And.Contain(library.Name);
}
private static string GetPackagesPath(string id, string version)
{
return GetPackagesPath(PackagesPath, id, version);
}
internal static string GetPackagesPath(string basePath, string id, string version)
{
return Path.Combine(basePath, id.ToLowerInvariant(), version.ToLowerInvariant());
}
}
}

View file

@ -76,7 +76,7 @@ A command is running to initially populate your local package cache, to improve
[Fact]
public void It_creates_a_sentinel_file_under_the_nuget_cache_folder()
{
_nugetCacheFolder.Should().HaveDirectory("Microsoft.NETCore.App");
_nugetCacheFolder.Should().HaveDirectory("microsoft.netcore.app");
}
private string GetDotnetVersion()