Refactor DependencyModel, make it ready for tests

This commit is contained in:
Pavel Krymets 2016-02-10 20:13:56 -08:00
parent 9c7ec89392
commit 39e1e26f0e
39 changed files with 1739 additions and 346 deletions

View file

@ -4,6 +4,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{ED2FE3E2-F7E7-4389-8231-B65123F2076F}"
ProjectSection(SolutionItems) = preProject
src\Microsoft.Extensions.EnvironmentAbstractions\project.json = src\Microsoft.Extensions.EnvironmentAbstractions\project.json
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{5A29E8E3-A0FC-4C57-81DD-297B56D1A119}"
ProjectSection(SolutionItems) = preProject
@ -50,6 +53,7 @@ EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "dotnet-projectmodel-server.Tests", "test\dotnet-projectmodel-server.Tests\dotnet-projectmodel-server.Tests.xproj", "{11C77123-E4DA-499F-8900-80C88C2C69F2}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Files", "src\Microsoft.DotNet.Files\Microsoft.DotNet.Files.xproj", "{D521DD9F-0614-4929-93B4-D8FA5682C174}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{88278B81-7649-45DC-8A6A-D3A645C5AFC3}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "dotnet-cli-build", "scripts\dotnet-cli-build\dotnet-cli-build.xproj", "{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}"
@ -68,6 +72,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestLibrary", "TestAssets\T
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestProjectToProjectDependencies", "TestAssets\TestProjects\TestProjectToProjectDependencies\TestProjectToProjectDependencies.xproj", "{947DD232-8D9B-4B78-9C6A-94F807D22222}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.InternalAbstractions", "src\Microsoft.DotNet.InternalAbstractions\Microsoft.DotNet.InternalAbstractions.xproj", "{BD4F0750-4E81-4AD2-90B5-E470881792C3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -352,6 +358,38 @@ Global
{D521DD9F-0614-4929-93B4-D8FA5682C174}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{D521DD9F-0614-4929-93B4-D8FA5682C174}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{D521DD9F-0614-4929-93B4-D8FA5682C174}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.Debug|x64.ActiveCfg = Debug|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.Debug|x64.Build.0 = Debug|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.Release|Any CPU.Build.0 = Release|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.Release|x64.ActiveCfg = Release|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.Release|x64.Build.0 = Release|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.Debug|x64.ActiveCfg = Debug|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.Debug|x64.Build.0 = Debug|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.Release|Any CPU.Build.0 = Release|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.Release|x64.ActiveCfg = Release|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.Release|x64.Build.0 = Release|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{920B71D8-62DA-4F5E-8A26-926C113F1D97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{920B71D8-62DA-4F5E-8A26-926C113F1D97}.Debug|Any CPU.Build.0 = Debug|Any CPU
{920B71D8-62DA-4F5E-8A26-926C113F1D97}.Debug|x64.ActiveCfg = Debug|Any CPU
@ -448,70 +486,22 @@ Global
{947DD232-8D9B-4B78-9C6A-94F807D22222}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{947DD232-8D9B-4B78-9C6A-94F807D22222}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{947DD232-8D9B-4B78-9C6A-94F807D22222}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{09C52F96-EFDD-4448-95EC-6D362DD60BAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{09C52F96-EFDD-4448-95EC-6D362DD60BAA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{09C52F96-EFDD-4448-95EC-6D362DD60BAA}.Debug|x64.ActiveCfg = Debug|Any CPU
{09C52F96-EFDD-4448-95EC-6D362DD60BAA}.Debug|x64.Build.0 = Debug|Any CPU
{09C52F96-EFDD-4448-95EC-6D362DD60BAA}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
{09C52F96-EFDD-4448-95EC-6D362DD60BAA}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
{09C52F96-EFDD-4448-95EC-6D362DD60BAA}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{09C52F96-EFDD-4448-95EC-6D362DD60BAA}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{09C52F96-EFDD-4448-95EC-6D362DD60BAA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{09C52F96-EFDD-4448-95EC-6D362DD60BAA}.Release|Any CPU.Build.0 = Release|Any CPU
{09C52F96-EFDD-4448-95EC-6D362DD60BAA}.Release|x64.ActiveCfg = Release|Any CPU
{09C52F96-EFDD-4448-95EC-6D362DD60BAA}.Release|x64.Build.0 = Release|Any CPU
{09C52F96-EFDD-4448-95EC-6D362DD60BAA}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
{09C52F96-EFDD-4448-95EC-6D362DD60BAA}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{09C52F96-EFDD-4448-95EC-6D362DD60BAA}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{09C52F96-EFDD-4448-95EC-6D362DD60BAA}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{44E7D1AC-DCF1-4A18-9C22-F09E6BB302B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{44E7D1AC-DCF1-4A18-9C22-F09E6BB302B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{44E7D1AC-DCF1-4A18-9C22-F09E6BB302B5}.Debug|x64.ActiveCfg = Debug|Any CPU
{44E7D1AC-DCF1-4A18-9C22-F09E6BB302B5}.Debug|x64.Build.0 = Debug|Any CPU
{44E7D1AC-DCF1-4A18-9C22-F09E6BB302B5}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
{44E7D1AC-DCF1-4A18-9C22-F09E6BB302B5}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
{44E7D1AC-DCF1-4A18-9C22-F09E6BB302B5}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{44E7D1AC-DCF1-4A18-9C22-F09E6BB302B5}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{44E7D1AC-DCF1-4A18-9C22-F09E6BB302B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44E7D1AC-DCF1-4A18-9C22-F09E6BB302B5}.Release|Any CPU.Build.0 = Release|Any CPU
{44E7D1AC-DCF1-4A18-9C22-F09E6BB302B5}.Release|x64.ActiveCfg = Release|Any CPU
{44E7D1AC-DCF1-4A18-9C22-F09E6BB302B5}.Release|x64.Build.0 = Release|Any CPU
{44E7D1AC-DCF1-4A18-9C22-F09E6BB302B5}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
{44E7D1AC-DCF1-4A18-9C22-F09E6BB302B5}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{44E7D1AC-DCF1-4A18-9C22-F09E6BB302B5}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{44E7D1AC-DCF1-4A18-9C22-F09E6BB302B5}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.Debug|x64.ActiveCfg = Debug|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.Debug|x64.Build.0 = Debug|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.Release|Any CPU.Build.0 = Release|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.Release|x64.ActiveCfg = Release|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.Release|x64.Build.0 = Release|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.Debug|x64.ActiveCfg = Debug|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.Debug|x64.Build.0 = Debug|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.Release|Any CPU.Build.0 = Release|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.Release|x64.ActiveCfg = Release|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.Release|x64.Build.0 = Release|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{BD4F0750-4E81-4AD2-90B5-E470881792C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BD4F0750-4E81-4AD2-90B5-E470881792C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BD4F0750-4E81-4AD2-90B5-E470881792C3}.Debug|x64.ActiveCfg = Debug|Any CPU
{BD4F0750-4E81-4AD2-90B5-E470881792C3}.Debug|x64.Build.0 = Debug|Any CPU
{BD4F0750-4E81-4AD2-90B5-E470881792C3}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
{BD4F0750-4E81-4AD2-90B5-E470881792C3}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
{BD4F0750-4E81-4AD2-90B5-E470881792C3}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{BD4F0750-4E81-4AD2-90B5-E470881792C3}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{BD4F0750-4E81-4AD2-90B5-E470881792C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BD4F0750-4E81-4AD2-90B5-E470881792C3}.Release|Any CPU.Build.0 = Release|Any CPU
{BD4F0750-4E81-4AD2-90B5-E470881792C3}.Release|x64.ActiveCfg = Release|Any CPU
{BD4F0750-4E81-4AD2-90B5-E470881792C3}.Release|x64.Build.0 = Release|Any CPU
{BD4F0750-4E81-4AD2-90B5-E470881792C3}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
{BD4F0750-4E81-4AD2-90B5-E470881792C3}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{BD4F0750-4E81-4AD2-90B5-E470881792C3}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{BD4F0750-4E81-4AD2-90B5-E470881792C3}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -535,15 +525,14 @@ Global
{386D412C-003C-47B1-8258-0E35865CB7C4} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
{11C77123-E4DA-499F-8900-80C88C2C69F2} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
{D521DD9F-0614-4929-93B4-D8FA5682C174} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5} = {88278B81-7649-45DC-8A6A-D3A645C5AFC3}
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D} = {88278B81-7649-45DC-8A6A-D3A645C5AFC3}
{920B71D8-62DA-4F5E-8A26-926C113F1D97} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
{58808BBC-371E-47D6-A3D0-4902145EDA4E} = {713CBFBB-5392-438D-B766-A9A585EF1BB8}
{DA8E0E9E-A6D6-4583-864C-8F40465E3A48} = {713CBFBB-5392-438D-B766-A9A585EF1BB8}
{0138CB8F-4AA9-4029-A21E-C07C30F425BA} = {713CBFBB-5392-438D-B766-A9A585EF1BB8}
{947DD232-8D9B-4B78-9C6A-94F807D2DD58} = {713CBFBB-5392-438D-B766-A9A585EF1BB8}
{947DD232-8D9B-4B78-9C6A-94F807D22222} = {713CBFBB-5392-438D-B766-A9A585EF1BB8}
{09C52F96-EFDD-4448-95EC-6D362DD60BAA} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
{44E7D1AC-DCF1-4A18-9C22-F09E6BB302B5} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5} = {88278B81-7649-45DC-8A6A-D3A645C5AFC3}
{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D} = {88278B81-7649-45DC-8A6A-D3A645C5AFC3}
{BD4F0750-4E81-4AD2-90B5-E470881792C3} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
EndGlobalSection
EndGlobal

View file

@ -28,6 +28,7 @@ namespace Microsoft.DotNet.Cli.Build
"dotnet-build.Tests",
"Microsoft.DotNet.Cli.Utils.Tests",
"Microsoft.DotNet.Compiler.Common.Tests",
"Microsoft.Extensions.DependencyModel.Tests",
"ArgumentForwardingTests"
};

View file

@ -6,6 +6,7 @@ $ProjectsToPack = @(
"Microsoft.DotNet.ProjectModel",
"Microsoft.DotNet.ProjectModel.Loader",
"Microsoft.DotNet.ProjectModel.Workspaces",
"Microsoft.DotNet.InternalAbstractions",
"Microsoft.Extensions.DependencyModel",
"Microsoft.Extensions.Testing.Abstractions"
)

View file

@ -0,0 +1,15 @@
// 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;
namespace Microsoft.Extensions.EnvironmentAbstractions
{
internal class DirectoryWrapper: IDirectory
{
public bool Exists(string path)
{
return Directory.Exists(path);
}
}
}

View file

@ -0,0 +1,17 @@
// 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;
namespace Microsoft.Extensions.EnvironmentAbstractions
{
internal class EnvironmentWrapper : IEnvironment
{
public static IEnvironment Default = new EnvironmentWrapper();
public string GetEnvironmentVariable(string name)
{
return Environment.GetEnvironmentVariable(name);
}
}
}

View file

@ -0,0 +1,14 @@
// 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.Extensions.EnvironmentAbstractions
{
internal class FileSystemWrapper : IFileSystem
{
public static IFileSystem Default { get; } = new FileSystemWrapper();
public IFile File { get; } = new FileWrapper();
public IDirectory Directory { get; } = new DirectoryWrapper();
}
}

View file

@ -0,0 +1,20 @@
// 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;
namespace Microsoft.Extensions.EnvironmentAbstractions
{
internal class FileWrapper: IFile
{
public bool Exists(string path)
{
return File.Exists(path);
}
public string ReadAllText(string path)
{
return File.ReadAllText(path);
}
}
}

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.Extensions.EnvironmentAbstractions
{
internal interface IDirectory
{
bool Exists(string path);
}
}

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.Extensions.EnvironmentAbstractions
{
internal interface IEnvironment
{
string GetEnvironmentVariable(string name);
}
}

View file

@ -0,0 +1,12 @@
// 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.Extensions.EnvironmentAbstractions
{
internal interface IFile
{
bool Exists(string path);
string ReadAllText(string path);
}
}

View file

@ -0,0 +1,11 @@
// 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.Extensions.EnvironmentAbstractions
{
internal interface IFileSystem
{
IFile File { get; }
IDirectory Directory { get; }
}
}

View file

@ -0,0 +1,5 @@
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Microsoft.Extensions.DependencyModel, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.DotNet.Tools.Tests.Utilities, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.Extensions.DependencyModel.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]

View file

@ -0,0 +1,25 @@
{
"description": "Abstractions for making code that uses file system and environment testable.",
"version": "1.0.0-*",
"repository": {
"type": "git",
"url": "git://github.com/dotnet/cli"
},
"compilationOptions": {
"warningsAsErrors": true,
"keyFile": "../../tools/Key.snk"
},
"dependencies": {
"Microsoft.Extensions.PlatformAbstractions": "1.0.0-rc2-16537"
},
"frameworks": {
"net451": { },
"dotnet5.4": {
"dependencies": {
"System.Runtime": "4.0.21-rc2-23811"
}
},
},
"scripts": {
}
}

View file

@ -3,9 +3,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Microsoft.Extensions.PlatformAbstractions;
using Microsoft.Extensions.DependencyModel.Resolution;
namespace Microsoft.Extensions.DependencyModel
{
@ -19,100 +17,22 @@ namespace Microsoft.Extensions.DependencyModel
public IReadOnlyList<string> Assemblies { get; }
public IEnumerable<string> ResolveReferencePaths()
internal static ICompilationAssemblyResolver DefaultResolver { get; } = new CompositeCompilationAssemblyResolver(new ICompilationAssemblyResolver[]
{
var entryAssembly = Assembly.GetEntryAssembly();
new PackageCacheCompilationAssemblyResolver(),
new AppBaseCompilationAssemblyResolver(),
new ReferenceAssemblyPathResolver(),
new PackageCompilationAssemblyResolver()
});
string basePath;
var appBase = PlatformServices.Default.Application.ApplicationBasePath;
var refsDir = Path.Combine(appBase, "refs");
var hasRefs = Directory.Exists(refsDir);
var isProject = string.Equals(LibraryType, "project", StringComparison.OrdinalIgnoreCase);
var isReferenceAssembly = string.Equals(LibraryType, "referenceassembly", StringComparison.OrdinalIgnoreCase);
if (!isProject && PackagePathResolver.TryResolvePackageCachePath(this, out basePath))
{
return ResolveFromPackagePath(basePath);
}
if (hasRefs || isProject)
{
var directories = new List<string>()
{
appBase
};
if (hasRefs)
{
directories.Add(refsDir);
}
return ResolveFromDirectories(directories.ToArray());
}
if (isReferenceAssembly)
{
return ResolveFromReferenceAssemblies();
}
if (PackagePathResolver.TryResolvePackagePath(this, out basePath))
{
return ResolveFromPackagePath(basePath);
}
throw new InvalidOperationException($"Can not find compilation library location for package '{PackageName}'");
}
private IEnumerable<string> ResolveFromPackagePath(string basePath)
public IEnumerable<string> ResolveReferencePaths(CompilationLibrary compilationLibrary)
{
foreach (var assembly in Assemblies)
var assemblies = new List<string>();
if (!DefaultResolver.TryResolveAssemblyPaths(compilationLibrary, assemblies))
{
string fullName;
if (!TryResolveAssemblyFile(basePath, assembly, out fullName))
{
throw new InvalidOperationException($"Can not find assembly file for package {PackageName} at '{fullName}'");
}
yield return fullName;
throw new InvalidOperationException($"Can not find compilation library location for package '{PackageName}'");
}
}
private IEnumerable<string> ResolveFromReferenceAssemblies()
{
foreach (var assembly in Assemblies)
{
string fullName;
if (!ReferenceAssemblyPathResolver.TryResolveReferenceAssembly(assembly, out fullName))
{
throw new InvalidOperationException($"Can not find refernce assembly file for package {PackageName}: '{assembly}'");
}
yield return fullName;
}
}
private IEnumerable<string> ResolveFromDirectories(string[] directories)
{
foreach (var assembly in Assemblies)
{
var assemblyFile = Path.GetFileName(assembly);
foreach (var directory in directories)
{
string fullName;
if (TryResolveAssemblyFile(directory, assemblyFile, out fullName))
{
yield return fullName;
break;
}
var errorMessage = $"Can not find assembly file {assemblyFile} at '{string.Join(",", directories)}'";
throw new InvalidOperationException(errorMessage);
}
}
}
private bool TryResolveAssemblyFile(string basePath, string assemblyPath, out string fullName)
{
fullName = Path.Combine(basePath, assemblyPath);
if (File.Exists(fullName))
{
return true;
}
return false;
return assemblies;
}
}
}

View file

@ -1,84 +0,0 @@
// 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;
using System.IO;
using Microsoft.Extensions.PlatformAbstractions;
namespace Microsoft.Extensions.DependencyModel
{
public class PackagePathResolver
{
private static string _nugetPackages = Environment.GetEnvironmentVariable("NUGET_PACKAGES") ?? GetDefaultPackageDirectory();
private static string _packageCache = Environment.GetEnvironmentVariable("DOTNET_PACKAGES_CACHE");
internal static bool TryResolvePackageCachePath(CompilationLibrary library, out string packagePath)
{
packagePath = null;
if (!string.IsNullOrEmpty(_packageCache))
{
var hashSplitterPos = library.Hash.IndexOf('-');
if (hashSplitterPos <= 0 || hashSplitterPos == library.Hash.Length - 1)
{
throw new InvalidOperationException($"Invalid hash entry '{library.Hash}' for package '{library.PackageName}'");
}
var hashAlgorithm = library.Hash.Substring(0, hashSplitterPos);
var cacheHashPath = Path.Combine(_packageCache, $"{library.PackageName}.{library.Version}.nupkg.{hashAlgorithm}");
if (File.Exists(cacheHashPath) &&
File.ReadAllText(cacheHashPath) == library.Hash.Substring(hashSplitterPos + 1))
{
if (TryResolvePackagePath(library, _nugetPackages, out packagePath))
{
return true;
}
}
}
return false;
}
internal static bool TryResolvePackagePath(CompilationLibrary library, out string packagePath)
{
packagePath = null;
if (!string.IsNullOrEmpty(_nugetPackages) &&
TryResolvePackagePath(library, _nugetPackages, out packagePath))
{
return true;
}
return false;
}
private static string GetDefaultPackageDirectory()
{
string basePath;
if (PlatformServices.Default.Runtime.OperatingSystemPlatform == Platform.Windows)
{
basePath = Environment.GetEnvironmentVariable("USERPROFILE");
}
else
{
basePath = Environment.GetEnvironmentVariable("HOME");
}
if (string.IsNullOrEmpty(basePath))
{
return null;
}
return Path.Combine(basePath, ".nuget", "packages");
}
private static bool TryResolvePackagePath(CompilationLibrary library, string basePath, out string packagePath)
{
packagePath = Path.Combine(basePath, library.PackageName, library.Version);
if (Directory.Exists(packagePath))
{
return true;
}
return false;
}
}
}

View file

@ -0,0 +1,3 @@
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Microsoft.Extensions.DependencyModel.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]

View file

@ -1,100 +0,0 @@
// 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;
using System.IO;
using Microsoft.Extensions.PlatformAbstractions;
namespace Microsoft.Extensions.DependencyModel
{
public class ReferenceAssemblyPathResolver
{
private static readonly Lazy<string> _defaultReferenceAssembliesPath = new Lazy<string>(GetDefaultReferenceAssembliesPath);
private static readonly Lazy<string[]> _fallbackSearchPaths = new Lazy<string[]>(GetFallbackSearchPaths);
private static string[] GetFallbackSearchPaths()
{
if (PlatformServices.Default.Runtime.OperatingSystemPlatform != Platform.Windows)
{
return new string[0];
}
var net20Dir = Path.Combine(Environment.GetEnvironmentVariable("WINDIR"), "Microsoft.NET", "Framework", "v2.0.50727");
if (!Directory.Exists(net20Dir))
{
return new string[0];
}
return new[] { net20Dir };
}
public static string GetDefaultReferenceAssembliesPath()
{
// Allow setting the reference assemblies path via an environment variable
var referenceAssembliesPath = Environment.GetEnvironmentVariable("DOTNET_REFERENCE_ASSEMBLIES_PATH");
if (!string.IsNullOrEmpty(referenceAssembliesPath))
{
return referenceAssembliesPath;
}
if (PlatformServices.Default.Runtime.OperatingSystemPlatform != Platform.Windows)
{
// There is no reference assemblies path outside of windows
// The environment variable can be used to specify one
return null;
}
// References assemblies are in %ProgramFiles(x86)% on
// 64 bit machines
var programFiles = Environment.GetEnvironmentVariable("ProgramFiles(x86)");
if (string.IsNullOrEmpty(programFiles))
{
// On 32 bit machines they are in %ProgramFiles%
programFiles = Environment.GetEnvironmentVariable("ProgramFiles");
}
if (string.IsNullOrEmpty(programFiles))
{
// Reference assemblies aren't installed
return null;
}
return Path.Combine(
programFiles,
"Reference Assemblies", "Microsoft", "Framework");
}
public static bool TryResolveReferenceAssembly(string path, out string fullPath)
{
fullPath = null;
var refereneAssembliesPath = _defaultReferenceAssembliesPath.Value;
if (refereneAssembliesPath == null)
{
return false;
}
var relativeToReferenceAssemblies = Path.Combine(refereneAssembliesPath, path);
if (File.Exists(relativeToReferenceAssemblies))
{
fullPath = relativeToReferenceAssemblies;
return true;
}
var name = Path.GetFileName(path);
foreach (var fallbackPath in _fallbackSearchPaths.Value)
{
var fallbackFile = Path.Combine(fallbackPath, name);
if (File.Exists(fallbackFile))
{
fullPath = fallbackFile;
return true;
}
}
return false;
}
}
}

View file

@ -0,0 +1,85 @@
// 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;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Microsoft.Extensions.PlatformAbstractions;
using Microsoft.Extensions.EnvironmentAbstractions;
namespace Microsoft.Extensions.DependencyModel.Resolution
{
public class AppBaseCompilationAssemblyResolver : ICompilationAssemblyResolver
{
private readonly IFileSystem _fileSystem;
private readonly string _basePath;
public AppBaseCompilationAssemblyResolver()
: this(FileSystemWrapper.Default)
{
}
public AppBaseCompilationAssemblyResolver(string basePath) : this(FileSystemWrapper.Default, basePath)
{
}
internal AppBaseCompilationAssemblyResolver(IFileSystem fileSystem)
: this(fileSystem, PlatformServices.Default.Application.ApplicationBasePath)
{
}
internal AppBaseCompilationAssemblyResolver(IFileSystem fileSystem, string basePath)
{
_fileSystem = fileSystem;
_basePath = basePath;
}
public bool TryResolveAssemblyPaths(CompilationLibrary library, List<string> assemblies)
{
if (!string.Equals(library.LibraryType, "package", StringComparison.OrdinalIgnoreCase) &&
!string.Equals(library.LibraryType, "project", StringComparison.OrdinalIgnoreCase) &&
!string.Equals(library.LibraryType, "referenceassembly", StringComparison.OrdinalIgnoreCase))
{
return false;
}
var directories = new List<string>()
{
_basePath
};
var refsPath = Path.Combine(_basePath, "refs");
var hasRefs = _fileSystem.Directory.Exists(refsPath);
if (hasRefs)
{
directories.Insert(0, refsPath);
}
foreach (var assembly in library.Assemblies)
{
bool resolved = false;
var assemblyFile = Path.GetFileName(assembly);
foreach (var directory in directories)
{
string fullName;
if (ResolverUtils.TryResolveAssemblyFile(_fileSystem, directory, assemblyFile, out fullName))
{
assemblies.Add(fullName);
resolved = true;
break;
}
}
if (!resolved)
{
throw new InvalidOperationException(
$"Can not find assembly file {assemblyFile} at '{string.Join(",", directories)}'");
}
}
return true;
}
}
}

View file

@ -0,0 +1,30 @@
// 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.Collections.Generic;
using Microsoft.Extensions.DependencyModel.Resolution;
namespace Microsoft.Extensions.DependencyModel.Resolution
{
public class CompositeCompilationAssemblyResolver: ICompilationAssemblyResolver
{
private readonly ICompilationAssemblyResolver[] _resolvers;
public CompositeCompilationAssemblyResolver(ICompilationAssemblyResolver[] resolvers)
{
_resolvers = resolvers;
}
public bool TryResolveAssemblyPaths(CompilationLibrary library, List<string> assemblies)
{
foreach (var resolver in _resolvers)
{
if (resolver.TryResolveAssemblyPaths(library, assemblies))
{
return true;
}
}
return false;;
}
}
}

View file

@ -0,0 +1,12 @@
// 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.Collections.Generic;
namespace Microsoft.Extensions.DependencyModel.Resolution
{
public interface ICompilationAssemblyResolver
{
bool TryResolveAssemblyPaths(CompilationLibrary library, List<string> assemblies);
}
}

View file

@ -0,0 +1,75 @@
// 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;
using System.Collections.Generic;
using System.IO;
using Microsoft.Extensions.EnvironmentAbstractions;
namespace Microsoft.Extensions.DependencyModel.Resolution
{
public class PackageCacheCompilationAssemblyResolver: ICompilationAssemblyResolver
{
private readonly IFileSystem _fileSystem;
private readonly string _packageCacheDirectory;
public PackageCacheCompilationAssemblyResolver()
: this(FileSystemWrapper.Default, EnvironmentWrapper.Default)
{
}
public PackageCacheCompilationAssemblyResolver(string packageCacheDirectory)
: this(FileSystemWrapper.Default, packageCacheDirectory)
{
}
internal PackageCacheCompilationAssemblyResolver(IFileSystem fileSystem, IEnvironment environment)
: this(fileSystem, GetDefaultPackageCacheDirectory(environment))
{
}
internal PackageCacheCompilationAssemblyResolver(IFileSystem fileSystem, string packageCacheDirectory)
{
_packageCacheDirectory = packageCacheDirectory;
_fileSystem = fileSystem;
}
public bool TryResolveAssemblyPaths(CompilationLibrary library, List<string> assemblies)
{
if (!string.Equals(library.LibraryType, "package", StringComparison.OrdinalIgnoreCase))
{
return false;
}
if (!string.IsNullOrEmpty(_packageCacheDirectory))
{
var hashSplitterPos = library.Hash.IndexOf('-');
if (hashSplitterPos <= 0 || hashSplitterPos == library.Hash.Length - 1)
{
throw new InvalidOperationException($"Invalid hash entry '{library.Hash}' for package '{library.PackageName}'");
}
var hashAlgorithm = library.Hash.Substring(0, hashSplitterPos);
var cacheHashPath = Path.Combine(_packageCacheDirectory, $"{library.PackageName}.{library.Version}.nupkg.{hashAlgorithm}");
if (_fileSystem.File.Exists(cacheHashPath) &&
_fileSystem.File.ReadAllText(cacheHashPath) == library.Hash.Substring(hashSplitterPos + 1))
{
string packagePath;
if (ResolverUtils.TryResolvePackagePath(_fileSystem, library, _packageCacheDirectory, out packagePath))
{
assemblies.AddRange( ResolverUtils.ResolveFromPackagePath(_fileSystem, library, packagePath));
return true;
}
}
}
return false;
}
internal static string GetDefaultPackageCacheDirectory(IEnvironment environment)
{
return environment.GetEnvironmentVariable("DOTNET_PACKAGES_CACHE");
}
}
}

View file

@ -0,0 +1,83 @@
// 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;
using System.Collections.Generic;
using System.IO;
using Microsoft.Extensions.PlatformAbstractions;
using Microsoft.Extensions.EnvironmentAbstractions;
namespace Microsoft.Extensions.DependencyModel.Resolution
{
public class PackageCompilationAssemblyResolver: ICompilationAssemblyResolver
{
private readonly IFileSystem _fileSystem;
private readonly string _nugetPackageDirectory;
public PackageCompilationAssemblyResolver()
: this(EnvironmentWrapper.Default, PlatformServices.Default.Runtime, FileSystemWrapper.Default)
{
}
public PackageCompilationAssemblyResolver(string nugetPackageDirectory)
: this(FileSystemWrapper.Default, nugetPackageDirectory)
{
}
internal PackageCompilationAssemblyResolver(IEnvironment environment,
IRuntimeEnvironment runtimeEnvironment,
IFileSystem fileSystem)
: this(fileSystem, GetDefaultPackageDirectory(runtimeEnvironment, environment))
{
}
internal PackageCompilationAssemblyResolver(IFileSystem fileSystem, string nugetPackageDirectory)
{
_fileSystem = fileSystem;
_nugetPackageDirectory = nugetPackageDirectory;
}
internal static string GetDefaultPackageDirectory(IRuntimeEnvironment runtimeEnvironment, IEnvironment environment)
{
var packageDirectory = environment.GetEnvironmentVariable("NUGET_PACKAGES");
if (!string.IsNullOrEmpty(packageDirectory))
{
return packageDirectory;
}
string basePath;
if (runtimeEnvironment.OperatingSystemPlatform == Platform.Windows)
{
basePath = environment.GetEnvironmentVariable("USERPROFILE");
}
else
{
basePath = environment.GetEnvironmentVariable("HOME");
}
if (string.IsNullOrEmpty(basePath))
{
return null;
}
return Path.Combine(basePath, ".nuget", "packages");
}
public bool TryResolveAssemblyPaths(CompilationLibrary library, List<string> assemblies)
{
if (string.IsNullOrEmpty(_nugetPackageDirectory) ||
!string.Equals(library.LibraryType, "package", StringComparison.OrdinalIgnoreCase))
{
return false;
}
string packagePath;
if (ResolverUtils.TryResolvePackagePath(_fileSystem, library, _nugetPackageDirectory, out packagePath))
{
assemblies.AddRange(ResolverUtils.ResolveFromPackagePath(_fileSystem, library, packagePath));
return true;
}
return false;
}
}
}

View file

@ -0,0 +1,143 @@
// 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;
using System.Collections.Generic;
using System.IO;
using Microsoft.Extensions.PlatformAbstractions;
using Microsoft.Extensions.EnvironmentAbstractions;
namespace Microsoft.Extensions.DependencyModel.Resolution
{
public class ReferenceAssemblyPathResolver: ICompilationAssemblyResolver
{
private readonly IFileSystem _fileSystem;
private readonly string _defaultReferenceAssembliesPath;
private readonly string[] _fallbackSearchPaths;
public ReferenceAssemblyPathResolver()
: this(FileSystemWrapper.Default, PlatformServices.Default.Runtime, EnvironmentWrapper.Default)
{
}
public ReferenceAssemblyPathResolver(string defaultReferenceAssembliesPath, string[] fallbackSearchPaths)
: this(FileSystemWrapper.Default, defaultReferenceAssembliesPath, fallbackSearchPaths)
{
}
internal ReferenceAssemblyPathResolver(IFileSystem fileSystem, IRuntimeEnvironment runtimeEnvironment, IEnvironment environment)
: this(fileSystem,
GetDefaultReferenceAssembliesPath(runtimeEnvironment, environment),
GetFallbackSearchPaths(fileSystem, runtimeEnvironment, environment))
{
}
internal ReferenceAssemblyPathResolver(IFileSystem fileSystem, string defaultReferenceAssembliesPath, string[] fallbackSearchPaths)
{
_fileSystem = fileSystem;
_defaultReferenceAssembliesPath = defaultReferenceAssembliesPath;
_fallbackSearchPaths = fallbackSearchPaths;
}
public bool TryResolveAssemblyPaths(CompilationLibrary library, List<string> assemblies)
{
if (!string.Equals(library.LibraryType, "referenceassembly", StringComparison.OrdinalIgnoreCase))
{
return false;
}
foreach (var assembly in library.Assemblies)
{
string fullName;
if (!TryResolveReferenceAssembly(assembly, out fullName))
{
throw new InvalidOperationException($"Can not find reference assembly '{assembly}' file for package {library.PackageName}");
}
assemblies.Add(fullName);
}
return true;
}
private bool TryResolveReferenceAssembly(string path, out string fullPath)
{
fullPath = null;
if (_defaultReferenceAssembliesPath != null)
{
var relativeToReferenceAssemblies = Path.Combine(_defaultReferenceAssembliesPath, path);
if (_fileSystem.File.Exists(relativeToReferenceAssemblies))
{
fullPath = relativeToReferenceAssemblies;
return true;
}
}
var name = Path.GetFileName(path);
foreach (var fallbackPath in _fallbackSearchPaths)
{
var fallbackFile = Path.Combine(fallbackPath, name);
if (_fileSystem.File.Exists(fallbackFile))
{
fullPath = fallbackFile;
return true;
}
}
return false;
}
internal static string[] GetFallbackSearchPaths(IFileSystem fileSystem, IRuntimeEnvironment runtimeEnvironment, IEnvironment environment)
{
if (runtimeEnvironment.OperatingSystemPlatform != Platform.Windows)
{
return new string[0];
}
var net20Dir = Path.Combine(environment.GetEnvironmentVariable("WINDIR"), "Microsoft.NET", "Framework", "v2.0.50727");
if (!fileSystem.Directory.Exists(net20Dir))
{
return new string[0];
}
return new[] { net20Dir };
}
internal static string GetDefaultReferenceAssembliesPath(IRuntimeEnvironment runtimeEnvironment, IEnvironment environment)
{
// Allow setting the reference assemblies path via an environment variable
var referenceAssembliesPath = environment.GetEnvironmentVariable("DOTNET_REFERENCE_ASSEMBLIES_PATH");
if (!string.IsNullOrEmpty(referenceAssembliesPath))
{
return referenceAssembliesPath;
}
if (runtimeEnvironment.OperatingSystemPlatform != Platform.Windows)
{
// There is no reference assemblies path outside of windows
// The environment variable can be used to specify one
return null;
}
// References assemblies are in %ProgramFiles(x86)% on
// 64 bit machines
var programFiles = environment.GetEnvironmentVariable("ProgramFiles(x86)");
if (string.IsNullOrEmpty(programFiles))
{
// On 32 bit machines they are in %ProgramFiles%
programFiles = environment.GetEnvironmentVariable("ProgramFiles");
}
if (string.IsNullOrEmpty(programFiles))
{
// Reference assemblies aren't installed
return null;
}
return Path.Combine(
programFiles,
"Reference Assemblies", "Microsoft", "Framework");
}
}
}

View file

@ -0,0 +1,46 @@
// 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;
using System.Collections.Generic;
using System.IO;
using Microsoft.Extensions.EnvironmentAbstractions;
namespace Microsoft.Extensions.DependencyModel.Resolution
{
internal static class ResolverUtils
{
internal static bool TryResolvePackagePath(IFileSystem fileSystem, CompilationLibrary library, string basePath, out string packagePath)
{
packagePath = Path.Combine(basePath, library.PackageName, library.Version);
if (fileSystem.Directory.Exists(packagePath))
{
return true;
}
return false;
}
internal static IEnumerable<string> ResolveFromPackagePath(IFileSystem fileSystem, CompilationLibrary library, string basePath)
{
foreach (var assembly in library.Assemblies)
{
string fullName;
if (!TryResolveAssemblyFile(fileSystem, basePath, assembly, out fullName))
{
throw new InvalidOperationException($"Can not find assembly file for package {library.PackageName} at '{fullName}'");
}
yield return fullName;
}
}
internal static bool TryResolveAssemblyFile(IFileSystem fileSystem, string basePath, string assemblyPath, out string fullName)
{
fullName = Path.Combine(basePath, assemblyPath);
if (fileSystem.File.Exists(fullName))
{
return true;
}
return false;
}
}
}

View file

@ -10,6 +10,11 @@
"keyFile": "../../tools/Key.snk"
},
"dependencies": {
"Microsoft.DotNet.InternalAbstractions": {
"target": "project",
"version": "1.0.0-*"
},
"Newtonsoft.Json": "7.0.1",
"Microsoft.Extensions.PlatformAbstractions": "1.0.0-rc2-16537"
},

View file

@ -0,0 +1,48 @@
// 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.Collections.Generic;
using Microsoft.Extensions.EnvironmentAbstractions;
namespace Microsoft.DotNet.Tools.Test.Utilities.Mock
{
internal class EnvironmentMockBuilder
{
private Dictionary<string, string> _variables = new Dictionary<string, string>();
internal static IEnvironment Empty { get; } = Create().Build();
public static EnvironmentMockBuilder Create()
{
return new EnvironmentMockBuilder();
}
public EnvironmentMockBuilder AddVariable(string name, string value)
{
_variables.Add(name, value);
return this;
}
internal IEnvironment Build()
{
return new EnvironmentMock(_variables);
}
private class EnvironmentMock : IEnvironment
{
private Dictionary<string, string> _variables;
public EnvironmentMock(Dictionary<string, string> variables)
{
_variables = variables;
}
public string GetEnvironmentVariable(string name)
{
string value = null;
_variables.TryGetValue(name, out value);
return value;
}
}
}
}

View file

@ -0,0 +1,94 @@
// 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.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Extensions.EnvironmentAbstractions;
namespace Microsoft.Extensions.DependencyModel.Tests
{
class FileSystemMockBuilder
{
private Dictionary<string, string> _files = new Dictionary<string, string>();
internal static IFileSystem Empty { get; } = Create().Build();
public static FileSystemMockBuilder Create()
{
return new FileSystemMockBuilder();
}
public FileSystemMockBuilder AddFile(string name, string content = "")
{
_files.Add(name, content);
return this;
}
public FileSystemMockBuilder AddFiles(string basePath, params string[] files)
{
foreach (var file in files)
{
AddFile(Path.Combine(basePath, file));
}
return this;
}
internal IFileSystem Build()
{
return new FileSystemMock(_files);
}
private class FileSystemMock : IFileSystem
{
public FileSystemMock(Dictionary<string, string> files)
{
File = new FileMock(files);
Directory = new DirectoryMock(files);
}
public IFile File { get; }
public IDirectory Directory { get; }
}
private class FileMock : IFile
{
private Dictionary<string, string> _files;
public FileMock(Dictionary<string, string> files)
{
_files = files;
}
public bool Exists(string path)
{
return _files.ContainsKey(path);
}
public string ReadAllText(string path)
{
string text;
if (!_files.TryGetValue(path, out text))
{
throw new FileNotFoundException(path);
}
return text;
}
}
private class DirectoryMock : IDirectory
{
private Dictionary<string, string> _files;
public DirectoryMock(Dictionary<string, string> files)
{
_files = files;
}
public bool Exists(string path)
{
return _files.Keys.Any(k => k.StartsWith(path));
}
}
}
}

View file

@ -0,0 +1,3 @@
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Microsoft.Extensions.DependencyModel.Tests , PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]

View file

@ -1,15 +1,22 @@
{
"version": "1.0.0-*",
"description": "Microsoft.DotNet.Tools.Tests.Utilities Class Library",
"compilationOptions": {
"keyFile": "../../tools/Key.snk"
},
"dependencies": {
"NETStandard.Library": "1.0.0-rc2-23811",
"System.Collections.Immutable": "1.2.0-rc2-23811",
"FluentAssertions": "4.0.0",
"xunit": "2.1.0",
"dotnet-test-xunit": "1.0.0-dev-48273-16",
"Microsoft.DotNet.Cli.Utils": "1.0.0-*",
"Microsoft.Extensions.PlatformAbstractions": "1.0.0-rc2-16537"
"Microsoft.Extensions.PlatformAbstractions": "1.0.0-rc2-16537",
"Microsoft.DotNet.InternalAbstractions": {
"target": "project",
"version": "1.0.0-*"
}
},

View file

@ -0,0 +1,172 @@
// 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;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyModel;
using Microsoft.Extensions.DependencyModel.Resolution;
using Xunit;
using FluentAssertions;
namespace Microsoft.Extensions.DependencyModel.Tests
{
public class AppBaseResolverTests
{
private static string BasePath = Path.Combine("Base","Path");
private static string BasePathRefs = Path.Combine(BasePath, "refs");
[Fact]
public void ResolvesProjectType()
{
var resolver = new AppBaseCompilationAssemblyResolver();
var library = TestLibraryFactory.Create(
TestLibraryFactory.ProjectType,
assemblies: TestLibraryFactory.EmptyAssemblies);
var result = resolver.TryResolveAssemblyPaths(library, null);
Assert.True(result);
}
[Fact]
public void ResolvesPackageType()
{
var resolver = new AppBaseCompilationAssemblyResolver();
var library = TestLibraryFactory.Create(
TestLibraryFactory.PackageType,
assemblies: TestLibraryFactory.EmptyAssemblies);
var result = resolver.TryResolveAssemblyPaths(library, null);
Assert.True(result);
}
[Fact]
public void ResolvesReferenceAssemblyType()
{
var resolver = new AppBaseCompilationAssemblyResolver();
var library = TestLibraryFactory.Create(
TestLibraryFactory.ReferenceAssemblyType,
assemblies: TestLibraryFactory.EmptyAssemblies);
var result = resolver.TryResolveAssemblyPaths(library, null);
Assert.True(result);
}
[Fact]
public void RequiresAllLibrariesToExist()
{
var fileSystem = FileSystemMockBuilder
.Create()
.AddFiles(BasePath, TestLibraryFactory.DefaultAssembly)
.AddFiles(BasePathRefs, TestLibraryFactory.DefaultAssembly)
.Build();
var library = TestLibraryFactory.Create(
TestLibraryFactory.ReferenceAssemblyType,
assemblies: TestLibraryFactory.TwoAssemblies);
var resolver = new AppBaseCompilationAssemblyResolver(fileSystem, BasePath);
var assemblies = new List<string>();
var exception = Assert.Throws<InvalidOperationException>(() => resolver.TryResolveAssemblyPaths(library, assemblies));
exception.Message.Should()
.Contain(BasePath)
.And.Contain(BasePathRefs)
.And.Contain(TestLibraryFactory.SecondAssembly);
}
[Fact]
public void ResolvesIfAllAreInBaseDir()
{
var fileSystem = FileSystemMockBuilder
.Create()
.AddFiles(BasePath, TestLibraryFactory.DefaultAssembly, TestLibraryFactory.SecondAssembly)
.Build();
var library = TestLibraryFactory.Create(
TestLibraryFactory.ReferenceAssemblyType,
assemblies: TestLibraryFactory.TwoAssemblies);
var resolver = new AppBaseCompilationAssemblyResolver(fileSystem, BasePath);
var assemblies = new List<string>();
var result = resolver.TryResolveAssemblyPaths(library, assemblies);
Assert.True(result);
assemblies.Should().HaveCount(2);
assemblies.Should().Contain(Path.Combine(BasePath, TestLibraryFactory.DefaultAssembly));
assemblies.Should().Contain(Path.Combine(BasePath, TestLibraryFactory.SecondAssembly));
}
[Fact]
public void ResolvesIfAllAreInRefDir()
{
var fileSystem = FileSystemMockBuilder
.Create()
.AddFiles(BasePathRefs, TestLibraryFactory.DefaultAssembly, TestLibraryFactory.SecondAssembly)
.Build();
var library = TestLibraryFactory.Create(
TestLibraryFactory.ReferenceAssemblyType,
assemblies: TestLibraryFactory.TwoAssemblies);
var resolver = new AppBaseCompilationAssemblyResolver(fileSystem, BasePath);
var assemblies = new List<string>();
var result = resolver.TryResolveAssemblyPaths(library, assemblies);
Assert.True(result);
assemblies.Should().HaveCount(2);
assemblies.Should().Contain(Path.Combine(BasePathRefs, TestLibraryFactory.DefaultAssembly));
assemblies.Should().Contain(Path.Combine(BasePathRefs, TestLibraryFactory.SecondAssembly));
}
[Fact]
public void ResolvesIfOneInBaseOtherInRefs()
{
var fileSystem = FileSystemMockBuilder
.Create()
.AddFiles(BasePath, TestLibraryFactory.DefaultAssembly)
.AddFiles(BasePathRefs, TestLibraryFactory.SecondAssembly)
.Build();
var library = TestLibraryFactory.Create(
TestLibraryFactory.ReferenceAssemblyType,
assemblies: TestLibraryFactory.TwoAssemblies);
var resolver = new AppBaseCompilationAssemblyResolver(fileSystem, BasePath);
var assemblies = new List<string>();
var result = resolver.TryResolveAssemblyPaths(library, assemblies);
Assert.True(result);
assemblies.Should().HaveCount(2);
assemblies.Should().Contain(Path.Combine(BasePath, TestLibraryFactory.DefaultAssembly));
assemblies.Should().Contain(Path.Combine(BasePathRefs, TestLibraryFactory.SecondAssembly));
}
[Fact]
public void PrefersRefs()
{
var fileSystem = FileSystemMockBuilder
.Create()
.AddFiles(BasePath, TestLibraryFactory.DefaultAssembly)
.AddFiles(BasePathRefs, TestLibraryFactory.DefaultAssembly)
.Build();
var library = TestLibraryFactory.Create(
TestLibraryFactory.ReferenceAssemblyType
);
var resolver = new AppBaseCompilationAssemblyResolver(fileSystem, BasePath);
var assemblies = new List<string>();
var result = resolver.TryResolveAssemblyPaths(library, assemblies);
Assert.True(result);
assemblies.Should().HaveCount(1);
assemblies.Should().Contain(Path.Combine(BasePathRefs, TestLibraryFactory.DefaultAssembly));
}
}
}

View file

@ -0,0 +1,93 @@
// 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;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyModel;
using Microsoft.Extensions.DependencyModel.Resolution;
using Moq;
using Xunit;
using FluentAssertions;
namespace StreamForwarderTests
{
public class CompositeResolverTests
{
[Fact]
public void ReturnsFirstSuccesfullResolve()
{
var fail = new Mock<ICompilationAssemblyResolver>();
var success = new Mock<ICompilationAssemblyResolver>();
success.Setup(r => r.TryResolveAssemblyPaths(It.IsAny<CompilationLibrary>(), It.IsAny<List<string>>()))
.Returns(true);
var failTwo = new Mock<ICompilationAssemblyResolver>();
var resolvers = new[]
{
fail.Object,
success.Object,
failTwo.Object
};
var resolver = new CompositeCompilationAssemblyResolver(resolvers);
var result = resolver.TryResolveAssemblyPaths(null, null);
Assert.True(result);
fail.Verify(r => r.TryResolveAssemblyPaths(It.IsAny<CompilationLibrary>(), It.IsAny<List<string>>()),
Times.Once());
success.Verify(r => r.TryResolveAssemblyPaths(It.IsAny<CompilationLibrary>(), It.IsAny<List<string>>()),
Times.Once());
failTwo.Verify(r => r.TryResolveAssemblyPaths(It.IsAny<CompilationLibrary>(), It.IsAny<List<string>>()),
Times.Never());
}
[Fact]
public void PassesLibraryToAllResolvers()
{
var fail = new Mock<ICompilationAssemblyResolver>();
var failTwo = new Mock<ICompilationAssemblyResolver>();
var resolvers = new[]
{
fail.Object,
failTwo.Object
};
var library = new CompilationLibrary(string.Empty, string.Empty, string.Empty, string.Empty, null, null, false);
var resolver = new CompositeCompilationAssemblyResolver(resolvers);
var result = resolver.TryResolveAssemblyPaths(library, null);
fail.Verify(r => r.TryResolveAssemblyPaths(library, null), Times.Once());
failTwo.Verify(r => r.TryResolveAssemblyPaths(library, null), Times.Once());
}
[Fact]
public void PopulatedAssemblies()
{
var fail = new Mock<ICompilationAssemblyResolver>();
var success = new Mock<ICompilationAssemblyResolver>();
success.Setup(r => r.TryResolveAssemblyPaths(It.IsAny<CompilationLibrary>(), It.IsAny<List<string>>()))
.Returns(true)
.Callback((CompilationLibrary l, List<string> a) =>
{
a.Add("Assembly");
});
var resolvers = new[]
{
fail.Object,
success.Object
};
var assemblies = new List<string>();
var library = new CompilationLibrary(string.Empty, string.Empty, string.Empty, string.Empty, null, null, false);
var resolver = new CompositeCompilationAssemblyResolver(resolvers);
var result = resolver.TryResolveAssemblyPaths(library, assemblies);
assemblies.Should().Contain("Assembly");
}
}
}

View file

@ -0,0 +1,48 @@
// 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.Collections.Generic;
using Microsoft.Extensions.EnvironmentAbstractions;
namespace Microsoft.Extensions.DependencyModel.Tests
{
public class EnvironmentMockBuilder
{
private Dictionary<string, string> _variables = new Dictionary<string, string>();
internal static IEnvironment Empty { get; } = Create().Build();
public static EnvironmentMockBuilder Create()
{
return new EnvironmentMockBuilder();
}
public EnvironmentMockBuilder AddVariable(string name, string value)
{
_variables.Add(name, value);
return this;
}
internal IEnvironment Build()
{
return new EnvironmentMock(_variables);
}
private class EnvironmentMock : IEnvironment
{
private Dictionary<string, string> _variables;
public EnvironmentMock(Dictionary<string, string> variables)
{
_variables = variables;
}
public string GetEnvironmentVariable(string name)
{
string value = null;
_variables.TryGetValue(name, out value);
return value;
}
}
}
}

View file

@ -0,0 +1,94 @@
// 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.Linq;
using System.Collections.Generic;
using System.IO;
using Microsoft.Extensions.EnvironmentAbstractions;
namespace Microsoft.Extensions.DependencyModel.Tests
{
class FileSystemMockBuilder
{
private Dictionary<string, string> _files = new Dictionary<string, string>();
public static IFileSystem Empty { get; } = Create().Build();
public static FileSystemMockBuilder Create()
{
return new FileSystemMockBuilder();
}
public FileSystemMockBuilder AddFile(string name, string content = "")
{
_files.Add(name, content);
return this;
}
public FileSystemMockBuilder AddFiles(string basePath, params string[] files)
{
foreach (var file in files)
{
AddFile(Path.Combine(basePath, file));
}
return this;
}
public IFileSystem Build()
{
return new FileSystemMock(_files);
}
private class FileSystemMock : IFileSystem
{
public FileSystemMock(Dictionary<string, string> files)
{
File = new FileMock(files);
Directory = new DirectoryMock(files);
}
public IFile File { get; }
public IDirectory Directory { get; }
}
private class FileMock : IFile
{
private Dictionary<string, string> _files;
public FileMock(Dictionary<string, string> files)
{
_files = files;
}
public bool Exists(string path)
{
return _files.ContainsKey(path);
}
public string ReadAllText(string path)
{
string text;
if (!_files.TryGetValue(path, out text))
{
throw new FileNotFoundException(path);
}
return text;
}
}
private class DirectoryMock : IDirectory
{
private Dictionary<string, string> _files;
public DirectoryMock(Dictionary<string, string> files)
{
_files = files;
}
public bool Exists(string path)
{
return _files.Keys.Any(k => k.StartsWith(path));
}
}
}
}

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0.23107" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.23107</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>4a4711d8-4312-49fc-87b5-4f183f4c6a51</ProjectGuid>
<RootNamespace>Microsoft.Extensions.DependencyModel.Tests</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View file

@ -0,0 +1,129 @@
// 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;
using System.Collections.Generic;
using System.IO;
using FluentAssertions;
using Microsoft.Extensions.EnvironmentAbstractions;
using Microsoft.Extensions.DependencyModel.Resolution;
using Xunit;
using F = Microsoft.Extensions.DependencyModel.Tests.TestLibraryFactory;
namespace Microsoft.Extensions.DependencyModel.Tests
{
public class PackageCacheResolverTest
{
private static string CachePath = Path.Combine("cache", "directory", "location");
[Fact]
public void SholdUseEnvironmentVariableToGetDefaultLocation()
{
var result = PackageCacheCompilationAssemblyResolver.GetDefaultPackageCacheDirectory(GetDefaultEnviroment());
result.Should().Be(CachePath);
}
[Fact]
public void SkipsNonPackage()
{
var resolver = new PackageCacheCompilationAssemblyResolver();
var library = F.Create(
F.PackageType,
assemblies: F.EmptyAssemblies);
var result = resolver.TryResolveAssemblyPaths(library, null);
result.Should().BeFalse();
}
[Theory]
[InlineData("INVALIDHASHVALUE")]
[InlineData("INVALIDHASHVALUE-")]
[InlineData("-INVALIDHASHVALUE")]
public void FailsOnInvalidHash(string hash)
{
var resolver = new PackageCacheCompilationAssemblyResolver(FileSystemMockBuilder.Empty, CachePath);
var library = F.Create(hash: hash);
var exception = Assert.Throws<InvalidOperationException>(() => resolver.TryResolveAssemblyPaths(library, null));
exception.Message.Should()
.Contain(library.Hash)
.And.Contain(library.PackageName);
}
[Fact]
public void ChecksHashFile()
{
var packagePath = Path.Combine(CachePath, F.DefaultPackageName, F.DefaultVersion);
var fileSystem = FileSystemMockBuilder.Create()
.AddFile(
Path.Combine(CachePath, $"{F.DefaultPackageName}.{F.DefaultVersion}.nupkg.{F.DefaultHashAlgoritm}"),
"WRONGHASH"
)
.AddFiles(packagePath, F.DefaultAssemblies)
.Build();
var resolver = new PackageCacheCompilationAssemblyResolver(fileSystem, CachePath);
var assemblies = new List<string>();
var result = resolver.TryResolveAssemblyPaths(F.Create(), assemblies);
result.Should().BeFalse();
}
[Fact]
public void ResolvesAllAssemblies()
{
var packagePath = Path.Combine(CachePath, F.DefaultPackageName, F.DefaultVersion);
var fileSystem = FileSystemMockBuilder.Create()
.AddFile(
Path.Combine(CachePath, $"{F.DefaultPackageName}.{F.DefaultVersion}.nupkg.{F.DefaultHashAlgoritm}"),
F.DefaultHashValue
)
.AddFiles(packagePath, F.TwoAssemblies)
.Build();
var library = F.Create(assemblies: F.TwoAssemblies);
var resolver = new PackageCacheCompilationAssemblyResolver(fileSystem, CachePath);
var assemblies = new List<string>();
var result = resolver.TryResolveAssemblyPaths(library, assemblies);
assemblies.Should().HaveCount(2);
assemblies.Should().Contain(Path.Combine(packagePath, F.DefaultAssemblyPath));
assemblies.Should().Contain(Path.Combine(packagePath, F.SecondAssemblyPath));
}
[Fact]
public void FailsWhenOneOfAssembliesNotFound()
{
var packagePath = Path.Combine(CachePath, F.DefaultPackageName, F.DefaultVersion);
var fileSystem = FileSystemMockBuilder.Create()
.AddFile(
Path.Combine(CachePath, $"{F.DefaultPackageName}.{F.DefaultVersion}.nupkg.{F.DefaultHashAlgoritm}"),
F.DefaultHashValue
)
.AddFiles(packagePath, F.DefaultAssemblyPath)
.Build();
var library = F.Create(assemblies: F.TwoAssemblies);
var resolver = new PackageCacheCompilationAssemblyResolver(fileSystem, CachePath);
var assemblies = new List<string>();
var exception = Assert.Throws<InvalidOperationException>(() => resolver.TryResolveAssemblyPaths(library, assemblies));
exception.Message.Should()
.Contain(F.SecondAssemblyPath)
.And.Contain(library.PackageName);
}
private IEnvironment GetDefaultEnviroment()
{
return EnvironmentMockBuilder.Create()
.AddVariable("DOTNET_PACKAGES_CACHE", CachePath)
.Build();
}
}
}

View file

@ -0,0 +1,101 @@
// 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;
using System.Collections.Generic;
using System.IO;
using FluentAssertions;
using Microsoft.Extensions.DependencyModel.Resolution;
using Microsoft.Extensions.PlatformAbstractions;
using Moq;
using Xunit;
using F = Microsoft.Extensions.DependencyModel.Tests.TestLibraryFactory;
namespace Microsoft.Extensions.DependencyModel.Tests
{
public class PackageResolverTest
{
private static string PackagesPath = Path.Combine("package", "directory", "location");
[Fact]
public void SholdUseEnvironmentVariableToGetDefaultLocation()
{
var runtime = new Mock<IRuntimeEnvironment>();
var environment = EnvironmentMockBuilder.Create()
.AddVariable("NUGET_PACKAGES", PackagesPath)
.Build();
var result = PackageCompilationAssemblyResolver.GetDefaultPackageDirectory(runtime.Object, environment);
result.Should().Be(PackagesPath);
}
[Fact]
public void SholdUseNugetUnderUserProfileOnWindows()
{
var runtime = new Mock<IRuntimeEnvironment>();
runtime.SetupGet(r => r.OperatingSystemPlatform).Returns(Platform.Windows);
var environment = EnvironmentMockBuilder.Create()
.AddVariable("USERPROFILE", "User Profile")
.Build();
var result = PackageCompilationAssemblyResolver.GetDefaultPackageDirectory(runtime.Object, environment);
result.Should().Be(Path.Combine("User Profile", ".nuget", "packages"));
}
[Fact]
public void SholdUseNugetUnderHomeOnNonWindows()
{
var runtime = new Mock<IRuntimeEnvironment>();
runtime.SetupGet(r => r.OperatingSystemPlatform).Returns(Platform.Linux);
var environment = EnvironmentMockBuilder.Create()
.AddVariable("HOME", "User Home")
.Build();
var result = PackageCompilationAssemblyResolver.GetDefaultPackageDirectory(runtime.Object, environment);
result.Should().Be(Path.Combine("User Home", ".nuget", "packages"));
}
[Fact]
public void ResolvesAllAssemblies()
{
var packagePath = Path.Combine(PackagesPath, F.DefaultPackageName, F.DefaultVersion);
var fileSystem = FileSystemMockBuilder.Create()
.AddFiles(packagePath, F.TwoAssemblies)
.Build();
var library = F.Create(assemblies: F.TwoAssemblies);
var resolver = new PackageCompilationAssemblyResolver(fileSystem, PackagesPath);
var assemblies = new List<string>();
var result = resolver.TryResolveAssemblyPaths(library, assemblies);
assemblies.Should().HaveCount(2);
assemblies.Should().Contain(Path.Combine(packagePath, F.DefaultAssemblyPath));
assemblies.Should().Contain(Path.Combine(packagePath, F.SecondAssemblyPath));
}
[Fact]
public void FailsWhenOneOfAssembliesNotFound()
{
var packagePath = Path.Combine(PackagesPath, F.DefaultPackageName, F.DefaultVersion);
var fileSystem = FileSystemMockBuilder.Create()
.AddFiles(packagePath, F.DefaultAssemblyPath)
.Build();
var library = F.Create(assemblies: F.TwoAssemblies);
var resolver = new PackageCompilationAssemblyResolver(fileSystem, PackagesPath);
var assemblies = new List<string>();
var exception = Assert.Throws<InvalidOperationException>(() => resolver.TryResolveAssemblyPaths(library, assemblies));
exception.Message.Should()
.Contain(F.SecondAssemblyPath)
.And.Contain(library.PackageName);
}
}
}

View file

@ -0,0 +1,159 @@
// 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;
using System.Collections.Generic;
using System.IO;
using FluentAssertions;
using Microsoft.Extensions.DependencyModel.Resolution;
using Microsoft.Extensions.PlatformAbstractions;
using Moq;
using Xunit;
using F = Microsoft.Extensions.DependencyModel.Tests.TestLibraryFactory;
namespace Microsoft.Extensions.DependencyModel.Tests
{
public class ReferenceAssemblyResolverTests
{
private static string ReferencePath = Path.Combine("reference", "assembly", "directory", "location");
[Fact]
public void SkipsNonReferenceAssembly()
{
var resolver = new ReferenceAssemblyPathResolver();
var library = F.Create(
F.PackageType);
var result = resolver.TryResolveAssemblyPaths(library, null);
result.Should().BeFalse();
}
[Fact]
public void UsesEnvironmentVariableForDefaultPath()
{
var runtime = new Mock<IRuntimeEnvironment>();
runtime.SetupGet(r => r.OperatingSystemPlatform).Returns(Platform.Windows);
var environment = EnvironmentMockBuilder.Create()
.AddVariable("DOTNET_REFERENCE_ASSEMBLIES_PATH", ReferencePath)
.Build();
var result = ReferenceAssemblyPathResolver.GetDefaultReferenceAssembliesPath(runtime.Object, environment);
result.Should().Be(ReferencePath);
}
[Fact]
public void LooksOnlyOnEnvironmentVariableOnNonWindows()
{
var runtime = new Mock<IRuntimeEnvironment>();
runtime.SetupGet(r => r.OperatingSystemPlatform).Returns(Platform.Linux);
var result = ReferenceAssemblyPathResolver.GetDefaultReferenceAssembliesPath(runtime.Object, EnvironmentMockBuilder.Empty);
result.Should().BeNull();
}
[Fact]
public void ReturnsProgramFiles86AsDefaultLocationOnWin64()
{
var runtime = new Mock<IRuntimeEnvironment>();
runtime.SetupGet(r => r.OperatingSystemPlatform).Returns(Platform.Windows);
var environment = EnvironmentMockBuilder.Create()
.AddVariable("ProgramFiles(x86)", "Program Files (x86)")
.AddVariable("ProgramFiles", "Program Files")
.Build();
var result = ReferenceAssemblyPathResolver.GetDefaultReferenceAssembliesPath(runtime.Object, environment);
result.Should().Be(Path.Combine("Program Files (x86)", "Reference Assemblies", "Microsoft", "Framework"));
}
[Fact]
public void ReturnsProgramFilesAsDefaultLocationOnWin32()
{
var runtime = new Mock<IRuntimeEnvironment>();
runtime.SetupGet(r => r.OperatingSystemPlatform).Returns(Platform.Windows);
var environment = EnvironmentMockBuilder.Create()
.AddVariable("ProgramFiles", "Program Files")
.Build();
var result = ReferenceAssemblyPathResolver.GetDefaultReferenceAssembliesPath(runtime.Object, environment);
result.Should().Be(Path.Combine("Program Files", "Reference Assemblies", "Microsoft", "Framework"));
}
[Fact]
public void ReturnNet20PathAsFallbackOnWindows()
{
var net20Path = Path.Combine("Windows", "Microsoft.NET", "Framework", "v2.0.50727");
var fileSystem = FileSystemMockBuilder.Create()
.AddFiles(net20Path, "some.dll")
.Build();
var runtime = new Mock<IRuntimeEnvironment>();
runtime.SetupGet(r => r.OperatingSystemPlatform).Returns(Platform.Windows);
var environment = EnvironmentMockBuilder.Create()
.AddVariable("WINDIR", "Windows")
.Build();
var result = ReferenceAssemblyPathResolver.GetFallbackSearchPaths(fileSystem, runtime.Object, environment);
result.Should().Contain(net20Path);
}
[Fact]
public void ChecksForRelativePathUnderDefaultLocation()
{
var fileSystem = FileSystemMockBuilder.Create()
.AddFiles(ReferencePath, F.DefaultAssemblyPath)
.Build();
var library = F.Create(libraryType: F.ReferenceAssemblyType);
var assemblies = new List<string>();
var resolver = new ReferenceAssemblyPathResolver(fileSystem, ReferencePath, new string[] { });
var result = resolver.TryResolveAssemblyPaths(library, assemblies);
result.Should().BeTrue();
assemblies.Should().Contain(Path.Combine(ReferencePath, F.DefaultAssemblyPath));
}
[Fact]
public void ChecksForFileNameInFallbackLocation()
{
var fileSystem = FileSystemMockBuilder.Create()
.AddFiles(ReferencePath, F.DefaultAssembly)
.Build();
var library = F.Create(libraryType: F.ReferenceAssemblyType);
var assemblies = new List<string>();
var resolver = new ReferenceAssemblyPathResolver(fileSystem, null, new string[] { ReferencePath });
var result = resolver.TryResolveAssemblyPaths(library, assemblies);
result.Should().BeTrue();
assemblies.Should().Contain(Path.Combine(ReferencePath, F.DefaultAssembly));
}
[Fact]
public void ShouldResolveAll()
{
var fileSystem = FileSystemMockBuilder.Create()
.AddFiles(ReferencePath, F.DefaultAssembly)
.Build();
var library = F.Create(libraryType: F.ReferenceAssemblyType, assemblies: F.TwoAssemblies);
var assemblies = new List<string>();
var resolver = new ReferenceAssemblyPathResolver(fileSystem, null, new string[] { ReferencePath });
var exception = Assert.Throws<InvalidOperationException>(() => resolver.TryResolveAssemblyPaths(library, assemblies));
exception.Message.Should()
.Contain(F.SecondAssemblyPath)
.And.Contain(library.PackageName);
}
}
}

View file

@ -0,0 +1,53 @@
// 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;
namespace Microsoft.Extensions.DependencyModel.Tests
{
static class TestLibraryFactory
{
public static readonly string DefaultType = "package";
public static readonly string DefaultPackageName = "My.Package";
public static readonly string DefaultVersion = "1.2.3.7";
public static readonly Dependency[] DefaultDependencies = { };
public static readonly bool DefaultServiceable = true;
public static readonly string DefaultAssembly = "My.Package.dll";
public static readonly string SecondAssembly = "My.PackageEx.dll";
public static readonly string DefaultAssemblyPath = Path.Combine("ref", DefaultAssembly);
public static readonly string SecondAssemblyPath = Path.Combine("ref", SecondAssembly);
public static readonly string[] EmptyAssemblies = { };
public static readonly string[] DefaultAssemblies = { DefaultAssemblyPath };
public static readonly string[] TwoAssemblies = { DefaultAssemblyPath, SecondAssemblyPath };
public static readonly string DefaultHashValue = "HASHVALUE";
public static readonly string DefaultHashAlgoritm = "ALG";
public static readonly string DefaultHash = DefaultHashAlgoritm + "-" + DefaultHashValue;
public static readonly string ProjectType = "project";
public static readonly string ReferenceAssemblyType = "referenceassembly";
public static readonly string PackageType = "package";
public static CompilationLibrary Create(
string libraryType = null,
string packageName = null,
string version = null,
string hash = null,
string[] assemblies = null,
Dependency[] dependencies = null,
bool? serviceable = null)
{
return new CompilationLibrary(
libraryType ?? DefaultType,
packageName ?? DefaultPackageName,
version ?? DefaultVersion,
hash ?? DefaultHash,
assemblies ?? DefaultAssemblies,
dependencies ?? DefaultDependencies,
serviceable ?? DefaultServiceable
);
}
}
}

View file

@ -0,0 +1,25 @@
{
"version": "1.0.0-*",
"description": "Microsoft.DotNet.Tools.Tests.Utilities Class Library",
"compilationOptions": {
"keyFile": "../../tools/Key.snk"
},
"dependencies": {
"NETStandard.Library": "1.0.0-rc2-23811",
"Microsoft.DotNet.Tools.Tests.Utilities": { "target": "project" },
"FluentAssertions": "4.0.0",
"moq.netcore": "4.4.0-beta8",
"xunit": "2.1.0",
"dotnet-test-xunit": "1.0.0-dev-48273-16"
},
"frameworks": {
"dnxcore50": {
"imports": "portable-net45+win8"
}
},
"testRunner": "xunit"
}