diff --git a/Microsoft.DotNet.Cli.sln b/Microsoft.DotNet.Cli.sln index ce13bb1b6..61d7908da 100644 --- a/Microsoft.DotNet.Cli.sln +++ b/Microsoft.DotNet.Cli.sln @@ -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 diff --git a/scripts/dotnet-cli-build/TestTargets.cs b/scripts/dotnet-cli-build/TestTargets.cs index a31bd4d6f..78e24baaa 100644 --- a/scripts/dotnet-cli-build/TestTargets.cs +++ b/scripts/dotnet-cli-build/TestTargets.cs @@ -29,6 +29,7 @@ namespace Microsoft.DotNet.Cli.Build "dotnet-pack.Tests", "Microsoft.DotNet.Cli.Utils.Tests", "Microsoft.DotNet.Compiler.Common.Tests", + "Microsoft.Extensions.DependencyModel.Tests", "ArgumentForwardingTests" }; diff --git a/scripts/package/projectsToPack.ps1 b/scripts/package/projectsToPack.ps1 index 047753336..1b8cbe54f 100644 --- a/scripts/package/projectsToPack.ps1 +++ b/scripts/package/projectsToPack.ps1 @@ -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" ) \ No newline at end of file diff --git a/src/Microsoft.DotNet.InternalAbstractions/DirectoryWrapper.cs b/src/Microsoft.DotNet.InternalAbstractions/DirectoryWrapper.cs new file mode 100644 index 000000000..3aa9b5174 --- /dev/null +++ b/src/Microsoft.DotNet.InternalAbstractions/DirectoryWrapper.cs @@ -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); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.InternalAbstractions/EnvironmentWrapper.cs b/src/Microsoft.DotNet.InternalAbstractions/EnvironmentWrapper.cs new file mode 100644 index 000000000..405cd9054 --- /dev/null +++ b/src/Microsoft.DotNet.InternalAbstractions/EnvironmentWrapper.cs @@ -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); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.InternalAbstractions/FileSystemWrapper.cs b/src/Microsoft.DotNet.InternalAbstractions/FileSystemWrapper.cs new file mode 100644 index 000000000..9d69002e8 --- /dev/null +++ b/src/Microsoft.DotNet.InternalAbstractions/FileSystemWrapper.cs @@ -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(); + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.InternalAbstractions/FileWrapper.cs b/src/Microsoft.DotNet.InternalAbstractions/FileWrapper.cs new file mode 100644 index 000000000..8b6efbeac --- /dev/null +++ b/src/Microsoft.DotNet.InternalAbstractions/FileWrapper.cs @@ -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); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.InternalAbstractions/IDirectory.cs b/src/Microsoft.DotNet.InternalAbstractions/IDirectory.cs new file mode 100644 index 000000000..20f28a9c5 --- /dev/null +++ b/src/Microsoft.DotNet.InternalAbstractions/IDirectory.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.Extensions.EnvironmentAbstractions +{ + internal interface IDirectory + { + bool Exists(string path); + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.InternalAbstractions/IEnvironment.cs b/src/Microsoft.DotNet.InternalAbstractions/IEnvironment.cs new file mode 100644 index 000000000..79452612f --- /dev/null +++ b/src/Microsoft.DotNet.InternalAbstractions/IEnvironment.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.Extensions.EnvironmentAbstractions +{ + internal interface IEnvironment + { + string GetEnvironmentVariable(string name); + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.InternalAbstractions/IFile.cs b/src/Microsoft.DotNet.InternalAbstractions/IFile.cs new file mode 100644 index 000000000..26d029eec --- /dev/null +++ b/src/Microsoft.DotNet.InternalAbstractions/IFile.cs @@ -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); + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.InternalAbstractions/IFileSystem.cs b/src/Microsoft.DotNet.InternalAbstractions/IFileSystem.cs new file mode 100644 index 000000000..87e5f9863 --- /dev/null +++ b/src/Microsoft.DotNet.InternalAbstractions/IFileSystem.cs @@ -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; } + } +} diff --git a/src/Microsoft.DotNet.InternalAbstractions/Properties/Properties.cs b/src/Microsoft.DotNet.InternalAbstractions/Properties/Properties.cs new file mode 100644 index 000000000..f8989eabc --- /dev/null +++ b/src/Microsoft.DotNet.InternalAbstractions/Properties/Properties.cs @@ -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")] \ No newline at end of file diff --git a/src/Microsoft.DotNet.InternalAbstractions/project.json b/src/Microsoft.DotNet.InternalAbstractions/project.json new file mode 100644 index 000000000..67016d56d --- /dev/null +++ b/src/Microsoft.DotNet.InternalAbstractions/project.json @@ -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": { + } +} diff --git a/src/Microsoft.Extensions.DependencyModel/CompilationLibrary.cs b/src/Microsoft.Extensions.DependencyModel/CompilationLibrary.cs index 6acd61e16..f1989c882 100644 --- a/src/Microsoft.Extensions.DependencyModel/CompilationLibrary.cs +++ b/src/Microsoft.Extensions.DependencyModel/CompilationLibrary.cs @@ -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 Assemblies { get; } - public IEnumerable 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() - { - 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 ResolveFromPackagePath(string basePath) + public IEnumerable ResolveReferencePaths(CompilationLibrary compilationLibrary) { - foreach (var assembly in Assemblies) + var assemblies = new List(); + 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 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 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; } } } \ No newline at end of file diff --git a/src/Microsoft.Extensions.DependencyModel/PackagePathResolver.cs b/src/Microsoft.Extensions.DependencyModel/PackagePathResolver.cs deleted file mode 100644 index e68353190..000000000 --- a/src/Microsoft.Extensions.DependencyModel/PackagePathResolver.cs +++ /dev/null @@ -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; - } - - } -} diff --git a/src/Microsoft.Extensions.DependencyModel/Properties/Properties.cs b/src/Microsoft.Extensions.DependencyModel/Properties/Properties.cs new file mode 100644 index 000000000..db059877f --- /dev/null +++ b/src/Microsoft.Extensions.DependencyModel/Properties/Properties.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Microsoft.Extensions.DependencyModel.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] \ No newline at end of file diff --git a/src/Microsoft.Extensions.DependencyModel/ReferenceAssemblyPathResolver.cs b/src/Microsoft.Extensions.DependencyModel/ReferenceAssemblyPathResolver.cs deleted file mode 100644 index 4a3a3a88c..000000000 --- a/src/Microsoft.Extensions.DependencyModel/ReferenceAssemblyPathResolver.cs +++ /dev/null @@ -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 _defaultReferenceAssembliesPath = new Lazy(GetDefaultReferenceAssembliesPath); - private static readonly Lazy _fallbackSearchPaths = new Lazy(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; - } - } -} \ No newline at end of file diff --git a/src/Microsoft.Extensions.DependencyModel/Resolution/AppBaseCompilationAssemblyResolver.cs b/src/Microsoft.Extensions.DependencyModel/Resolution/AppBaseCompilationAssemblyResolver.cs new file mode 100644 index 000000000..0e9c4acac --- /dev/null +++ b/src/Microsoft.Extensions.DependencyModel/Resolution/AppBaseCompilationAssemblyResolver.cs @@ -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 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() + { + _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; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.DependencyModel/Resolution/CompositeCompilationAssemblyResolver.cs b/src/Microsoft.Extensions.DependencyModel/Resolution/CompositeCompilationAssemblyResolver.cs new file mode 100644 index 000000000..c6daf2bf7 --- /dev/null +++ b/src/Microsoft.Extensions.DependencyModel/Resolution/CompositeCompilationAssemblyResolver.cs @@ -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 assemblies) + { + foreach (var resolver in _resolvers) + { + if (resolver.TryResolveAssemblyPaths(library, assemblies)) + { + return true; + } + } + return false;; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.DependencyModel/Resolution/ICompilationAssemblyResolver.cs b/src/Microsoft.Extensions.DependencyModel/Resolution/ICompilationAssemblyResolver.cs new file mode 100644 index 000000000..b4eed2a57 --- /dev/null +++ b/src/Microsoft.Extensions.DependencyModel/Resolution/ICompilationAssemblyResolver.cs @@ -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 assemblies); + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.DependencyModel/Resolution/PackageCacheCompilationAssemblyResolver.cs b/src/Microsoft.Extensions.DependencyModel/Resolution/PackageCacheCompilationAssemblyResolver.cs new file mode 100644 index 000000000..34adb116a --- /dev/null +++ b/src/Microsoft.Extensions.DependencyModel/Resolution/PackageCacheCompilationAssemblyResolver.cs @@ -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 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"); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.DependencyModel/Resolution/PackageCompilationAssemblyResolver.cs b/src/Microsoft.Extensions.DependencyModel/Resolution/PackageCompilationAssemblyResolver.cs new file mode 100644 index 000000000..4f4928473 --- /dev/null +++ b/src/Microsoft.Extensions.DependencyModel/Resolution/PackageCompilationAssemblyResolver.cs @@ -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 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; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.DependencyModel/Resolution/ReferenceAssemblyPathResolver.cs b/src/Microsoft.Extensions.DependencyModel/Resolution/ReferenceAssemblyPathResolver.cs new file mode 100644 index 000000000..53a36abdb --- /dev/null +++ b/src/Microsoft.Extensions.DependencyModel/Resolution/ReferenceAssemblyPathResolver.cs @@ -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 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"); + } + + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.DependencyModel/Resolution/ResolverUtils.cs b/src/Microsoft.Extensions.DependencyModel/Resolution/ResolverUtils.cs new file mode 100644 index 000000000..bfcf7f44f --- /dev/null +++ b/src/Microsoft.Extensions.DependencyModel/Resolution/ResolverUtils.cs @@ -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 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; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.DependencyModel/project.json b/src/Microsoft.Extensions.DependencyModel/project.json index 01e65852d..b64b34476 100644 --- a/src/Microsoft.Extensions.DependencyModel/project.json +++ b/src/Microsoft.Extensions.DependencyModel/project.json @@ -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" }, diff --git a/test/Microsoft.DotNet.Tools.Tests.Utilities/Mock/EnvironmentMockBuilder.cs b/test/Microsoft.DotNet.Tools.Tests.Utilities/Mock/EnvironmentMockBuilder.cs new file mode 100644 index 000000000..f8e4a82d5 --- /dev/null +++ b/test/Microsoft.DotNet.Tools.Tests.Utilities/Mock/EnvironmentMockBuilder.cs @@ -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 _variables = new Dictionary(); + + 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 _variables; + + public EnvironmentMock(Dictionary variables) + { + _variables = variables; + } + + public string GetEnvironmentVariable(string name) + { + string value = null; + _variables.TryGetValue(name, out value); + return value; + } + } + } +} diff --git a/test/Microsoft.DotNet.Tools.Tests.Utilities/Mock/FileSystemMockBuilder.cs b/test/Microsoft.DotNet.Tools.Tests.Utilities/Mock/FileSystemMockBuilder.cs new file mode 100644 index 000000000..40ac2aa37 --- /dev/null +++ b/test/Microsoft.DotNet.Tools.Tests.Utilities/Mock/FileSystemMockBuilder.cs @@ -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 _files = new Dictionary(); + + 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 files) + { + File = new FileMock(files); + Directory = new DirectoryMock(files); + } + + public IFile File { get; } + + public IDirectory Directory { get; } + } + + private class FileMock : IFile + { + private Dictionary _files; + public FileMock(Dictionary 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 _files; + public DirectoryMock(Dictionary files) + { + _files = files; + } + + public bool Exists(string path) + { + return _files.Keys.Any(k => k.StartsWith(path)); + } + } + } + +} diff --git a/test/Microsoft.DotNet.Tools.Tests.Utilities/Properties/Properties.cs b/test/Microsoft.DotNet.Tools.Tests.Utilities/Properties/Properties.cs new file mode 100644 index 000000000..50d5790b3 --- /dev/null +++ b/test/Microsoft.DotNet.Tools.Tests.Utilities/Properties/Properties.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Microsoft.Extensions.DependencyModel.Tests , PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] \ No newline at end of file diff --git a/test/Microsoft.DotNet.Tools.Tests.Utilities/project.json b/test/Microsoft.DotNet.Tools.Tests.Utilities/project.json index 804214a35..a881e8521 100644 --- a/test/Microsoft.DotNet.Tools.Tests.Utilities/project.json +++ b/test/Microsoft.DotNet.Tools.Tests.Utilities/project.json @@ -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-*" + } }, diff --git a/test/Microsoft.Extensions.DependencyModel.Tests/AppBaseResolverTests.cs b/test/Microsoft.Extensions.DependencyModel.Tests/AppBaseResolverTests.cs new file mode 100644 index 000000000..66f1d6c52 --- /dev/null +++ b/test/Microsoft.Extensions.DependencyModel.Tests/AppBaseResolverTests.cs @@ -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(); + + var exception = Assert.Throws(() => 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(); + + 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(); + + 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(); + + 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(); + + var result = resolver.TryResolveAssemblyPaths(library, assemblies); + + Assert.True(result); + assemblies.Should().HaveCount(1); + assemblies.Should().Contain(Path.Combine(BasePathRefs, TestLibraryFactory.DefaultAssembly)); + } + + + } +} diff --git a/test/Microsoft.Extensions.DependencyModel.Tests/CompositeResolverTests.cs b/test/Microsoft.Extensions.DependencyModel.Tests/CompositeResolverTests.cs new file mode 100644 index 000000000..f1894aceb --- /dev/null +++ b/test/Microsoft.Extensions.DependencyModel.Tests/CompositeResolverTests.cs @@ -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(); + var success = new Mock(); + success.Setup(r => r.TryResolveAssemblyPaths(It.IsAny(), It.IsAny>())) + .Returns(true); + + var failTwo = new Mock(); + + 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(), It.IsAny>()), + Times.Once()); + success.Verify(r => r.TryResolveAssemblyPaths(It.IsAny(), It.IsAny>()), + Times.Once()); + failTwo.Verify(r => r.TryResolveAssemblyPaths(It.IsAny(), It.IsAny>()), + Times.Never()); + } + + [Fact] + public void PassesLibraryToAllResolvers() + { + var fail = new Mock(); + var failTwo = new Mock(); + 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(); + var success = new Mock(); + success.Setup(r => r.TryResolveAssemblyPaths(It.IsAny(), It.IsAny>())) + .Returns(true) + .Callback((CompilationLibrary l, List a) => + { + a.Add("Assembly"); + }); + + var resolvers = new[] + { + fail.Object, + success.Object + }; + + var assemblies = new List(); + 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"); + } + } +} diff --git a/test/Microsoft.Extensions.DependencyModel.Tests/EnvironmentMockBuilder.cs b/test/Microsoft.Extensions.DependencyModel.Tests/EnvironmentMockBuilder.cs new file mode 100644 index 000000000..55e55065c --- /dev/null +++ b/test/Microsoft.Extensions.DependencyModel.Tests/EnvironmentMockBuilder.cs @@ -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 _variables = new Dictionary(); + + 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 _variables; + + public EnvironmentMock(Dictionary variables) + { + _variables = variables; + } + + public string GetEnvironmentVariable(string name) + { + string value = null; + _variables.TryGetValue(name, out value); + return value; + } + } + } +} diff --git a/test/Microsoft.Extensions.DependencyModel.Tests/FileSystemMockBuilder.cs b/test/Microsoft.Extensions.DependencyModel.Tests/FileSystemMockBuilder.cs new file mode 100644 index 000000000..48886c69e --- /dev/null +++ b/test/Microsoft.Extensions.DependencyModel.Tests/FileSystemMockBuilder.cs @@ -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 _files = new Dictionary(); + + 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 files) + { + File = new FileMock(files); + Directory = new DirectoryMock(files); + } + + public IFile File { get; } + + public IDirectory Directory { get; } + } + + private class FileMock : IFile + { + private Dictionary _files; + public FileMock(Dictionary 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 _files; + public DirectoryMock(Dictionary files) + { + _files = files; + } + + public bool Exists(string path) + { + return _files.Keys.Any(k => k.StartsWith(path)); + } + } + } + +} diff --git a/test/Microsoft.Extensions.DependencyModel.Tests/Microsoft.Extensions.DependencyModel.Tests.xproj b/test/Microsoft.Extensions.DependencyModel.Tests/Microsoft.Extensions.DependencyModel.Tests.xproj new file mode 100644 index 000000000..280b6d48d --- /dev/null +++ b/test/Microsoft.Extensions.DependencyModel.Tests/Microsoft.Extensions.DependencyModel.Tests.xproj @@ -0,0 +1,19 @@ + + + + 14.0.23107 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 4a4711d8-4312-49fc-87b5-4f183f4c6a51 + Microsoft.Extensions.DependencyModel.Tests + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ + + + + 2.0 + + + \ No newline at end of file diff --git a/test/Microsoft.Extensions.DependencyModel.Tests/PackageCacheResolverTest.cs b/test/Microsoft.Extensions.DependencyModel.Tests/PackageCacheResolverTest.cs new file mode 100644 index 000000000..c6355eca4 --- /dev/null +++ b/test/Microsoft.Extensions.DependencyModel.Tests/PackageCacheResolverTest.cs @@ -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(() => 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(); + + 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(); + + 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(); + + var exception = Assert.Throws(() => 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(); + } + + + } +} diff --git a/test/Microsoft.Extensions.DependencyModel.Tests/PackageResolverTest.cs b/test/Microsoft.Extensions.DependencyModel.Tests/PackageResolverTest.cs new file mode 100644 index 000000000..35869d7fc --- /dev/null +++ b/test/Microsoft.Extensions.DependencyModel.Tests/PackageResolverTest.cs @@ -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(); + + 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(); + 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(); + 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(); + + 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(); + + var exception = Assert.Throws(() => resolver.TryResolveAssemblyPaths(library, assemblies)); + exception.Message.Should() + .Contain(F.SecondAssemblyPath) + .And.Contain(library.PackageName); + } + } +} diff --git a/test/Microsoft.Extensions.DependencyModel.Tests/ReferenceAssemblyResolverTests.cs b/test/Microsoft.Extensions.DependencyModel.Tests/ReferenceAssemblyResolverTests.cs new file mode 100644 index 000000000..9af3e0abf --- /dev/null +++ b/test/Microsoft.Extensions.DependencyModel.Tests/ReferenceAssemblyResolverTests.cs @@ -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(); + 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(); + 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(); + 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(); + 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(); + 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(); + + 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(); + + 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(); + + var resolver = new ReferenceAssemblyPathResolver(fileSystem, null, new string[] { ReferencePath }); + + var exception = Assert.Throws(() => resolver.TryResolveAssemblyPaths(library, assemblies)); + + exception.Message.Should() + .Contain(F.SecondAssemblyPath) + .And.Contain(library.PackageName); + } + } +} diff --git a/test/Microsoft.Extensions.DependencyModel.Tests/TestLibraryFactory.cs b/test/Microsoft.Extensions.DependencyModel.Tests/TestLibraryFactory.cs new file mode 100644 index 000000000..9e81d4bc1 --- /dev/null +++ b/test/Microsoft.Extensions.DependencyModel.Tests/TestLibraryFactory.cs @@ -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 + ); + } + } + +} diff --git a/test/Microsoft.Extensions.DependencyModel.Tests/project.json b/test/Microsoft.Extensions.DependencyModel.Tests/project.json new file mode 100644 index 000000000..1aa2f6ff9 --- /dev/null +++ b/test/Microsoft.Extensions.DependencyModel.Tests/project.json @@ -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" +} \ No newline at end of file