Skip to content

Commit

Permalink
Fix package code for new NuGet.
Browse files Browse the repository at this point in the history
The new NuGet uses tolower paths, and we need to react to it.

Port dotnet#2722
Port dotnet#3554
  • Loading branch information
eerhardt committed Jul 26, 2016
1 parent 428951f commit 66eb0da
Show file tree
Hide file tree
Showing 19 changed files with 150 additions and 73 deletions.
4 changes: 4 additions & 0 deletions TestAssets/LockFiles/ExportFiles/valid/project.lock.json
Expand Up @@ -57,5 +57,9 @@
"ClassLibrary2",
"ClassLibrary3"
]
},
"packageFolders": {
"/foo/packages": {},
"/foo/packages2": {}
}
}
Expand Up @@ -55,7 +55,7 @@ public string GetLockFilePath(string packageId, NuGetVersion version, NuGetFrame

return Path.Combine(
GetBaseToolPath(packageId),
version.ToNormalizedString(),
version.ToNormalizedString().ToLowerInvariant(),
framework.GetShortFolderName(),
"project.lock.json");
}
Expand All @@ -65,7 +65,7 @@ private string GetBaseToolPath(string packageId)
return Path.Combine(
_packagesDirectory,
".tools",
packageId);
packageId.ToLowerInvariant());
}

private IEnumerable<NuGetVersion> GetAvailableToolVersions(string packageId)
Expand Down
16 changes: 12 additions & 4 deletions src/Microsoft.DotNet.Compiler.Common/Executable.cs
Expand Up @@ -67,7 +67,7 @@ private void VerifyCoreClrPresenceInPackageGraph()
.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.");
}
Expand All @@ -94,7 +94,7 @@ private void MakeCompilationOutputRunnableForFullFramework()
}

private void MakeCompilationOutputRunnableForCoreCLR(bool skipRuntimeConfig)
{
{
WriteDepsFileAndCopyProjectDependencies(_exporter, skipRuntimeConfig);

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

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)
Expand Down
4 changes: 2 additions & 2 deletions src/Microsoft.DotNet.Configurer/NuGetCacheSentinel.cs
Expand Up @@ -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
{
Expand All @@ -23,7 +23,7 @@ private string NuGetCachePath
{
if (string.IsNullOrEmpty(_nugetCachePath))
{
_nugetCachePath = PackageDependencyProvider.ResolvePackagesPath(null, null);
_nugetCachePath = NuGetPathContext.Create(new NullSettings()).UserPackageFolder;
}

return _nugetCachePath;
Expand Down
1 change: 1 addition & 0 deletions src/Microsoft.DotNet.ProjectModel/Graph/LockFile.cs
Expand Up @@ -20,6 +20,7 @@ public class LockFile
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)
{
Expand Down
10 changes: 10 additions & 0 deletions src/Microsoft.DotNet.ProjectModel/Graph/LockFilePackageFolder.cs
@@ -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; }
}
}
15 changes: 15 additions & 0 deletions src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs
Expand Up @@ -117,6 +117,7 @@ private LockFile ReadLockFile(string lockFilePath, JObject cursor)
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;
}
Expand Down Expand Up @@ -194,6 +195,20 @@ private LockFileTarget ReadTarget(string property, JToken json)
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;
Expand Down
30 changes: 26 additions & 4 deletions src/Microsoft.DotNet.ProjectModel/ProjectContextBuilder.cs
Expand Up @@ -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
Expand Down Expand Up @@ -210,7 +210,6 @@ public ProjectContext Build()
}

RootDirectory = globalSettings?.DirectoryPath ?? RootDirectory;
PackagesDirectory = PackagesDirectory ?? PackageDependencyProvider.ResolvePackagesPath(RootDirectory, globalSettings);

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

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;

Expand Down Expand Up @@ -271,7 +281,7 @@ public ProjectContext Build()
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);

Expand Down Expand Up @@ -377,6 +387,18 @@ public ProjectContext Build()
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
Expand Down
Expand Up @@ -8,19 +8,24 @@
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using Microsoft.DotNet.ProjectModel.Graph;
using NuGet.Common;
using NuGet.Frameworks;
using NuGet.Packaging;

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;
}

Expand All @@ -40,8 +45,8 @@ public PackageDescription GetDescription(NuGetFramework targetFramework, LockFil
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)
{
Expand Down Expand Up @@ -155,35 +160,5 @@ public static bool IsPlaceholderFile(string path)
{
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");
}
}
}
1 change: 1 addition & 0 deletions src/Microsoft.DotNet.ProjectModel/project.json
Expand Up @@ -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"
Expand Down
Expand Up @@ -53,7 +53,8 @@ public bool TryResolveAssemblyPaths(CompilationLibrary library, List<string> ass
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))
Expand Down
Expand Up @@ -12,7 +12,11 @@ internal static class ResolverUtils
{
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;
Expand Down
3 changes: 2 additions & 1 deletion src/dotnet-compile-fsc/Program.cs
Expand Up @@ -13,6 +13,7 @@
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.ProjectModel;
using Microsoft.DotNet.ProjectModel.Resolution;
using NuGet.Configuration;

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

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);
Expand Down
15 changes: 9 additions & 6 deletions src/dotnet/commands/dotnet-run/RunCommand.cs
Expand Up @@ -145,13 +145,16 @@ private int RunExecutable()
}

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
Expand Down
11 changes: 11 additions & 0 deletions test/Microsoft.DotNet.ProjectModel.Tests/LockFilePatchingTests.cs
Expand Up @@ -120,6 +120,17 @@ public void TestMissmatchingFileVersionsUnderDesignTime()
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;
Expand Down

0 comments on commit 66eb0da

Please sign in to comment.