diff --git a/src/Workspaces/Core/MSBuild/MSBuild/MSBuildProjectLoader.Worker.cs b/src/Workspaces/Core/MSBuild/MSBuild/MSBuildProjectLoader.Worker.cs index ff2e71fa7c14ff7cb7dec6a071ac22a58cad15d2..a3dc82221b01f8fa2dabe893a98e4414868b47ae 100644 --- a/src/Workspaces/Core/MSBuild/MSBuild/MSBuildProjectLoader.Worker.cs +++ b/src/Workspaces/Core/MSBuild/MSBuild/MSBuildProjectLoader.Worker.cs @@ -224,7 +224,8 @@ private async Task> LoadProjectFileInfosAsync(st private async Task> LoadProjectInfosFromPathAsync( string projectPath, DiagnosticReportingOptions reportingOptions, CancellationToken cancellationToken) { - if (_projectMap.TryGetProjectInfosByProjectPath(projectPath, out var results)) + if (_projectMap.TryGetProjectInfosByProjectPath(projectPath, out var results) || + _pathToDiscoveredProjectInfosMap.TryGetValue(projectPath, out results)) { return results; } diff --git a/src/Workspaces/CoreTestUtilities/DotNetCoreSdk.cs b/src/Workspaces/CoreTestUtilities/DotNetCoreSdk.cs new file mode 100644 index 0000000000000000000000000000000000000000..a30c2f53ada9f62d664310a602c1d6291d2b7233 --- /dev/null +++ b/src/Workspaces/CoreTestUtilities/DotNetCoreSdk.cs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.IO; +using System.Linq; +using Roslyn.Test.Utilities; + +namespace Microsoft.CodeAnalysis.UnitTests +{ + public static class DotNetCoreSdk + { + public sealed class IsAvailable : ExecutionCondition + { + public override bool ShouldSkip + => ExePath == null; + public override string SkipReason + => "The location of dotnet SDK can't be determined (DOTNET_INSTALL_DIR environment variable is unset)"; + } + + public static string ExePath { get; } + + static DotNetCoreSdk() + { + var dotNetExeName = "dotnet" + (Path.DirectorySeparatorChar == '/' ? "" : ".exe"); + + bool DotNetExeExists(string directory) + => directory != null + && File.Exists(Path.Combine(directory, dotNetExeName)); + + var dotNetInstallDir = Environment.GetEnvironmentVariable("DOTNET_INSTALL_DIR"); + if (!DotNetExeExists(dotNetInstallDir)) + { + dotNetInstallDir = Environment.GetEnvironmentVariable("PATH") + .Split(Path.PathSeparator) + .FirstOrDefault(DotNetExeExists); + } + + if (dotNetInstallDir != null) + { + ExePath = Path.Combine(dotNetInstallDir, dotNetExeName); + } + } + } +} diff --git a/src/Workspaces/CoreTestUtilities/DotNetHelper.cs b/src/Workspaces/CoreTestUtilities/DotNetHelper.cs deleted file mode 100644 index 9c59912ed6a93dfe64dc38e127798d8156649475..0000000000000000000000000000000000000000 --- a/src/Workspaces/CoreTestUtilities/DotNetHelper.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Diagnostics; -using System.Text; - -namespace Microsoft.CodeAnalysis.UnitTests -{ - public static class DotNetHelper - { - private static string RunProcess(string fileName, string arguments, string workingDirectory = null) - { - var process = new Process - { - StartInfo = new ProcessStartInfo(fileName, arguments) - { - RedirectStandardError = true, - RedirectStandardOutput = true, - CreateNoWindow = true, - UseShellExecute = false, - WorkingDirectory = workingDirectory ?? string.Empty - } - }; - - var output = new StringBuilder(); - - process.OutputDataReceived += (_, e) => output.AppendLine(e.Data); - process.ErrorDataReceived += (_, e) => output.AppendLine(e.Data); - - process.Start(); - - process.WaitForExit(); - - return output.ToString(); - } - - public static string Restore(string solutionOrProjectFileName, string workingDirectory = null) - { - return RunProcess("dotnet", $"restore {solutionOrProjectFileName}", workingDirectory); - } - } -} diff --git a/src/Workspaces/CoreTestUtilities/Resources/NetCoreMultiTFM_ProjectReferenceToFSharp/Solution.sln b/src/Workspaces/CoreTestUtilities/Resources/NetCoreMultiTFM_ProjectReferenceToFSharp/Solution.sln new file mode 100644 index 0000000000000000000000000000000000000000..80c8b739e750d4c06e33b758b2c433f57c203126 --- /dev/null +++ b/src/Workspaces/CoreTestUtilities/Resources/NetCoreMultiTFM_ProjectReferenceToFSharp/Solution.sln @@ -0,0 +1,48 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26124.0 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "fsharplib", "fsharplib\fsharplib.fsproj", "{B023B477-7783-490C-A1C2-549D1A87116C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "csharplib", "csharplib\csharplib.csproj", "{9E50A9D1-E6DB-4CE5-9F86-40ACB3CBF3BF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9E50A9D1-E6DB-4CE5-9F86-40ACB3CBF3BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9E50A9D1-E6DB-4CE5-9F86-40ACB3CBF3BF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9E50A9D1-E6DB-4CE5-9F86-40ACB3CBF3BF}.Debug|x64.ActiveCfg = Debug|Any CPU + {9E50A9D1-E6DB-4CE5-9F86-40ACB3CBF3BF}.Debug|x64.Build.0 = Debug|Any CPU + {9E50A9D1-E6DB-4CE5-9F86-40ACB3CBF3BF}.Debug|x86.ActiveCfg = Debug|Any CPU + {9E50A9D1-E6DB-4CE5-9F86-40ACB3CBF3BF}.Debug|x86.Build.0 = Debug|Any CPU + {9E50A9D1-E6DB-4CE5-9F86-40ACB3CBF3BF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9E50A9D1-E6DB-4CE5-9F86-40ACB3CBF3BF}.Release|Any CPU.Build.0 = Release|Any CPU + {9E50A9D1-E6DB-4CE5-9F86-40ACB3CBF3BF}.Release|x64.ActiveCfg = Release|Any CPU + {9E50A9D1-E6DB-4CE5-9F86-40ACB3CBF3BF}.Release|x64.Build.0 = Release|Any CPU + {9E50A9D1-E6DB-4CE5-9F86-40ACB3CBF3BF}.Release|x86.ActiveCfg = Release|Any CPU + {9E50A9D1-E6DB-4CE5-9F86-40ACB3CBF3BF}.Release|x86.Build.0 = Release|Any CPU + {B023B477-7783-490C-A1C2-549D1A87116C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B023B477-7783-490C-A1C2-549D1A87116C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B023B477-7783-490C-A1C2-549D1A87116C}.Debug|x64.ActiveCfg = Debug|Any CPU + {B023B477-7783-490C-A1C2-549D1A87116C}.Debug|x64.Build.0 = Debug|Any CPU + {B023B477-7783-490C-A1C2-549D1A87116C}.Debug|x86.ActiveCfg = Debug|Any CPU + {B023B477-7783-490C-A1C2-549D1A87116C}.Debug|x86.Build.0 = Debug|Any CPU + {B023B477-7783-490C-A1C2-549D1A87116C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B023B477-7783-490C-A1C2-549D1A87116C}.Release|Any CPU.Build.0 = Release|Any CPU + {B023B477-7783-490C-A1C2-549D1A87116C}.Release|x64.ActiveCfg = Release|Any CPU + {B023B477-7783-490C-A1C2-549D1A87116C}.Release|x64.Build.0 = Release|Any CPU + {B023B477-7783-490C-A1C2-549D1A87116C}.Release|x86.ActiveCfg = Release|Any CPU + {B023B477-7783-490C-A1C2-549D1A87116C}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/src/Workspaces/CoreTestUtilities/Resources/NetCoreMultiTFM_ProjectReferenceToFSharp/csharplib/Class1.cs b/src/Workspaces/CoreTestUtilities/Resources/NetCoreMultiTFM_ProjectReferenceToFSharp/csharplib/Class1.cs new file mode 100644 index 0000000000000000000000000000000000000000..c26b268e10105bc8dd20993b07c0ae556f276e53 --- /dev/null +++ b/src/Workspaces/CoreTestUtilities/Resources/NetCoreMultiTFM_ProjectReferenceToFSharp/csharplib/Class1.cs @@ -0,0 +1,8 @@ +using System; + +namespace csharplib +{ + public class Class1 + { + } +} diff --git a/src/Workspaces/CoreTestUtilities/Resources/NetCoreMultiTFM_ProjectReferenceToFSharp/csharplib/csharplib.csproj b/src/Workspaces/CoreTestUtilities/Resources/NetCoreMultiTFM_ProjectReferenceToFSharp/csharplib/csharplib.csproj new file mode 100644 index 0000000000000000000000000000000000000000..70767c971b4781fe2819e6a4e5e1b38c5ee77261 --- /dev/null +++ b/src/Workspaces/CoreTestUtilities/Resources/NetCoreMultiTFM_ProjectReferenceToFSharp/csharplib/csharplib.csproj @@ -0,0 +1,11 @@ + + + + netstandard2.0;netcoreapp2.0 + + + + + + + diff --git a/src/Workspaces/CoreTestUtilities/Resources/NetCoreMultiTFM_ProjectReferenceToFSharp/fsharplib/Library.fs b/src/Workspaces/CoreTestUtilities/Resources/NetCoreMultiTFM_ProjectReferenceToFSharp/fsharplib/Library.fs new file mode 100644 index 0000000000000000000000000000000000000000..0b741d56de263b30bb77ba1e8bcd486453d6e4d6 --- /dev/null +++ b/src/Workspaces/CoreTestUtilities/Resources/NetCoreMultiTFM_ProjectReferenceToFSharp/fsharplib/Library.fs @@ -0,0 +1,5 @@ +namespace fsharplib + +module Say = + let hello name = + printfn "Hello %s" name diff --git a/src/Workspaces/CoreTestUtilities/Resources/NetCoreMultiTFM_ProjectReferenceToFSharp/fsharplib/fsharplib.fsproj b/src/Workspaces/CoreTestUtilities/Resources/NetCoreMultiTFM_ProjectReferenceToFSharp/fsharplib/fsharplib.fsproj new file mode 100644 index 0000000000000000000000000000000000000000..df4543225fb42b691a5fd823e2ecd695532d1a4d --- /dev/null +++ b/src/Workspaces/CoreTestUtilities/Resources/NetCoreMultiTFM_ProjectReferenceToFSharp/fsharplib/fsharplib.fsproj @@ -0,0 +1,11 @@ + + + + netstandard2.0 + + + + + + + diff --git a/src/Workspaces/CoreTestUtilities/TestFiles/Resources.cs b/src/Workspaces/CoreTestUtilities/TestFiles/Resources.cs index 800eff19cdefd6d7035a01777abb55ac82865abe..ed527b646639af338955594a31d2f4ac5301af77 100644 --- a/src/Workspaces/CoreTestUtilities/TestFiles/Resources.cs +++ b/src/Workspaces/CoreTestUtilities/TestFiles/Resources.cs @@ -70,6 +70,7 @@ private static TResult GetOrLoadValue(string name, Func GetText("Directory.Build.props"); public static string Directory_Build_targets => GetText("Directory.Build.targets"); public static byte[] Key_snk => GetBytes("key.snk"); + public static string NuGet_Config => GetText("NuGet.Config"); public static class SolutionFiles { @@ -89,6 +90,7 @@ public static class SolutionFiles public static string MissingEndProject1 => GetText("SolutionFiles.MissingEndProject1.sln"); public static string MissingEndProject2 => GetText("SolutionFiles.MissingEndProject2.sln"); public static string MissingEndProject3 => GetText("SolutionFiles.MissingEndProject3.sln"); + public static string NetCoreMultiTFM_ProjectReferenceToFSharp = GetText("NetCoreMultiTFM_ProjectReferenceToFSharp.Solution.sln"); public static string NonExistentProject => GetText("SolutionFiles.NonExistentProject.sln"); public static string SolutionFolder => GetText("SolutionFiles.SolutionFolder.sln"); public static string VB_and_CSharp => GetText("SolutionFiles.VB_and_CSharp.sln"); @@ -131,6 +133,7 @@ public static class CSharp public static string NetCoreMultiTFM_Project => GetText("NetCoreMultiTFM.Project.csproj"); public static string NetCoreMultiTFM_ProjectReference_Library => GetText("NetCoreMultiTFM_ProjectReference.Library.csproj"); public static string NetCoreMultiTFM_ProjectReference_Project => GetText("NetCoreMultiTFM_ProjectReference.Project.csproj"); + public static string NetCoreMultiTFM_ProjectReferenceToFSharp_CSharpLib = GetText("NetCoreMultiTFM_ProjectReferenceToFSharp.csharplib.csharplib.csproj"); public static string NetCoreMultiTFM_ProjectReferenceWithReversedTFMs_Library => GetText("NetCoreMultiTFM_ProjectReferenceWithReversedTFMs.Library.csproj"); public static string NetCoreMultiTFM_ProjectReferenceWithReversedTFMs_Project => GetText("NetCoreMultiTFM_ProjectReferenceWithReversedTFMs.Project.csproj"); public static string PortableProject => GetText("ProjectFiles.CSharp.PortableProject.csproj"); @@ -145,6 +148,11 @@ public static class CSharp public static string WithoutPrefer32Bit => GetText("ProjectFiles.CSharp.WithoutPrefer32Bit.csproj"); } + public static class FSharp + { + public static string NetCoreMultiTFM_ProjectReferenceToFSharp_FSharpLib = GetText("NetCoreMultiTFM_ProjectReferenceToFSharp.fsharplib.fsharplib.fsproj"); + } + public static class VisualBasic { public static string AnalyzerReference => GetText("ProjectFiles.VisualBasic.AnalyzerReference.vbproj"); @@ -181,12 +189,18 @@ public static class CSharp public static string NetCoreMultiTFM_Program => GetText("NetCoreMultiTFM.Program.cs"); public static string NetCoreMultiTFM_ProjectReference_Class1 => GetText("NetCoreMultiTFM_ProjectReference.Class1.cs"); public static string NetCoreMultiTFM_ProjectReference_Program => GetText("NetCoreMultiTFM_ProjectReference.Program.cs"); + public static string NetCoreMultiTFM_ProjectReferenceToFSharp_CSharpLib_Class1 = GetText("NetCoreMultiTFM_ProjectReferenceToFSharp.csharplib.Class1.cs"); public static string NetCoreMultiTFM_ProjectReferenceWithReversedTFMs_Class1 => GetText("NetCoreMultiTFM_ProjectReferenceWithReversedTFMs.Class1.cs"); public static string NetCoreMultiTFM_ProjectReferenceWithReversedTFMs_Program => GetText("NetCoreMultiTFM_ProjectReferenceWithReversedTFMs.Program.cs"); public static string MainWindow => GetText("SourceFiles.CSharp.MainWindow.xaml.cs"); public static string OtherStuff_Foo => GetText("SourceFiles.CSharp.OtherStuff_Foo.cs"); } + public static class FSharp + { + public static string NetCoreMultiTFM_ProjectReferenceToFSharp_FSharpLib_Library = GetText("NetCoreMultiTFM_ProjectReferenceToFSharp.fsharplib.Library.fs"); + } + public static class VisualBasic { public static string Application => GetText("SourceFiles.VisualBasic.Application.myapp"); diff --git a/src/Workspaces/CoreTestUtilities/WorkspaceTestBase.cs b/src/Workspaces/CoreTestUtilities/WorkspaceTestBase.cs index 4c75c97a8d30aba3fbb285955b41f66c633561d3..168d3bc45a4a651032889d0d27b28ac9f7050ded 100644 --- a/src/Workspaces/CoreTestUtilities/WorkspaceTestBase.cs +++ b/src/Workspaces/CoreTestUtilities/WorkspaceTestBase.cs @@ -90,6 +90,7 @@ protected void CreateCSharpFiles() protected FileSet GetSimpleCSharpSolutionFiles() { return new FileSet( + (@"NuGet.Config", Resources.NuGet_Config), (@"Directory.Build.props", Resources.Directory_Build_props), (@"Directory.Build.targets", Resources.Directory_Build_targets), (@"TestSolution.sln", Resources.SolutionFiles.CSharp), @@ -101,6 +102,7 @@ protected FileSet GetSimpleCSharpSolutionFiles() protected FileSet GetNetCoreApp2Files() { return new FileSet( + (@"NuGet.Config", Resources.NuGet_Config), (@"Directory.Build.props", Resources.Directory_Build_props), (@"Directory.Build.targets", Resources.Directory_Build_targets), (@"Project.csproj", Resources.ProjectFiles.CSharp.NetCoreApp2_Project), @@ -110,6 +112,7 @@ protected FileSet GetNetCoreApp2Files() protected FileSet GetNetCoreApp2AndLibraryFiles() { return new FileSet( + (@"NuGet.Config", Resources.NuGet_Config), (@"Directory.Build.props", Resources.Directory_Build_props), (@"Directory.Build.targets", Resources.Directory_Build_targets), (@"Project\Project.csproj", Resources.ProjectFiles.CSharp.NetCoreApp2AndLibrary_Project), @@ -121,6 +124,7 @@ protected FileSet GetNetCoreApp2AndLibraryFiles() protected FileSet GetNetCoreApp2AndTwoLibrariesFiles() { return new FileSet( + (@"NuGet.Config", Resources.NuGet_Config), (@"Directory.Build.props", Resources.Directory_Build_props), (@"Directory.Build.targets", Resources.Directory_Build_targets), (@"Project\Project.csproj", Resources.ProjectFiles.CSharp.NetCoreApp2AndTwoLibraries_Project), @@ -134,6 +138,7 @@ protected FileSet GetNetCoreApp2AndTwoLibrariesFiles() protected FileSet GetNetCoreMultiTFMFiles() { return new FileSet( + (@"NuGet.Config", Resources.NuGet_Config), (@"Directory.Build.props", Resources.Directory_Build_props), (@"Directory.Build.targets", Resources.Directory_Build_targets), (@"Project.csproj", Resources.ProjectFiles.CSharp.NetCoreMultiTFM_Project), @@ -143,6 +148,7 @@ protected FileSet GetNetCoreMultiTFMFiles() protected FileSet GetNetCoreMultiTFMFiles_ProjectReference() { return new FileSet( + (@"NuGet.Config", Resources.NuGet_Config), (@"Directory.Build.props", Resources.Directory_Build_props), (@"Directory.Build.targets", Resources.Directory_Build_targets), (@"Project\Project.csproj", Resources.ProjectFiles.CSharp.NetCoreMultiTFM_ProjectReference_Project), @@ -154,6 +160,7 @@ protected FileSet GetNetCoreMultiTFMFiles_ProjectReference() protected FileSet GetNetCoreMultiTFMFiles_ProjectReferenceWithReversedTFMs() { return new FileSet( + (@"NuGet.Config", Resources.NuGet_Config), (@"Directory.Build.props", Resources.Directory_Build_props), (@"Directory.Build.targets", Resources.Directory_Build_targets), (@"Project\Project.csproj", Resources.ProjectFiles.CSharp.NetCoreMultiTFM_ProjectReferenceWithReversedTFMs_Project), @@ -162,9 +169,23 @@ protected FileSet GetNetCoreMultiTFMFiles_ProjectReferenceWithReversedTFMs() (@"Library\Class1.cs", Resources.SourceFiles.CSharp.NetCoreMultiTFM_ProjectReferenceWithReversedTFMs_Class1)); } + protected FileSet GetNetCoreMultiTFMFiles_ProjectReferenceToFSharp() + { + return new FileSet( + (@"NuGet.Config", Resources.NuGet_Config), + (@"Directory.Build.props", Resources.Directory_Build_props), + (@"Directory.Build.targets", Resources.Directory_Build_targets), + (@"Solution.sln", Resources.SolutionFiles.NetCoreMultiTFM_ProjectReferenceToFSharp), + (@"csharplib\csharplib.csproj", Resources.ProjectFiles.CSharp.NetCoreMultiTFM_ProjectReferenceToFSharp_CSharpLib), + (@"csharplib\Class1.cs", Resources.SourceFiles.CSharp.NetCoreMultiTFM_ProjectReferenceToFSharp_CSharpLib_Class1), + (@"fsharplib\fsharplib.fsproj", Resources.ProjectFiles.FSharp.NetCoreMultiTFM_ProjectReferenceToFSharp_FSharpLib), + (@"fsharplib\Library.fs", Resources.SourceFiles.FSharp.NetCoreMultiTFM_ProjectReferenceToFSharp_FSharpLib_Library)); + } + protected FileSet GetMultiProjectSolutionFiles() { return new FileSet( + (@"NuGet.Config", Resources.NuGet_Config), (@"Directory.Build.props", Resources.Directory_Build_props), (@"Directory.Build.targets", Resources.Directory_Build_targets), (@"TestSolution.sln", Resources.SolutionFiles.VB_and_CSharp), @@ -185,6 +206,7 @@ protected FileSet GetMultiProjectSolutionFiles() protected FileSet GetProjectReferenceSolutionFiles() { return new FileSet( + (@"NuGet.Config", Resources.NuGet_Config), (@"Directory.Build.props", Resources.Directory_Build_props), (@"Directory.Build.targets", Resources.Directory_Build_targets), (@"CSharpProjectReference.sln", Resources.SolutionFiles.CSharp_ProjectReference), @@ -198,6 +220,7 @@ protected FileSet GetProjectReferenceSolutionFiles() protected FileSet GetAnalyzerReferenceSolutionFiles() { return new FileSet( + (@"NuGet.Config", Resources.NuGet_Config), (@"Directory.Build.props", Resources.Directory_Build_props), (@"Directory.Build.targets", Resources.Directory_Build_targets), (@"AnalyzerReference.sln", Resources.SolutionFiles.AnalyzerReference), @@ -219,6 +242,7 @@ protected FileSet GetAnalyzerReferenceSolutionFiles() protected FileSet GetSolutionWithDuplicatedGuidFiles() { return new FileSet( + (@"NuGet.Config", Resources.NuGet_Config), (@"Directory.Build.props", Resources.Directory_Build_props), (@"Directory.Build.targets", Resources.Directory_Build_targets), (@"DuplicatedGuids.sln", Resources.SolutionFiles.DuplicatedGuids), @@ -230,6 +254,7 @@ protected FileSet GetSolutionWithDuplicatedGuidFiles() protected FileSet GetSolutionWithCircularProjectReferences() { return new FileSet( + (@"NuGet.Config", Resources.NuGet_Config), (@"Directory.Build.props", Resources.Directory_Build_props), (@"Directory.Build.targets", Resources.Directory_Build_targets), (@"CircularSolution.sln", Resources.SolutionFiles.CircularSolution), diff --git a/src/Workspaces/MSBuildTest/NetCoreTests.cs b/src/Workspaces/MSBuildTest/NetCoreTests.cs index 87801d05f35ef8f9d78a184554ef0d946d4c3911..62805e03af9ae95f9eaf8613edfcbf5859780c3f 100644 --- a/src/Workspaces/MSBuildTest/NetCoreTests.cs +++ b/src/Workspaces/MSBuildTest/NetCoreTests.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Test.Utilities; @@ -14,7 +15,32 @@ namespace Microsoft.CodeAnalysis.MSBuild.UnitTests { public class NetCoreTests : MSBuildWorkspaceTestBase { - [ConditionalFact(typeof(VisualStudioMSBuildInstalled))] + private readonly TempDirectory _nugetCacheDir; + + public NetCoreTests() + { + _nugetCacheDir = SolutionDirectory.CreateDirectory(".packages"); + } + + private void DotNetRestore(string solutionOrProjectFileName) + { + Assert.NotNull(DotNetCoreSdk.ExePath); + + var environmentVariables = new Dictionary() + { + ["NUGET_PACKAGES"] = _nugetCacheDir.Path + }; + + var restoreResult = ProcessUtilities.Run( + fileName: DotNetCoreSdk.ExePath, + arguments: $@"msbuild ""{solutionOrProjectFileName}"" /t:restore /bl:{Path.Combine(SolutionDirectory.Path, "restore.binlog")}", + workingDirectory: SolutionDirectory.Path, + additionalEnvironmentVars: environmentVariables); + + Assert.True(restoreResult.ExitCode == 0, $"Restore failed with exit code {restoreResult.ExitCode}: {restoreResult.Output}"); + } + + [ConditionalFact(typeof(VisualStudioMSBuildInstalled), typeof(DotNetCoreSdk.IsAvailable))] [Trait(Traits.Feature, Traits.Features.MSBuildWorkspace)] [Trait(Traits.Feature, Traits.Features.NetCore)] public async Task TestOpenProject_NetCoreApp2() @@ -23,7 +49,7 @@ public async Task TestOpenProject_NetCoreApp2() var projectFilePath = GetSolutionFileName("Project.csproj"); - DotNetHelper.Restore("Project.csproj", workingDirectory: this.SolutionDirectory.Path); + DotNetRestore("Project.csproj"); using (var workspace = CreateMSBuildWorkspace()) { @@ -40,7 +66,7 @@ public async Task TestOpenProject_NetCoreApp2() } } - [ConditionalFact(typeof(VisualStudioMSBuildInstalled))] + [ConditionalFact(typeof(VisualStudioMSBuildInstalled), typeof(DotNetCoreSdk.IsAvailable))] [Trait(Traits.Feature, Traits.Features.MSBuildWorkspace)] [Trait(Traits.Feature, Traits.Features.NetCore)] public async Task TestOpenProjectTwice_NetCoreApp2AndLibrary() @@ -50,7 +76,7 @@ public async Task TestOpenProjectTwice_NetCoreApp2AndLibrary() var projectFilePath = GetSolutionFileName(@"Project\Project.csproj"); var libraryFilePath = GetSolutionFileName(@"Library\Library.csproj"); - DotNetHelper.Restore(@"Project\Project.csproj", workingDirectory: this.SolutionDirectory.Path); + DotNetRestore(@"Project\Project.csproj"); using (var workspace = CreateMSBuildWorkspace()) { @@ -79,7 +105,7 @@ public async Task TestOpenProjectTwice_NetCoreApp2AndLibrary() } } - [ConditionalFact(typeof(VisualStudioMSBuildInstalled))] + [ConditionalFact(typeof(VisualStudioMSBuildInstalled), typeof(DotNetCoreSdk.IsAvailable))] [Trait(Traits.Feature, Traits.Features.MSBuildWorkspace)] [Trait(Traits.Feature, Traits.Features.NetCore)] public async Task TestOpenProjectTwice_NetCoreApp2AndTwoLibraries() @@ -90,8 +116,8 @@ public async Task TestOpenProjectTwice_NetCoreApp2AndTwoLibraries() var library1FilePath = GetSolutionFileName(@"Library1\Library1.csproj"); var library2FilePath = GetSolutionFileName(@"Library2\Library2.csproj"); - DotNetHelper.Restore(@"Project\Project.csproj", workingDirectory: this.SolutionDirectory.Path); - DotNetHelper.Restore(@"Library2\Library2.csproj", workingDirectory: this.SolutionDirectory.Path); + DotNetRestore(@"Project\Project.csproj"); + DotNetRestore(@"Library2\Library2.csproj"); using (var workspace = CreateMSBuildWorkspace()) { @@ -127,7 +153,7 @@ void AssertSingleProjectReference(Project project, string projectRefFilePath) } } - [ConditionalFact(typeof(VisualStudioMSBuildInstalled), AlwaysSkip = "https://github.com/dotnet/roslyn/issues/28104")] + [ConditionalFact(typeof(VisualStudioMSBuildInstalled), typeof(DotNetCoreSdk.IsAvailable))] [Trait(Traits.Feature, Traits.Features.MSBuildWorkspace)] [Trait(Traits.Feature, Traits.Features.NetCore)] public async Task TestOpenProject_NetCoreMultiTFM() @@ -136,7 +162,7 @@ public async Task TestOpenProject_NetCoreMultiTFM() var projectFilePath = GetSolutionFileName("Project.csproj"); - DotNetHelper.Restore("Project.csproj", workingDirectory: this.SolutionDirectory.Path); + DotNetRestore("Project.csproj"); using (var workspace = CreateMSBuildWorkspace()) { @@ -171,7 +197,7 @@ public async Task TestOpenProject_NetCoreMultiTFM() } } - [ConditionalFact(typeof(VisualStudioMSBuildInstalled), AlwaysSkip = "https://github.com/dotnet/roslyn/issues/28104")] + [ConditionalFact(typeof(VisualStudioMSBuildInstalled), typeof(DotNetCoreSdk.IsAvailable))] [Trait(Traits.Feature, Traits.Features.MSBuildWorkspace)] [Trait(Traits.Feature, Traits.Features.NetCore)] public async Task TestOpenProject_NetCoreMultiTFM_ProjectReference() @@ -179,14 +205,14 @@ public async Task TestOpenProject_NetCoreMultiTFM_ProjectReference() CreateFiles(GetNetCoreMultiTFMFiles_ProjectReference()); // Restoring for Project.csproj should also restore Library.csproj - DotNetHelper.Restore(@"Project\Project.csproj", workingDirectory: this.SolutionDirectory.Path); + DotNetRestore(@"Project\Project.csproj"); var projectFilePath = GetSolutionFileName(@"Project\Project.csproj"); await AssertNetCoreMultiTFMProject(projectFilePath); } - [ConditionalFact(typeof(VisualStudioMSBuildInstalled), AlwaysSkip ="https://github.com/dotnet/roslyn/issues/28104")] + [ConditionalFact(typeof(VisualStudioMSBuildInstalled), typeof(DotNetCoreSdk.IsAvailable))] [Trait(Traits.Feature, Traits.Features.MSBuildWorkspace)] [Trait(Traits.Feature, Traits.Features.NetCore)] public async Task TestOpenProject_NetCoreMultiTFM_ProjectReferenceWithReversedTFMs() @@ -194,7 +220,7 @@ public async Task TestOpenProject_NetCoreMultiTFM_ProjectReferenceWithReversedTF CreateFiles(GetNetCoreMultiTFMFiles_ProjectReferenceWithReversedTFMs()); // Restoring for Project.csproj should also restore Library.csproj - DotNetHelper.Restore(@"Project\Project.csproj", workingDirectory: this.SolutionDirectory.Path); + DotNetRestore(@"Project\Project.csproj"); var projectFilePath = GetSolutionFileName(@"Project\Project.csproj"); @@ -227,9 +253,9 @@ private async Task AssertNetCoreMultiTFMProject(string projectFilePath) var expectedNames = new HashSet() { - "Library(netstandard2.0)", + "Library(netstandard2", "Library(net461)", - "Project(netcoreapp2.0)", + "Project(netcoreapp2", "Project(net461)" }; @@ -237,7 +263,12 @@ private async Task AssertNetCoreMultiTFMProject(string projectFilePath) foreach (var project in workspace.CurrentSolution.Projects) { - actualNames.Add(project.Name); + var dotIndex = project.Name.IndexOf('.'); + var projectName = dotIndex >= 0 + ? project.Name.Substring(0, dotIndex) + : project.Name; + + actualNames.Add(projectName); var fileName = PathUtilities.GetFileName(project.FilePath); Document document; @@ -263,7 +294,7 @@ private async Task AssertNetCoreMultiTFMProject(string projectFilePath) Assert.Empty(diagnostics); } - Assert.True(actualNames.SetEquals(expectedNames), $"Project names differ!{Environment.NewLine}Expected: {actualNames}{Environment.NewLine}Expected: {expectedNames}"); + Assert.True(actualNames.SetEquals(expectedNames), $"Project names differ!{Environment.NewLine}Actual: {{{actualNames.Join(",")}}}{Environment.NewLine}Expected: {{{expectedNames.Join(",")}}}"); // Verify that the projects reference the correct TFMs var projects = workspace.CurrentSolution.Projects.Where(p => p.FilePath.EndsWith("Project.csproj")); @@ -273,9 +304,9 @@ private async Task AssertNetCoreMultiTFMProject(string projectFilePath) var referencedProject = workspace.CurrentSolution.GetProject(projectReference.ProjectId); - if (project.OutputFilePath.Contains("netcoreapp2.0")) + if (project.OutputFilePath.Contains("netcoreapp2")) { - Assert.Contains("netstandard2.0", referencedProject.OutputFilePath); + Assert.Contains("netstandard2", referencedProject.OutputFilePath); } else if (project.OutputFilePath.Contains("net461")) { @@ -288,5 +319,33 @@ private async Task AssertNetCoreMultiTFMProject(string projectFilePath) } } } + + [ConditionalFact(typeof(VisualStudioMSBuildInstalled), typeof(DotNetCoreSdk.IsAvailable))] + [Trait(Traits.Feature, Traits.Features.MSBuildWorkspace)] + [Trait(Traits.Feature, Traits.Features.NetCore)] + public async Task TestOpenSolution_NetCoreMultiTFMWithProjectReferenceToFSharp() + { + CreateFiles(GetNetCoreMultiTFMFiles_ProjectReferenceToFSharp()); + + var solutionFilePath = GetSolutionFileName("Solution.sln"); + + DotNetRestore("Solution.sln"); + + using (var workspace = CreateMSBuildWorkspace()) + { + var solution = await workspace.OpenSolutionAsync(solutionFilePath); + + var projects = solution.Projects.ToArray(); + + Assert.Equal(2, projects.Length); + + foreach (var project in projects) + { + Assert.StartsWith("csharplib", project.Name); + Assert.Empty(project.ProjectReferences); + Assert.Single(project.AllProjectReferences); + } + } + } } } diff --git a/src/Workspaces/MSBuildTest/VisualStudioMSBuildInstalled.cs b/src/Workspaces/MSBuildTest/VisualStudioMSBuildInstalled.cs index 0da10767cf29e1de3134b935dd76a6833927ce28..838b21de480664ab267fa0b24ece86f72cb2af21 100644 --- a/src/Workspaces/MSBuildTest/VisualStudioMSBuildInstalled.cs +++ b/src/Workspaces/MSBuildTest/VisualStudioMSBuildInstalled.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Immutable; -using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection;