diff --git a/build_projects/dotnet-cli-build/project.json b/build_projects/dotnet-cli-build/project.json index 3397dfc23d..34436adfb4 100644 --- a/build_projects/dotnet-cli-build/project.json +++ b/build_projects/dotnet-cli-build/project.json @@ -13,7 +13,7 @@ "System.Runtime.Serialization.Primitives": "4.1.1-rc3-24206-00", "System.Xml.XmlSerializer": "4.0.11-rc3-24206-00", "WindowsAzure.Storage": "6.2.2-preview", - "NuGet.CommandLine.XPlat": "3.5.0-rc-1285", + "NuGet.CommandLine.XPlat": "3.5.0-rc-1298", "Microsoft.DotNet.Cli.Build.Framework": { "target": "project" }, diff --git a/build_projects/update-dependencies/project.json b/build_projects/update-dependencies/project.json index 1f99d0e350..13e17cc6e7 100644 --- a/build_projects/update-dependencies/project.json +++ b/build_projects/update-dependencies/project.json @@ -12,7 +12,7 @@ "Microsoft.DotNet.Cli.Build.Framework": { "target": "project" }, - "NuGet.Versioning": "3.5.0-rc-1285", + "NuGet.Versioning": "3.5.0-rc-1298", "Newtonsoft.Json": "7.0.1", "Octokit": "0.18.0", "Microsoft.Net.Http": "2.2.29" diff --git a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/ToolPathCalculator.cs b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/ToolPathCalculator.cs index dcb0f15e37..8ac6ecd389 100644 --- a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/ToolPathCalculator.cs +++ b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/ToolPathCalculator.cs @@ -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"); } @@ -65,7 +65,7 @@ private string GetBaseToolPath(string packageId) return Path.Combine( _packagesDirectory, ".tools", - packageId); + packageId.ToLowerInvariant()); } private IEnumerable GetAvailableToolVersions(string packageId) diff --git a/src/Microsoft.DotNet.Cli.Utils/project.json b/src/Microsoft.DotNet.Cli.Utils/project.json index 8fae6e53a0..9808ccff5e 100644 --- a/src/Microsoft.DotNet.Cli.Utils/project.json +++ b/src/Microsoft.DotNet.Cli.Utils/project.json @@ -8,10 +8,10 @@ "Microsoft.DotNet.ProjectModel": { "target": "project" }, - "NuGet.Versioning": "3.5.0-rc-1285", - "NuGet.Packaging": "3.5.0-rc-1285", - "NuGet.Frameworks": "3.5.0-rc-1285", - "NuGet.ProjectModel": "3.5.0-rc-1285" + "NuGet.Versioning": "3.5.0-rc-1298", + "NuGet.Packaging": "3.5.0-rc-1298", + "NuGet.Frameworks": "3.5.0-rc-1298", + "NuGet.ProjectModel": "3.5.0-rc-1298" }, "frameworks": { "net451": { diff --git a/src/Microsoft.DotNet.ProjectModel/Graph/LockFilePackageLibrary.cs b/src/Microsoft.DotNet.ProjectModel/Graph/LockFilePackageLibrary.cs index f8c2d29865..3713dcb358 100644 --- a/src/Microsoft.DotNet.ProjectModel/Graph/LockFilePackageLibrary.cs +++ b/src/Microsoft.DotNet.ProjectModel/Graph/LockFilePackageLibrary.cs @@ -16,6 +16,8 @@ public class LockFilePackageLibrary public string Sha512 { get; set; } + public string Path { get; set; } + public IList Files { get; set; } = new List(); } } diff --git a/src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs b/src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs index 9d7a070e3f..b9a50a7ed5 100644 --- a/src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs +++ b/src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs @@ -151,6 +151,7 @@ private void ReadLibrary(JObject json, LockFile lockFile) Version = version, IsServiceable = ReadBool(value, "serviceable", defaultValue: false), Sha512 = ReadString(value["sha512"]), + Path = value.Value("path"), Files = ReadPathArray(value["files"], ReadString) }); } diff --git a/src/Microsoft.DotNet.ProjectModel/Resolution/PackageDependencyProvider.cs b/src/Microsoft.DotNet.ProjectModel/Resolution/PackageDependencyProvider.cs index df0bdf64f2..521ff8a043 100644 --- a/src/Microsoft.DotNet.ProjectModel/Resolution/PackageDependencyProvider.cs +++ b/src/Microsoft.DotNet.ProjectModel/Resolution/PackageDependencyProvider.cs @@ -15,11 +15,13 @@ namespace Microsoft.DotNet.ProjectModel.Resolution { public class PackageDependencyProvider { + private readonly string _packagesPath; private readonly VersionFolderPathResolver _packagePathResolver; private readonly FrameworkReferenceResolver _frameworkReferenceResolver; public PackageDependencyProvider(string packagesPath, FrameworkReferenceResolver frameworkReferenceResolver) { + _packagesPath = packagesPath; _packagePathResolver = new VersionFolderPathResolver(packagesPath); _frameworkReferenceResolver = frameworkReferenceResolver; } @@ -40,7 +42,16 @@ public PackageDescription GetDescription(NuGetFramework targetFramework, LockFil var dependencies = new List(targetLibrary.Dependencies.Count + targetLibrary.FrameworkAssemblies.Count); PopulateDependencies(dependencies, targetLibrary, targetFramework); - var path = _packagePathResolver.GetInstallPath(package.Name, package.Version); + string path; + if (package.Path != null) + { + path = Path.Combine(_packagesPath, package.Path); + } + else + { + path = _packagePathResolver.GetInstallPath(package.Name, package.Version); + } + var exists = Directory.Exists(path); if (exists) diff --git a/src/Microsoft.DotNet.ProjectModel/project.json b/src/Microsoft.DotNet.ProjectModel/project.json index ef66371b5a..ad6cd6bf49 100644 --- a/src/Microsoft.DotNet.ProjectModel/project.json +++ b/src/Microsoft.DotNet.ProjectModel/project.json @@ -9,8 +9,8 @@ "target": "project" }, "Newtonsoft.Json": "7.0.1", - "NuGet.Packaging": "3.5.0-rc-1285", - "NuGet.RuntimeModel": "3.5.0-rc-1285", + "NuGet.Packaging": "3.5.0-rc-1298", + "NuGet.RuntimeModel": "3.5.0-rc-1298", "System.Reflection.Metadata": "1.3.0-rc3-24206-00" }, "frameworks": { diff --git a/src/Microsoft.Extensions.DependencyModel/Resolution/PackageCacheCompilationAssemblyResolver.cs b/src/Microsoft.Extensions.DependencyModel/Resolution/PackageCacheCompilationAssemblyResolver.cs index 156ea0622b..7497f0e087 100644 --- a/src/Microsoft.Extensions.DependencyModel/Resolution/PackageCacheCompilationAssemblyResolver.cs +++ b/src/Microsoft.Extensions.DependencyModel/Resolution/PackageCacheCompilationAssemblyResolver.cs @@ -53,7 +53,8 @@ public bool TryResolveAssemblyPaths(CompilationLibrary library, List 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)) diff --git a/src/Microsoft.Extensions.DependencyModel/Resolution/ResolverUtils.cs b/src/Microsoft.Extensions.DependencyModel/Resolution/ResolverUtils.cs index b9b93d2765..e105ad8c59 100644 --- a/src/Microsoft.Extensions.DependencyModel/Resolution/ResolverUtils.cs +++ b/src/Microsoft.Extensions.DependencyModel/Resolution/ResolverUtils.cs @@ -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; diff --git a/src/dotnet/project.json b/src/dotnet/project.json index d182d91076..6cc1a91fdd 100644 --- a/src/dotnet/project.json +++ b/src/dotnet/project.json @@ -21,10 +21,10 @@ }, "dependencies": { "NuGet.Commands": { - "version": "3.5.0-rc-1285", + "version": "3.5.0-rc-1298", "exclude": "compile" }, - "NuGet.CommandLine.XPlat": "3.5.0-rc-1285", + "NuGet.CommandLine.XPlat": "3.5.0-rc-1298", "Newtonsoft.Json": "7.0.1", "System.Text.Encoding.CodePages": "4.0.1-rc3-24206-00", "System.Diagnostics.FileVersionInfo": "4.0.0-rc3-24206-00", diff --git a/test/Microsoft.DotNet.Cli.Utils.Tests/GivenAProjectDependenciesCommandFactory.cs b/test/Microsoft.DotNet.Cli.Utils.Tests/GivenAProjectDependenciesCommandFactory.cs index 2df9faf854..e89dc34d8d 100644 --- a/test/Microsoft.DotNet.Cli.Utils.Tests/GivenAProjectDependenciesCommandFactory.cs +++ b/test/Microsoft.DotNet.Cli.Utils.Tests/GivenAProjectDependenciesCommandFactory.cs @@ -167,7 +167,7 @@ public void It_resolves_tools_whose_package_name_is_different_than_dll_name() var command = factory.Create("dotnet-tool-with-output-name", null); command.CommandArgs.Should().Contain( - Path.Combine("ToolWithOutputName", "1.0.0", "lib", "netcoreapp1.0", "dotnet-tool-with-output-name.dll")); + Path.Combine("toolwithoutputname", "1.0.0", "lib", "netcoreapp1.0", "dotnet-tool-with-output-name.dll")); } } } diff --git a/test/Microsoft.DotNet.Cli.Utils.Tests/project.json b/test/Microsoft.DotNet.Cli.Utils.Tests/project.json index 04cb5e7972..8f427935e5 100644 --- a/test/Microsoft.DotNet.Cli.Utils.Tests/project.json +++ b/test/Microsoft.DotNet.Cli.Utils.Tests/project.json @@ -20,10 +20,10 @@ }, "System.Diagnostics.TraceSource": "4.0.0-rc3-24206-00", "System.Runtime.Serialization.Primitives": "4.1.1-rc3-24206-00", - "NuGet.Versioning": "3.5.0-rc-1285", - "NuGet.Packaging": "3.5.0-rc-1285", - "NuGet.Frameworks": "3.5.0-rc-1285", - "NuGet.ProjectModel": "3.5.0-rc-1285", + "NuGet.Versioning": "3.5.0-rc-1298", + "NuGet.Packaging": "3.5.0-rc-1298", + "NuGet.Frameworks": "3.5.0-rc-1298", + "NuGet.ProjectModel": "3.5.0-rc-1298", "Microsoft.DotNet.ProjectModel": { "target": "project" }, diff --git a/test/Microsoft.DotNet.ProjectModel.Tests/LockFileReaderTests.cs b/test/Microsoft.DotNet.ProjectModel.Tests/LockFileReaderTests.cs new file mode 100644 index 0000000000..edb3701c49 --- /dev/null +++ b/test/Microsoft.DotNet.ProjectModel.Tests/LockFileReaderTests.cs @@ -0,0 +1,54 @@ +// 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. + +using System.IO; +using System.Text; +using FluentAssertions; +using Microsoft.DotNet.ProjectModel.Graph; +using Xunit; +using NuGet.Versioning; + +namespace Microsoft.DotNet.ProjectModel.Tests +{ + public class LockFileReaderTests + { + [Theory] + [InlineData("", null)] + [InlineData(@"""path"": null,", null)] + [InlineData(@"""path"": ""foo/1.0.0"",", "foo/1.0.0")] + public void SupportsTheOptionalPathPropertyOfALibraryPackage(string pathProperty, string expected) + { + // Arrange + var reader = new LockFileReader(); + var lockFileJson = @" + { + ""libraries"": { + ""Foo/1.0.0"": { + ""sha512"": ""something"", + " + pathProperty + @" + ""type"": ""package"", + ""files"": [ + ""lib/netstandard1.0/Foo.dll"" + ] + } + } + } + "; + var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(lockFileJson)); + + // Act + var lockFile = reader.ReadLockFile("project.lock.json", memoryStream, false); + + // Assert + lockFile.PackageLibraries.Should().HaveCount(1); + var library = lockFile.PackageLibraries[0]; + library.Path.Should().Be(expected); + + library.Name.Should().Be("Foo"); + library.Version.Should().Be(new NuGetVersion("1.0.0")); + library.Sha512.Should().Be("something"); + library.Files.Should().HaveCount(1); + library.Files[0].Should().Be(Path.Combine("lib", "netstandard1.0", "Foo.dll")); + } + } +} diff --git a/test/Microsoft.Extensions.DependencyModel.Tests/PackageCacheResolverTest.cs b/test/Microsoft.Extensions.DependencyModel.Tests/PackageCacheResolverTest.cs index 7ea550b980..c76b806a0e 100644 --- a/test/Microsoft.Extensions.DependencyModel.Tests/PackageCacheResolverTest.cs +++ b/test/Microsoft.Extensions.DependencyModel.Tests/PackageCacheResolverTest.cs @@ -55,10 +55,15 @@ public void FailsOnInvalidHash(string hash) [Fact] public void ChecksHashFile() { - var packagePath = Path.Combine(CachePath, F.DefaultPackageName, F.DefaultVersion); + var packagePath = Path.Combine( + CachePath, + F.DefaultPackageName.ToLowerInvariant(), + F.DefaultVersion.ToLowerInvariant()); var fileSystem = FileSystemMockBuilder.Create() .AddFile( - Path.Combine(packagePath, $"{F.DefaultPackageName}.{F.DefaultVersion}.nupkg.{F.DefaultHashAlgoritm}"), + Path.Combine( + packagePath, + $"{F.DefaultPackageName.ToLowerInvariant()}.{F.DefaultVersion.ToLowerInvariant()}.nupkg.{F.DefaultHashAlgoritm}"), "WRONGHASH" ) .AddFiles(packagePath, F.DefaultAssemblies) @@ -74,10 +79,15 @@ public void ChecksHashFile() [Fact] public void ResolvesAllAssemblies() { - var packagePath = Path.Combine(CachePath, F.DefaultPackageName, F.DefaultVersion); + var packagePath = Path.Combine( + CachePath, + F.DefaultPackageName.ToLowerInvariant(), + F.DefaultVersion.ToLowerInvariant()); var fileSystem = FileSystemMockBuilder.Create() .AddFile( - Path.Combine(packagePath, $"{F.DefaultPackageName}.{F.DefaultVersion}.nupkg.{F.DefaultHashAlgoritm}"), + Path.Combine( + packagePath, + $"{F.DefaultPackageName.ToLowerInvariant()}.{F.DefaultVersion.ToLowerInvariant()}.nupkg.{F.DefaultHashAlgoritm}"), F.DefaultHashValue ) .AddFiles(packagePath, F.TwoAssemblies) @@ -98,10 +108,15 @@ public void ResolvesAllAssemblies() [Fact] public void FailsWhenOneOfAssembliesNotFound() { - var packagePath = Path.Combine(CachePath, F.DefaultPackageName, F.DefaultVersion); + var packagePath = Path.Combine( + CachePath, + F.DefaultPackageName.ToLowerInvariant(), + F.DefaultVersion.ToLowerInvariant()); var fileSystem = FileSystemMockBuilder.Create() .AddFile( - Path.Combine(packagePath, $"{F.DefaultPackageName}.{F.DefaultVersion}.nupkg.{F.DefaultHashAlgoritm}"), + Path.Combine( + packagePath, + $"{F.DefaultPackageName.ToLowerInvariant()}.{F.DefaultVersion.ToLowerInvariant()}.nupkg.{F.DefaultHashAlgoritm}"), F.DefaultHashValue ) .AddFiles(packagePath, F.DefaultAssemblyPath) diff --git a/test/Microsoft.Extensions.DependencyModel.Tests/PackageResolverTest.cs b/test/Microsoft.Extensions.DependencyModel.Tests/PackageResolverTest.cs index c6727db7fa..1420865a3a 100644 --- a/test/Microsoft.Extensions.DependencyModel.Tests/PackageResolverTest.cs +++ b/test/Microsoft.Extensions.DependencyModel.Tests/PackageResolverTest.cs @@ -17,7 +17,7 @@ public class PackageResolverTest 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 @@ public void SholdUseEnvironmentVariableToGetDefaultLocation() [Fact] - public void SholdUseNugetUnderUserProfileOnWindows() + public void ShouldUseNuGetUnderUserProfileOnWindows() { var environment = EnvironmentMockBuilder.Create() .AddVariable("USERPROFILE", "User Profile") @@ -40,7 +40,7 @@ public void SholdUseNugetUnderUserProfileOnWindows() } [Fact] - public void SholdUseNugetUnderHomeOnNonWindows() + public void ShouldUseNuGetUnderHomeOnNonWindows() { var environment = EnvironmentMockBuilder.Create() .AddVariable("HOME", "User Home") @@ -53,7 +53,7 @@ public void SholdUseNugetUnderHomeOnNonWindows() [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 @@ public void ResolvesAllAssemblies() [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,10 @@ public void FailsWhenOneOfAssembliesNotFound() .Contain(F.SecondAssemblyPath) .And.Contain(library.Name); } + + private static string GetPackagesPath(string id, string version) + { + return Path.Combine(PackagesPath, id.ToLowerInvariant(), version.ToLowerInvariant()); + } } } diff --git a/test/dotnet-build.Tests/BuildMissingPackagesTests.cs b/test/dotnet-build.Tests/BuildMissingPackagesTests.cs new file mode 100644 index 0000000000..771d45af3d --- /dev/null +++ b/test/dotnet-build.Tests/BuildMissingPackagesTests.cs @@ -0,0 +1,51 @@ +// 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. + +using System.IO; +using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.TestFramework; +using Microsoft.DotNet.Tools.Test.Utilities; +using Xunit; + +namespace Microsoft.DotNet.Tools.Builder.Tests +{ + public class BuildMissingPackagesTests : TestBase + { + [Fact] + public void MissingPackageDuringBuildCauseFailure() + { + // Arrange + TestInstance instance = TestAssetsManager.CreateTestInstance("PortableTests"); + var testProject = Path.Combine(instance.TestRoot, "StandaloneApp", "project.json"); + var workingDirectory = Path.GetDirectoryName(testProject); + var testNuGetCache = Path.Combine(instance.Path, "packages"); + var oldLocation = Path.Combine(testNuGetCache, "system.console"); + var newLocation = Path.Combine(testNuGetCache, "system.console.different"); + + var restoreCommand = new RestoreCommand(); + + restoreCommand.WorkingDirectory = workingDirectory; + restoreCommand.Environment["NUGET_PACKAGES"] = testNuGetCache; + restoreCommand.Execute(); + + // Delete all System.Console packages. + foreach (var directory in Directory.EnumerateDirectories(testNuGetCache, "*system.console*")) + { + Directory.Delete(directory, true); + } + + var buildCommand = new BuildCommand(testProject); + + buildCommand.WorkingDirectory = workingDirectory; + buildCommand.Environment["NUGET_PACKAGES"] = testNuGetCache; + + // Act & Assert + buildCommand + .ExecuteWithCapturedOutput() + .Should() + .Fail() + .And + .HaveStdErrMatching("The dependency System.Console >= (?.+?) could not be resolved."); + } + } +}