From d63625c02b560cbb72f29db6a293db33512ea2f9 Mon Sep 17 00:00:00 2001 From: Nick Guerrera Date: Sun, 5 Aug 2018 15:29:14 -0700 Subject: [PATCH 01/18] Fix build warning and treat msbuild warnings as errors --- .../dotnet-dependency-tool-invoker.csproj | 4 +++- build/BuildDefaults.props | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/TestAssets/TestPackages/dotnet-dependency-tool-invoker/dotnet-dependency-tool-invoker.csproj b/TestAssets/TestPackages/dotnet-dependency-tool-invoker/dotnet-dependency-tool-invoker.csproj index f625dcbe6..a6e830926 100644 --- a/TestAssets/TestPackages/dotnet-dependency-tool-invoker/dotnet-dependency-tool-invoker.csproj +++ b/TestAssets/TestPackages/dotnet-dependency-tool-invoker/dotnet-dependency-tool-invoker.csproj @@ -1,8 +1,9 @@ - + + 1.0.0-rc @@ -23,4 +24,5 @@ + diff --git a/build/BuildDefaults.props b/build/BuildDefaults.props index d574b1789..1f26ed860 100644 --- a/build/BuildDefaults.props +++ b/build/BuildDefaults.props @@ -33,5 +33,6 @@ NU1701;NU5104 true + true From 1ec1f612aa62d01dff1d43170c63cea4fccb2dd3 Mon Sep 17 00:00:00 2001 From: Nick Guerrera Date: Mon, 6 Aug 2018 11:16:45 -0700 Subject: [PATCH 02/18] Don't let crossgen warnings become msbuild warnings-as-errors --- build_projects/dotnet-cli-build/Crossgen.cs | 33 ++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/build_projects/dotnet-cli-build/Crossgen.cs b/build_projects/dotnet-cli-build/Crossgen.cs index 48ebdebfa..8c4d4954e 100644 --- a/build_projects/dotnet-cli-build/Crossgen.cs +++ b/build_projects/dotnet-cli-build/Crossgen.cs @@ -82,7 +82,38 @@ namespace Microsoft.DotNet.Build.Tasks protected override MessageImportance StandardOutputLoggingImportance { - get { return MessageImportance.High; } // or else the output doesn't get logged by default + // Default is low, but we want to see output at normal verbosity. + get { return MessageImportance.Normal; } + } + + protected override MessageImportance StandardErrorLoggingImportance + { + // This turns stderr messages into msbuild errors below. + get { return MessageImportance.High; } + } + + protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance) + { + // Crossgen's error/warning formatting is inconsistent and so we do + // not use the "canonical error format" handling of base. + // + // Furthermore, we don't want to log crossgen warnings as msbuild + // warnings because we cannot prevent them and they are only + // occasionally formatted as something that base would recognize as + // a canonically formatted warning anyway. + // + // One thing that is consistent is that crossgne errors go to stderr + // and everything else goes to stdout. Above, we set stderr to high + // importance above, and stdout to normal. So we can use that here + // to distinguish between errors and messages. + if (messageImportance == MessageImportance.High) + { + Log.LogError(singleLine); + } + else + { + Log.LogMessage(messageImportance, singleLine); + } } protected override string GenerateFullPathToTool() From 624259561378c27833707a719aa0ea0cf0d4dfee Mon Sep 17 00:00:00 2001 From: Nick Guerrera Date: Mon, 6 Aug 2018 13:23:11 -0700 Subject: [PATCH 03/18] Fix warnings-as-errors in Linux packaging --- build/DependencyVersions.props | 2 +- build/package/Installer.DEB.proj | 29 +++++++++++++++-------------- build/package/Installer.RPM.targets | 3 ++- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/build/DependencyVersions.props b/build/DependencyVersions.props index 07e237526..048583f64 100644 --- a/build/DependencyVersions.props +++ b/build/DependencyVersions.props @@ -78,7 +78,7 @@ 2.1.0-prerelease-02430-04 $(BuildTasksFeedToolVersion) - 2.0.0-preview2-25331-01 + 2.0.0 diff --git a/build/package/Installer.DEB.proj b/build/package/Installer.DEB.proj index 0e516f440..51de5c615 100644 --- a/build/package/Installer.DEB.proj +++ b/build/package/Installer.DEB.proj @@ -94,12 +94,12 @@ UseHardlinksIfPossible="False" /> - - - - - - + + + + + + - - - - - - + + + + + + @@ -174,8 +174,9 @@ - - + + + diff --git a/build/package/Installer.RPM.targets b/build/package/Installer.RPM.targets index e6e4fa917..3a9990d62 100644 --- a/build/package/Installer.RPM.targets +++ b/build/package/Installer.RPM.targets @@ -196,7 +196,8 @@ - + + From 813c6b99e7abc99e69539f5d2436ffbed9e7a6a6 Mon Sep 17 00:00:00 2001 From: Livar Cunha Date: Thu, 9 Aug 2018 18:48:40 -0700 Subject: [PATCH 04/18] Update CLI branding to 2.1.203. --- build/Branding.props | 2 +- build/Version.props | 2 +- packaging/osx/clisdk/resources/cs.lproj/conclusion.html | 2 +- packaging/osx/clisdk/resources/de.lproj/conclusion.html | 2 +- packaging/osx/clisdk/resources/en.lproj/conclusion.html | 2 +- packaging/osx/clisdk/resources/es.lproj/conclusion.html | 2 +- packaging/osx/clisdk/resources/fr.lproj/conclusion.html | 2 +- packaging/osx/clisdk/resources/it.lproj/conclusion.html | 2 +- packaging/osx/clisdk/resources/ja.lproj/conclusion.html | 2 +- packaging/osx/clisdk/resources/ko.lproj/conclusion.html | 2 +- packaging/osx/clisdk/resources/pl.lproj/conclusion.html | 2 +- packaging/osx/clisdk/resources/pt-br.lproj/conclusion.html | 2 +- packaging/osx/clisdk/resources/ru.lproj/conclusion.html | 2 +- packaging/osx/clisdk/resources/tr.lproj/conclusion.html | 2 +- packaging/osx/clisdk/resources/zh-hans.lproj/conclusion.html | 2 +- packaging/osx/clisdk/resources/zh-hant.lproj/conclusion.html | 2 +- packaging/windows/clisdk/bundle.wxl | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/build/Branding.props b/build/Branding.props index 580260010..820b2f787 100644 --- a/build/Branding.props +++ b/build/Branding.props @@ -1,6 +1,6 @@ - Microsoft .NET Core SDK - 2.1.202 + Microsoft .NET Core SDK - 2.1.203 .NET Standard Support for Visual Studio 2015 Microsoft .NET Core Runtime - 2.0.9 Microsoft .NET Core Host - 2.0.1 diff --git a/build/Version.props b/build/Version.props index f1c4d1d12..3372d67b9 100644 --- a/build/Version.props +++ b/build/Version.props @@ -2,7 +2,7 @@ 2 1 - 202 + 203 preview $(VersionMajor).$(VersionMinor).$(VersionPatch)-$(ReleaseSuffix) diff --git a/packaging/osx/clisdk/resources/cs.lproj/conclusion.html b/packaging/osx/clisdk/resources/cs.lproj/conclusion.html index b66d897b2..7c2e12873 100644 --- a/packaging/osx/clisdk/resources/cs.lproj/conclusion.html +++ b/packaging/osx/clisdk/resources/cs.lproj/conclusion.html @@ -7,7 +7,7 @@

The following was installed at /usr/local/share/dotnet

    -
  • .NET Core SDK 2.1.202
  • +
  • .NET Core SDK 2.1.203
  • .NET Core Runtime 2.0.9
  • Runtime Package Store
diff --git a/packaging/osx/clisdk/resources/de.lproj/conclusion.html b/packaging/osx/clisdk/resources/de.lproj/conclusion.html index b66d897b2..7c2e12873 100644 --- a/packaging/osx/clisdk/resources/de.lproj/conclusion.html +++ b/packaging/osx/clisdk/resources/de.lproj/conclusion.html @@ -7,7 +7,7 @@

The following was installed at /usr/local/share/dotnet

    -
  • .NET Core SDK 2.1.202
  • +
  • .NET Core SDK 2.1.203
  • .NET Core Runtime 2.0.9
  • Runtime Package Store
diff --git a/packaging/osx/clisdk/resources/en.lproj/conclusion.html b/packaging/osx/clisdk/resources/en.lproj/conclusion.html index b66d897b2..7c2e12873 100644 --- a/packaging/osx/clisdk/resources/en.lproj/conclusion.html +++ b/packaging/osx/clisdk/resources/en.lproj/conclusion.html @@ -7,7 +7,7 @@

The following was installed at /usr/local/share/dotnet

    -
  • .NET Core SDK 2.1.202
  • +
  • .NET Core SDK 2.1.203
  • .NET Core Runtime 2.0.9
  • Runtime Package Store
diff --git a/packaging/osx/clisdk/resources/es.lproj/conclusion.html b/packaging/osx/clisdk/resources/es.lproj/conclusion.html index b66d897b2..7c2e12873 100644 --- a/packaging/osx/clisdk/resources/es.lproj/conclusion.html +++ b/packaging/osx/clisdk/resources/es.lproj/conclusion.html @@ -7,7 +7,7 @@

The following was installed at /usr/local/share/dotnet

    -
  • .NET Core SDK 2.1.202
  • +
  • .NET Core SDK 2.1.203
  • .NET Core Runtime 2.0.9
  • Runtime Package Store
diff --git a/packaging/osx/clisdk/resources/fr.lproj/conclusion.html b/packaging/osx/clisdk/resources/fr.lproj/conclusion.html index b66d897b2..7c2e12873 100644 --- a/packaging/osx/clisdk/resources/fr.lproj/conclusion.html +++ b/packaging/osx/clisdk/resources/fr.lproj/conclusion.html @@ -7,7 +7,7 @@

The following was installed at /usr/local/share/dotnet

    -
  • .NET Core SDK 2.1.202
  • +
  • .NET Core SDK 2.1.203
  • .NET Core Runtime 2.0.9
  • Runtime Package Store
diff --git a/packaging/osx/clisdk/resources/it.lproj/conclusion.html b/packaging/osx/clisdk/resources/it.lproj/conclusion.html index b66d897b2..7c2e12873 100644 --- a/packaging/osx/clisdk/resources/it.lproj/conclusion.html +++ b/packaging/osx/clisdk/resources/it.lproj/conclusion.html @@ -7,7 +7,7 @@

The following was installed at /usr/local/share/dotnet

    -
  • .NET Core SDK 2.1.202
  • +
  • .NET Core SDK 2.1.203
  • .NET Core Runtime 2.0.9
  • Runtime Package Store
diff --git a/packaging/osx/clisdk/resources/ja.lproj/conclusion.html b/packaging/osx/clisdk/resources/ja.lproj/conclusion.html index b66d897b2..7c2e12873 100644 --- a/packaging/osx/clisdk/resources/ja.lproj/conclusion.html +++ b/packaging/osx/clisdk/resources/ja.lproj/conclusion.html @@ -7,7 +7,7 @@

The following was installed at /usr/local/share/dotnet

    -
  • .NET Core SDK 2.1.202
  • +
  • .NET Core SDK 2.1.203
  • .NET Core Runtime 2.0.9
  • Runtime Package Store
diff --git a/packaging/osx/clisdk/resources/ko.lproj/conclusion.html b/packaging/osx/clisdk/resources/ko.lproj/conclusion.html index b66d897b2..7c2e12873 100644 --- a/packaging/osx/clisdk/resources/ko.lproj/conclusion.html +++ b/packaging/osx/clisdk/resources/ko.lproj/conclusion.html @@ -7,7 +7,7 @@

The following was installed at /usr/local/share/dotnet

    -
  • .NET Core SDK 2.1.202
  • +
  • .NET Core SDK 2.1.203
  • .NET Core Runtime 2.0.9
  • Runtime Package Store
diff --git a/packaging/osx/clisdk/resources/pl.lproj/conclusion.html b/packaging/osx/clisdk/resources/pl.lproj/conclusion.html index b66d897b2..7c2e12873 100644 --- a/packaging/osx/clisdk/resources/pl.lproj/conclusion.html +++ b/packaging/osx/clisdk/resources/pl.lproj/conclusion.html @@ -7,7 +7,7 @@

The following was installed at /usr/local/share/dotnet

    -
  • .NET Core SDK 2.1.202
  • +
  • .NET Core SDK 2.1.203
  • .NET Core Runtime 2.0.9
  • Runtime Package Store
diff --git a/packaging/osx/clisdk/resources/pt-br.lproj/conclusion.html b/packaging/osx/clisdk/resources/pt-br.lproj/conclusion.html index b66d897b2..7c2e12873 100644 --- a/packaging/osx/clisdk/resources/pt-br.lproj/conclusion.html +++ b/packaging/osx/clisdk/resources/pt-br.lproj/conclusion.html @@ -7,7 +7,7 @@

The following was installed at /usr/local/share/dotnet

    -
  • .NET Core SDK 2.1.202
  • +
  • .NET Core SDK 2.1.203
  • .NET Core Runtime 2.0.9
  • Runtime Package Store
diff --git a/packaging/osx/clisdk/resources/ru.lproj/conclusion.html b/packaging/osx/clisdk/resources/ru.lproj/conclusion.html index b66d897b2..7c2e12873 100644 --- a/packaging/osx/clisdk/resources/ru.lproj/conclusion.html +++ b/packaging/osx/clisdk/resources/ru.lproj/conclusion.html @@ -7,7 +7,7 @@

The following was installed at /usr/local/share/dotnet

    -
  • .NET Core SDK 2.1.202
  • +
  • .NET Core SDK 2.1.203
  • .NET Core Runtime 2.0.9
  • Runtime Package Store
diff --git a/packaging/osx/clisdk/resources/tr.lproj/conclusion.html b/packaging/osx/clisdk/resources/tr.lproj/conclusion.html index b66d897b2..7c2e12873 100644 --- a/packaging/osx/clisdk/resources/tr.lproj/conclusion.html +++ b/packaging/osx/clisdk/resources/tr.lproj/conclusion.html @@ -7,7 +7,7 @@

The following was installed at /usr/local/share/dotnet

    -
  • .NET Core SDK 2.1.202
  • +
  • .NET Core SDK 2.1.203
  • .NET Core Runtime 2.0.9
  • Runtime Package Store
diff --git a/packaging/osx/clisdk/resources/zh-hans.lproj/conclusion.html b/packaging/osx/clisdk/resources/zh-hans.lproj/conclusion.html index b66d897b2..7c2e12873 100644 --- a/packaging/osx/clisdk/resources/zh-hans.lproj/conclusion.html +++ b/packaging/osx/clisdk/resources/zh-hans.lproj/conclusion.html @@ -7,7 +7,7 @@

The following was installed at /usr/local/share/dotnet

    -
  • .NET Core SDK 2.1.202
  • +
  • .NET Core SDK 2.1.203
  • .NET Core Runtime 2.0.9
  • Runtime Package Store
diff --git a/packaging/osx/clisdk/resources/zh-hant.lproj/conclusion.html b/packaging/osx/clisdk/resources/zh-hant.lproj/conclusion.html index b66d897b2..7c2e12873 100644 --- a/packaging/osx/clisdk/resources/zh-hant.lproj/conclusion.html +++ b/packaging/osx/clisdk/resources/zh-hant.lproj/conclusion.html @@ -7,7 +7,7 @@

The following was installed at /usr/local/share/dotnet

    -
  • .NET Core SDK 2.1.202
  • +
  • .NET Core SDK 2.1.203
  • .NET Core Runtime 2.0.9
  • Runtime Package Store
diff --git a/packaging/windows/clisdk/bundle.wxl b/packaging/windows/clisdk/bundle.wxl index f6fe64faf..dd264abff 100644 --- a/packaging/windows/clisdk/bundle.wxl +++ b/packaging/windows/clisdk/bundle.wxl @@ -50,7 +50,7 @@ The installation was successful The following were installed at [DOTNETHOME] - • .NET Core SDK 2.1.202 + • .NET Core SDK 2.1.203 • .NET Core Runtime 2.0.9 • Runtime Package Store From ea47700f7520d0b43a866e52fa6b2681df0801ed Mon Sep 17 00:00:00 2001 From: Vagisha Nidhi Date: Fri, 10 Aug 2018 14:32:29 +0530 Subject: [PATCH 05/18] TestPlatform 15.9.0-preview Insertion --- build/DependencyVersions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/DependencyVersions.props b/build/DependencyVersions.props index 07e237526..abef520fc 100644 --- a/build/DependencyVersions.props +++ b/build/DependencyVersions.props @@ -53,7 +53,7 @@ $(NuGetBuildTasksPackageVersion) $(NuGetBuildTasksPackageVersion) $(NuGetBuildTasksPackageVersion) - 15.8.0 + 15.9.0-preview-20180807-05 $(MicrosoftNETTestSdkPackageVersion) $(MicrosoftNETTestSdkPackageVersion) 0.2.0-beta-000042 From 00bf470ddbc2a4adbefb0f52c6b8638e3eb842b3 Mon Sep 17 00:00:00 2001 From: Vagisha Nidhi Date: Fri, 10 Aug 2018 16:26:00 +0530 Subject: [PATCH 06/18] Updated test --- .../GivenDotnetTestBuildsAndRunsTestfromCsproj.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/test/dotnet-test.Tests/GivenDotnetTestBuildsAndRunsTestfromCsproj.cs b/test/dotnet-test.Tests/GivenDotnetTestBuildsAndRunsTestfromCsproj.cs index 7121959fe..bc88af2cd 100644 --- a/test/dotnet-test.Tests/GivenDotnetTestBuildsAndRunsTestfromCsproj.cs +++ b/test/dotnet-test.Tests/GivenDotnetTestBuildsAndRunsTestfromCsproj.cs @@ -152,11 +152,14 @@ namespace Microsoft.DotNet.Cli.Test.Tests .ExecuteWithCapturedOutput("--logger \"trx;logfilename=custom.trx\" --logger console;verbosity=normal -- RunConfiguration.ResultsDirectory=" + trxLoggerDirectory); // Verify - var trxFilePath = Path.Combine(trxLoggerDirectory, "custom.trx"); - Assert.True(File.Exists(trxFilePath)); - result.StdOut.Should().Contain(trxFilePath); - result.StdOut.Should().Contain("Passed VSTestPassTest"); - result.StdOut.Should().Contain("Failed VSTestFailTest"); + if (!DotnetUnderTest.IsLocalized()) + { + var trxFilePath = Path.Combine(trxLoggerDirectory, "custom.trx"); + Assert.True(File.Exists(trxFilePath)); + result.StdOut.Should().Contain(trxFilePath); + result.StdOut.Should().Contain("Passed VSTestPassTest"); + result.StdOut.Should().Contain("Failed VSTestFailTest"); + } // Cleanup trxLoggerDirectory if it exist if (Directory.Exists(trxLoggerDirectory)) From a19e2ed10252f7be5b45a45e8f81dcceaaff12d5 Mon Sep 17 00:00:00 2001 From: Livar Date: Fri, 10 Aug 2018 10:43:31 -0700 Subject: [PATCH 07/18] Update CLI branding to 2.1.402 --- build/Version.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Version.props b/build/Version.props index c2309c774..f2c100031 100644 --- a/build/Version.props +++ b/build/Version.props @@ -2,7 +2,7 @@ 2 1 - 401 + 402 preview $(VersionMajor).$(VersionMinor) From 5f1d5dabd4f66a1a0ea27d568b3e5bc0892c6bfd Mon Sep 17 00:00:00 2001 From: Livar Date: Fri, 10 Aug 2018 17:28:50 -0700 Subject: [PATCH 08/18] Adding the 2.1.3 runtime blob feed as a feed for the CLI This unblocks the prodcon build for 2.1.4 --- build/NugetConfigFile.targets | 1 + 1 file changed, 1 insertion(+) diff --git a/build/NugetConfigFile.targets b/build/NugetConfigFile.targets index 535665c79..0cae8455a 100644 --- a/build/NugetConfigFile.targets +++ b/build/NugetConfigFile.targets @@ -30,6 +30,7 @@ + ]]> From 1bd879bb18c19d3fc9e1d80e7b9236a30264d106 Mon Sep 17 00:00:00 2001 From: jbeisner Date: Mon, 13 Aug 2018 23:15:29 +0000 Subject: [PATCH 09/18] Add back: "PUBLISH_NUPKG_TO_BLOB_FEED" to manage the no-suffix builds in 2.1 --- build/publish/PublishNupkgToBlobFeed.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/publish/PublishNupkgToBlobFeed.targets b/build/publish/PublishNupkgToBlobFeed.targets index 272e08cc2..0914a2c9a 100644 --- a/build/publish/PublishNupkgToBlobFeed.targets +++ b/build/publish/PublishNupkgToBlobFeed.targets @@ -26,7 +26,7 @@ - + From 5635f0d0648e9eb3b6a8f150d5589846da021cae Mon Sep 17 00:00:00 2001 From: Livar Date: Tue, 14 Aug 2018 13:44:32 -0700 Subject: [PATCH 10/18] Disabled MSBuildTreatWarningsAsErrors --- build/BuildDefaults.props | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build/BuildDefaults.props b/build/BuildDefaults.props index 1f26ed860..053ea0a83 100644 --- a/build/BuildDefaults.props +++ b/build/BuildDefaults.props @@ -33,6 +33,7 @@ NU1701;NU5104 true - true + + From 1752be0f1cceb71df731d721b4347d2767837652 Mon Sep 17 00:00:00 2001 From: William Li Date: Tue, 14 Aug 2018 15:43:31 -0700 Subject: [PATCH 11/18] Revert "Disabled MSBuildTreatWarningsAsErrors" This reverts commit 5635f0d0648e9eb3b6a8f150d5589846da021cae. --- build/BuildDefaults.props | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build/BuildDefaults.props b/build/BuildDefaults.props index 053ea0a83..1f26ed860 100644 --- a/build/BuildDefaults.props +++ b/build/BuildDefaults.props @@ -33,7 +33,6 @@ NU1701;NU5104 true - - + true From cae6528834e7f9d538a7926656ead825f213d404 Mon Sep 17 00:00:00 2001 From: William Li Date: Tue, 14 Aug 2018 15:48:15 -0700 Subject: [PATCH 12/18] Use prebuild image --- scripts/docker/debian/Dockerfile | 34 +------------------------------- 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/scripts/docker/debian/Dockerfile b/scripts/docker/debian/Dockerfile index d54afeb0e..281778513 100644 --- a/scripts/docker/debian/Dockerfile +++ b/scripts/docker/debian/Dockerfile @@ -4,47 +4,15 @@ # # Dockerfile that creates a container suitable to build dotnet-cli -FROM debian:jessie +FROM microsoft/dotnet-buildtools-prereqs:debian-8.2-debpkg-d770b8b-20180628122423 # Misc Dependencies for build RUN apt-get update && \ apt-get -qqy install \ - curl \ - unzip \ - gettext \ sudo && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* -# This could become a "microsoft/coreclr" image, since it just installs the dependencies for CoreCLR (and stdlib) -RUN apt-get update &&\ - apt-get -qqy install \ - libunwind8 \ - libkrb5-3 \ - libicu52 \ - liblttng-ust0 \ - libssl1.0.0 \ - zlib1g \ - libuuid1 && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* - -# Install Build Prereqs -RUN apt-get update && \ - apt-get -qqy install \ - debhelper \ - build-essential \ - devscripts \ - git \ - cmake \ - clang-3.5 && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* - -# Use clang as c++ compiler -RUN update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++-3.5 100 -RUN update-alternatives --set c++ /usr/bin/clang++-3.5 - # Setup User to match Host User, and give superuser permissions ARG USER_ID=0 RUN useradd -m code_executor -u ${USER_ID} -g sudo From b2be5b4469f7a6d95fadd8ec449f63e2dcbbc202 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Wed, 15 Aug 2018 10:18:14 -0500 Subject: [PATCH 13/18] MSBuild 15.9.0-preview-000006 --- build/DependencyVersions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/DependencyVersions.props b/build/DependencyVersions.props index 98fbccae2..e5fd67afa 100644 --- a/build/DependencyVersions.props +++ b/build/DependencyVersions.props @@ -12,7 +12,7 @@ 2.1.1 2.1.2 $(MicrosoftNETCoreAppPackageVersion) - 15.8.166 + 15.9.0-preview-000006 $(MicrosoftBuildPackageVersion) $(MicrosoftBuildPackageVersion) $(MicrosoftBuildPackageVersion) From 30c2e7570b42e515120486874ee79971082421a2 Mon Sep 17 00:00:00 2001 From: Livar Date: Wed, 15 Aug 2018 10:51:23 -0700 Subject: [PATCH 14/18] Update links in the readme to release/2.1.5xx --- README.md | 66 +++++++++++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 2a225d342..48ce7e34a 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Looking for V1 of the .NET Core tooling? If you are looking for the v2.0 release of the .NET Core tools (CLI, MSBuild and the new csproj), head over to https://dot.net/core and download! -> **Note:** the release/2.1.4xx branch of the CLI repo is based on an upcoming update of the SDK and is considered pre-release. For production-level usage, please use the +> **Note:** the release/2.1.5xx branch of the CLI repo is based on an upcoming update of the SDK and is considered pre-release. For production-level usage, please use the > released version of the tools available at https://dot.net/core Found an issue? @@ -65,7 +65,7 @@ To download the .NET Core runtime **without** the SDK, visit https://github.com/ > want to install the latest released versions, check out the [preceding section](#looking-for-v1-of-the-net-core-tooling). > In order to be able to restore these pre-release packages, you may need to add a NuGet feed pointing to https://dotnet.myget.org/F/dotnet-core/api/v3/index.json. Other feeds may also be necessary depending on what kind of project you are working with. -| Platform | Latest Daily Build
*release/2.1.4xx*
[![][version-badge]][version] | +| Platform | Latest Daily Build
*release/2.1.5xx*
[![][version-badge]][version] | | -------- | :-------------------------------------: | | **Windows x64** | [Installer][win-x64-installer] - [Checksum][win-x64-installer-checksum]
[zip][win-x64-zip] - [Checksum][win-x64-zip-checksum] | | **Windows x86** | [Installer][win-x86-installer] - [Checksum][win-x86-installer-checksum]
[zip][win-x86-zip] - [Checksum][win-x86-zip-checksum] | @@ -76,7 +76,7 @@ To download the .NET Core runtime **without** the SDK, visit https://github.com/ | **RHEL 6** | [tar.gz][rhel-6-targz] - [Checksum][rhel-6-targz-checksum] | | **Linux-musl** | [tar.gz][linux-musl-targz] - [Checksum][linux-musl-targz-checksum] | -| Latest Coherent Build2
*release/2.1.4xx* | +| Latest Coherent Build2
*release/2.1.5xx* | |:------:| | [![][coherent-version-badge]][coherent-version] | @@ -84,47 +84,47 @@ Reference notes: > **1**: *Our Debian packages are put together slightly differently than the other OS specific installers. Instead of combining everything, we have separate component packages that depend on each other. If you're installing these directly from the .deb files (via dpkg or similar), then you'll need to install the [corresponding Host, Host FX Resolver, and Shared Framework packages](https://github.com/dotnet/core-setup#daily-builds) before installing the Sdk package.* >

**2**: *A 'coherent' build is defined as a build where the Runtime version matches between the CLI and Asp.NET.* -[version]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/latest.version -[coherent-version]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/latest.coherent.version +[version]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/latest.version +[coherent-version]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/latest.coherent.version [comment]: # (The latest versions are always the same across all platforms. Just need one to show, so picking win-x64's svg.) -[version-badge]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/win_x64_Release_version_badge.svg -[coherent-version-badge]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/win_x64_Release_coherent_badge.svg +[version-badge]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/win_x64_Release_version_badge.svg +[coherent-version-badge]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/win_x64_Release_coherent_badge.svg -[win-x64-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-win-x64.exe -[win-x64-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-win-x64.exe.sha -[win-x64-zip]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-win-x64.zip -[win-x64-zip-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-win-x64.zip.sha +[win-x64-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-win-x64.exe +[win-x64-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-win-x64.exe.sha +[win-x64-zip]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-win-x64.zip +[win-x64-zip-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-win-x64.zip.sha -[win-x86-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-win-x86.exe -[win-x86-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-win-x86.exe.sha -[win-x86-zip]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-win-x86.zip -[win-x86-zip-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-win-x86.zip.sha +[win-x86-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-win-x86.exe +[win-x86-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-win-x86.exe.sha +[win-x86-zip]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-win-x86.zip +[win-x86-zip-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-win-x86.zip.sha -[osx-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-osx-x64.pkg -[osx-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-osx-x64.pkg.sha -[osx-targz]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-osx-x64.tar.gz -[osx-targz-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-osx-x64.tar.gz.sha +[osx-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-osx-x64.pkg +[osx-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-osx-x64.pkg.sha +[osx-targz]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-osx-x64.tar.gz +[osx-targz-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-osx-x64.tar.gz.sha -[linux-targz]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-linux-x64.tar.gz -[linux-targz-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-linux-x64.tar.gz.sha +[linux-targz]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-linux-x64.tar.gz +[linux-targz-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-linux-x64.tar.gz.sha -[linux-arm-targz]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-linux-arm.tar.gz -[linux-arm-targz-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-linux-arm.tar.gz.sha +[linux-arm-targz]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-linux-arm.tar.gz +[linux-arm-targz-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-linux-arm.tar.gz.sha -[linux-arm64-targz]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-linux-arm64.tar.gz -[linux-arm64-targz-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-linux-arm64.tar.gz.sha +[linux-arm64-targz]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-linux-arm64.tar.gz +[linux-arm64-targz-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-linux-arm64.tar.gz.sha -[linux-DEB-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-x64.deb -[linux-DEB-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-x64.deb.sha +[linux-DEB-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-x64.deb +[linux-DEB-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-x64.deb.sha -[linux-RPM-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-x64.rpm -[linux-RPM-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-x64.rpm.sha +[linux-RPM-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-x64.rpm +[linux-RPM-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-x64.rpm.sha -[rhel-6-targz]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-rhel.6-x64.tar.gz -[rhel-6-targz-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.4xx/dotnet-sdk-latest-rhel.6-x64.tar.gz.sha +[rhel-6-targz]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-rhel.6-x64.tar.gz +[rhel-6-targz-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-rhel.6-x64.tar.gz.sha -[linux-musl-targz]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.3xx/dotnet-sdk-latest-linux-musl-x64.tar.gz -[linux-musl-targz-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.3xx/dotnet-sdk-latest-linux-musl-x64.tar.gz.sha +[linux-musl-targz]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-linux-musl-x64.tar.gz +[linux-musl-targz-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.1.5xx/dotnet-sdk-latest-linux-musl-x64.tar.gz.sha # Debian daily feed From 25509d31b174b746e7c32777b987c7832c2e77db Mon Sep 17 00:00:00 2001 From: William Li Date: Wed, 15 Aug 2018 12:40:09 -0700 Subject: [PATCH 15/18] Remove redundent call, ensure no apt list --- build/package/Installer.DEB.proj | 1 - scripts/docker/debian/Dockerfile | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/package/Installer.DEB.proj b/build/package/Installer.DEB.proj index 51de5c615..20f02b662 100644 --- a/build/package/Installer.DEB.proj +++ b/build/package/Installer.DEB.proj @@ -94,7 +94,6 @@ UseHardlinksIfPossible="False" /> - diff --git a/scripts/docker/debian/Dockerfile b/scripts/docker/debian/Dockerfile index 281778513..4b5515ec0 100644 --- a/scripts/docker/debian/Dockerfile +++ b/scripts/docker/debian/Dockerfile @@ -7,7 +7,8 @@ FROM microsoft/dotnet-buildtools-prereqs:debian-8.2-debpkg-d770b8b-20180628122423 # Misc Dependencies for build -RUN apt-get update && \ +RUN rm -rf /var/lib/apt/lists/* && \ + apt-get update && \ apt-get -qqy install \ sudo && \ apt-get clean && \ From d2740ce0b679911310353f00d662437b94cc320f Mon Sep 17 00:00:00 2001 From: William Li Date: Wed, 15 Aug 2018 14:13:07 -0700 Subject: [PATCH 16/18] Remove fallback folder --- build/package/Installer.DEB.proj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build/package/Installer.DEB.proj b/build/package/Installer.DEB.proj index 20f02b662..a8c00c921 100644 --- a/build/package/Installer.DEB.proj +++ b/build/package/Installer.DEB.proj @@ -128,6 +128,9 @@ ToolPath="$(DebianInstalledDirectory)" /> + + + From 3ccc3593c8415561970b9fd6948f67c523937f36 Mon Sep 17 00:00:00 2001 From: Nick Guerrera Date: Thu, 16 Aug 2018 19:21:48 -0700 Subject: [PATCH 17/18] MSBuild SDK Resolver Improvements (#9547) 1. When there's no global.json, use latest SDK that is compatible with msbuild, not latest SDK overall 2. Respect VS setting to allow / disallow resolving to preview SDKs --- build/DependencyVersions.props | 5 +- .../Interop.Common.cs | 36 --- .../Interop.NETFramework.cs | 47 --- .../Interop.NETStandard.cs | 53 ---- .../Interop.cs | 135 ++++++++ .../MSBuildSdkResolver.cs | 208 +++++++++++-- ...Microsoft.DotNet.MSBuildSdkResolver.csproj | 11 +- .../Microsoft.DotNet.MSBuildSdkResolver.sln | 19 +- .../NETCoreSdkResolver.cs | 76 +++++ .../VSSettings.cs | 155 ++++++++++ .../GivenAnMSBuildSdkResolver.cs | 287 +++++++++++++++++- ...oft.DotNet.MSBuildSdkResolver.Tests.csproj | 21 +- 12 files changed, 856 insertions(+), 197 deletions(-) delete mode 100644 src/Microsoft.DotNet.MSBuildSdkResolver/Interop.Common.cs delete mode 100644 src/Microsoft.DotNet.MSBuildSdkResolver/Interop.NETFramework.cs delete mode 100644 src/Microsoft.DotNet.MSBuildSdkResolver/Interop.NETStandard.cs create mode 100644 src/Microsoft.DotNet.MSBuildSdkResolver/Interop.cs create mode 100644 src/Microsoft.DotNet.MSBuildSdkResolver/NETCoreSdkResolver.cs create mode 100644 src/Microsoft.DotNet.MSBuildSdkResolver/VSSettings.cs diff --git a/build/DependencyVersions.props b/build/DependencyVersions.props index 0b0cf7b09..3d0d589e4 100644 --- a/build/DependencyVersions.props +++ b/build/DependencyVersions.props @@ -11,7 +11,10 @@ 2.1.1 2.1.1 2.1.3-servicing-26724-03 - $(MicrosoftNETCoreAppPackageVersion) + + + 3.0.0-preview1-26816-04 + 15.9.0-preview-000006 $(MicrosoftBuildPackageVersion) $(MicrosoftBuildPackageVersion) diff --git a/src/Microsoft.DotNet.MSBuildSdkResolver/Interop.Common.cs b/src/Microsoft.DotNet.MSBuildSdkResolver/Interop.Common.cs deleted file mode 100644 index 580d1220b..000000000 --- a/src/Microsoft.DotNet.MSBuildSdkResolver/Interop.Common.cs +++ /dev/null @@ -1,36 +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.Diagnostics; -using System.Text; - -namespace Microsoft.DotNet.MSBuildSdkResolver -{ - internal static partial class Interop - { - internal static string hostfxr_resolve_sdk(string exe_dir, string working_dir) - { - var buffer = new StringBuilder(capacity: 64); - - for (;;) - { - int size = hostfxr_resolve_sdk(exe_dir, working_dir, buffer, buffer.Capacity); - if (size <= 0) - { - Debug.Assert(size == 0); - return null; - } - - if (size <= buffer.Capacity) - { - break; - } - - buffer.Capacity = size; - } - - return buffer.ToString(); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.DotNet.MSBuildSdkResolver/Interop.NETFramework.cs b/src/Microsoft.DotNet.MSBuildSdkResolver/Interop.NETFramework.cs deleted file mode 100644 index 2101637f3..000000000 --- a/src/Microsoft.DotNet.MSBuildSdkResolver/Interop.NETFramework.cs +++ /dev/null @@ -1,47 +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. - -#if NET46 - -using System; -using System.IO; -using System.Runtime.InteropServices; -using System.Text; - -namespace Microsoft.DotNet.MSBuildSdkResolver -{ - internal static partial class Interop - { - internal static readonly bool RunningOnWindows = true; - - static Interop() - { - PreloadLibrary("hostfxr.dll"); - } - - // MSBuild SDK resolvers are required to be AnyCPU, but we have a native dependency and .NETFramework does not - // have a built-in facility for dynamically loading user native dlls for the appropriate platform. We therefore - // preload the version with the correct architecture (from a corresponding sub-folder relative to us) on static - // construction so that subsequent P/Invokes can find it. - private static void PreloadLibrary(string dllFileName) - { - string basePath = Path.GetDirectoryName(typeof(Interop).Assembly.Location); - string architecture = IntPtr.Size == 8 ? "x64" : "x86"; - string dllPath = Path.Combine(basePath, architecture, dllFileName); - - // return value is intentially ignored as we let the subsequent P/Invokes fail naturally. - LoadLibraryExW(dllPath, IntPtr.Zero, LOAD_WITH_ALTERED_SEARCH_PATH); - } - - // lpFileName passed to LoadLibraryEx must be a full path. - private const int LOAD_WITH_ALTERED_SEARCH_PATH = 0x8; - - [DllImport("kernel32", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] - private static extern IntPtr LoadLibraryExW(string lpFileName, IntPtr hFile, int dwFlags); - - [DllImport("hostfxr", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] - private static extern int hostfxr_resolve_sdk(string exe_dir, string working_dir, [Out] StringBuilder buffer, int buffer_size); - } -} - -#endif // NET46 \ No newline at end of file diff --git a/src/Microsoft.DotNet.MSBuildSdkResolver/Interop.NETStandard.cs b/src/Microsoft.DotNet.MSBuildSdkResolver/Interop.NETStandard.cs deleted file mode 100644 index 245f153a0..000000000 --- a/src/Microsoft.DotNet.MSBuildSdkResolver/Interop.NETStandard.cs +++ /dev/null @@ -1,53 +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. - -// NOTE: the NET46 build ships with Visual Studio/desktop msbuild on Windows. -// The netstandard1.5 adaptation here acts a proof-of-concept for cross-platform -// portability of the underlying hostfxr API and gives us build and test coverage -// on non-Windows machines. It also ships with msbuild on Mono. -#if NETSTANDARD2_0 - -using System; -using System.Runtime.InteropServices; -using System.Text; - -namespace Microsoft.DotNet.MSBuildSdkResolver -{ - internal static partial class Interop - { - internal static readonly bool RunningOnWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); - - internal static string realpath(string path) - { - var ptr = unix_realpath(path, IntPtr.Zero); - var result = Marshal.PtrToStringAnsi(ptr); // uses UTF8 on Unix - unix_free(ptr); - return result; - } - - private static int hostfxr_resolve_sdk(string exe_dir, string working_dir, [Out] StringBuilder buffer, int buffer_size) - { - // hostfxr string encoding is platform -specific so dispatch to the - // appropriately annotated P/Invoke for the current platform. - return RunningOnWindows - ? windows_hostfxr_resolve_sdk(exe_dir, working_dir, buffer, buffer_size) - : unix_hostfxr_resolve_sdk(exe_dir, working_dir, buffer, buffer_size); - } - - [DllImport("hostfxr", EntryPoint = nameof(hostfxr_resolve_sdk), CharSet = CharSet.Unicode, ExactSpelling=true, CallingConvention = CallingConvention.Cdecl)] - private static extern int windows_hostfxr_resolve_sdk(string exe_dir, string working_dir, [Out] StringBuilder buffer, int buffer_size); - - // CharSet.Ansi is UTF8 on Unix - [DllImport("hostfxr", EntryPoint = nameof(hostfxr_resolve_sdk), CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] - private static extern int unix_hostfxr_resolve_sdk(string exe_dir, string working_dir, [Out] StringBuilder buffer, int buffer_size); - - // CharSet.Ansi is UTF8 on Unix - [DllImport("libc", EntryPoint = nameof(realpath), CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] - private static extern IntPtr unix_realpath(string path, IntPtr buffer); - - [DllImport("libc", EntryPoint = "free", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] - private static extern void unix_free(IntPtr ptr); - } -} - -#endif // NETSTANDARD2_0 diff --git a/src/Microsoft.DotNet.MSBuildSdkResolver/Interop.cs b/src/Microsoft.DotNet.MSBuildSdkResolver/Interop.cs new file mode 100644 index 000000000..cda6dd3d0 --- /dev/null +++ b/src/Microsoft.DotNet.MSBuildSdkResolver/Interop.cs @@ -0,0 +1,135 @@ +// 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 System.Runtime.InteropServices; +using System.Text; + +namespace Microsoft.DotNet.MSBuildSdkResolver +{ + internal static partial class Interop + { + internal static readonly bool RunningOnWindows = +#if NET46 + // Not using RuntimeInformation on NET46 to avoid non-in-box framework API, + // which create deployment problems for the resolver. + Path.DirectorySeparatorChar == '\\'; +#else + RuntimeInformation.IsOSPlatform(OSPlatform.Windows); +#endif + + static Interop() + { + if (RunningOnWindows) + { + PreloadWindowsLibrary("hostfxr.dll"); + } + } + + // MSBuild SDK resolvers are required to be AnyCPU, but we have a native dependency and .NETFramework does not + // have a built-in facility for dynamically loading user native dlls for the appropriate platform. We therefore + // preload the version with the correct architecture (from a corresponding sub-folder relative to us) on static + // construction so that subsequent P/Invokes can find it. + private static void PreloadWindowsLibrary(string dllFileName) + { + string basePath = Path.GetDirectoryName(typeof(Interop).Assembly.Location); + string architecture = IntPtr.Size == 8 ? "x64" : "x86"; + string dllPath = Path.Combine(basePath, architecture, dllFileName); + + // return value is intentially ignored as we let the subsequent P/Invokes fail naturally. + LoadLibraryExW(dllPath, IntPtr.Zero, LOAD_WITH_ALTERED_SEARCH_PATH); + } + + // lpFileName passed to LoadLibraryEx must be a full path. + private const int LOAD_WITH_ALTERED_SEARCH_PATH = 0x8; + + [DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] + private static extern IntPtr LoadLibraryExW(string lpFileName, IntPtr hFile, int dwFlags); + + + [Flags] + internal enum hostfxr_resolve_sdk2_flags_t : int + { + disallow_prerelease = 0x1, + } + + internal enum hostfxr_resolve_sdk2_result_key_t : int + { + resolved_sdk_dir = 0, + global_json_path = 1, + } + + internal static class Windows + { + private const CharSet UTF16 = CharSet.Unicode; + + [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = UTF16)] + internal delegate void hostfxr_resolve_sdk2_result_fn( + hostfxr_resolve_sdk2_result_key_t key, + string value); + + [DllImport("hostfxr", CharSet = UTF16, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + internal static extern int hostfxr_resolve_sdk2( + string exe_dir, + string working_dir, + hostfxr_resolve_sdk2_flags_t flags, + hostfxr_resolve_sdk2_result_fn result); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = UTF16)] + internal delegate void hostfxr_get_available_sdks_result_fn( + int sdk_count, + [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] + string[] sdk_dirs); + + [DllImport("hostfxr", CharSet = UTF16, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + internal static extern int hostfxr_get_available_sdks( + string exe_dir, + hostfxr_get_available_sdks_result_fn result); + } + + internal static class Unix + { + // Ansi marhsaling on Unix is actually UTF8 + private const CharSet UTF8 = CharSet.Ansi; + private static string PtrToStringUTF8(IntPtr ptr) => Marshal.PtrToStringAnsi(ptr); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = UTF8)] + internal delegate void hostfxr_resolve_sdk2_result_fn( + hostfxr_resolve_sdk2_result_key_t key, + string value); + + [DllImport("hostfxr", CharSet = UTF8, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + internal static extern int hostfxr_resolve_sdk2( + string exe_dir, + string working_dir, + hostfxr_resolve_sdk2_flags_t flags, + hostfxr_resolve_sdk2_result_fn result); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = UTF8)] + internal delegate void hostfxr_get_available_sdks_result_fn( + int sdk_count, + [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] + string[] sdk_dirs); + + [DllImport("hostfxr", CharSet = UTF8, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + internal static extern int hostfxr_get_available_sdks( + string exe_dir, + hostfxr_get_available_sdks_result_fn result); + + [DllImport("libc", CharSet = UTF8, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr realpath(string path, IntPtr buffer); + + [DllImport("libc", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + private static extern void free(IntPtr ptr); + + internal static string realpath(string path) + { + var ptr = realpath(path, IntPtr.Zero); + var result = PtrToStringUTF8(ptr); + free(ptr); + return result; + } + } + } +} diff --git a/src/Microsoft.DotNet.MSBuildSdkResolver/MSBuildSdkResolver.cs b/src/Microsoft.DotNet.MSBuildSdkResolver/MSBuildSdkResolver.cs index a115a867b..ce648ed7e 100644 --- a/src/Microsoft.DotNet.MSBuildSdkResolver/MSBuildSdkResolver.cs +++ b/src/Microsoft.DotNet.MSBuildSdkResolver/MSBuildSdkResolver.cs @@ -3,13 +3,21 @@ using Microsoft.Build.Framework; using System; -using System.Collections.Generic; +using System.Collections.Concurrent; using System.IO; using System.Linq; using System.Reflection; namespace Microsoft.DotNet.MSBuildSdkResolver { + // Thread-safety note: + // 1. MSBuild can call the same resolver instance in parallel on multiple threads. + // 2. Nevertheless, in the IDE, project re-evaluation can create new instances for each evaluation. + // + // As such, all state (instance or static) must be guarded against concurrent access/updates. + // Caches of minimum versions, compatible SDKs are static to benefit multiple IDE evaluations. + // VSSettings are also effectively static (singleton instance that can be swapped by tests). + public sealed class DotNetMSBuildSdkResolver : SdkResolver { public override string Name => "Microsoft.DotNet.MSBuildSdkResolver"; @@ -18,29 +26,59 @@ namespace Microsoft.DotNet.MSBuildSdkResolver public override int Priority => 5000; private readonly Func _getEnvironmentVariable; + private readonly VSSettings _vsSettings; + + private static readonly ConcurrentDictionary s_minimumMSBuildVersions + = new ConcurrentDictionary(); + + private static readonly ConcurrentDictionary s_compatibleSdks + = new ConcurrentDictionary(); public DotNetMSBuildSdkResolver() - : this(Environment.GetEnvironmentVariable) + : this(Environment.GetEnvironmentVariable, VSSettings.Ambient) { } - // Test hook to provide environment variables without polluting the test process. - internal DotNetMSBuildSdkResolver(Func getEnvironmentVariable) + // Test constructor + internal DotNetMSBuildSdkResolver(Func getEnvironmentVariable, VSSettings vsSettings) { _getEnvironmentVariable = getEnvironmentVariable; + _vsSettings = vsSettings; + } + + private sealed class CachedResult + { + public string MSBuildSdksDir; + public string NETCoreSdkVersion; } public override SdkResult Resolve(SdkReference sdkReference, SdkResolverContext context, SdkResultFactory factory) { - // These are overrides that are used to force the resolved SDK tasks and targets to come from a given - // base directory and report a given version to msbuild (which may be null if unknown. One key use case - // for this is to test SDK tasks and targets without deploying them inside the .NET Core SDK. - string msbuildSdksDir = _getEnvironmentVariable("DOTNET_MSBUILD_SDK_RESOLVER_SDKS_DIR"); - string netcoreSdkVersion = _getEnvironmentVariable("DOTNET_MSBUILD_SDK_RESOLVER_SDKS_VER"); + string msbuildSdksDir = null; + string netcoreSdkVersion = null; + + if (context.State is CachedResult priorResult) + { + msbuildSdksDir = priorResult.MSBuildSdksDir; + netcoreSdkVersion = priorResult.NETCoreSdkVersion; + } if (msbuildSdksDir == null) { - string netcoreSdkDir = ResolveNetcoreSdkDirectory(context); + // These are overrides that are used to force the resolved SDK tasks and targets to come from a given + // base directory and report a given version to msbuild (which may be null if unknown. One key use case + // for this is to test SDK tasks and targets without deploying them inside the .NET Core SDK. + msbuildSdksDir = _getEnvironmentVariable("DOTNET_MSBUILD_SDK_RESOLVER_SDKS_DIR"); + netcoreSdkVersion = _getEnvironmentVariable("DOTNET_MSBUILD_SDK_RESOLVER_SDKS_VER"); + } + + if (msbuildSdksDir == null) + { + string dotnetExeDir = GetDotnetExeDirectory(); + var resolverResult = ResolveNETCoreSdkDirectory(context, dotnetExeDir); + string netcoreSdkDir = resolverResult.ResolvedSdkDirectory; + string globalJsonPath = resolverResult.GlobalJsonPath; + if (netcoreSdkDir == null) { return factory.IndicateFailure( @@ -66,21 +104,20 @@ namespace Microsoft.DotNet.MSBuildSdkResolver }); } - string minimumMSBuildVersionString = GetMinimumMSBuildVersion(netcoreSdkDir); - var minimumMSBuildVersion = Version.Parse(minimumMSBuildVersionString); + Version minimumMSBuildVersion = GetMinimumMSBuildVersion(netcoreSdkDir); if (context.MSBuildVersion < minimumMSBuildVersion) { return factory.IndicateFailure( new[] { - $"Version {netcoreSdkVersion} of the .NET Core SDK requires at least version {minimumMSBuildVersionString}" + $"Version {netcoreSdkVersion} of the .NET Core SDK requires at least version {minimumMSBuildVersion.ToString()}" + $" of MSBuild. The current available version of MSBuild is {context.MSBuildVersion.ToString()}." + " Change the .NET Core SDK specified in global.json to an older version that requires the MSBuild" + " version currently available." }); } - string minimumVSDefinedSDKVersion = GetMinimumVSDefinedSDKVersion(); + string minimumVSDefinedSDKVersion = GetMinimumVSDefinedSDKVersion(); if (IsNetCoreSDKSmallerThanTheMinimumVersion(netcoreSdkVersion, minimumVSDefinedSDKVersion)) { return factory.IndicateFailure( @@ -93,6 +130,12 @@ namespace Microsoft.DotNet.MSBuildSdkResolver } } + context.State = new CachedResult + { + MSBuildSdksDir = msbuildSdksDir, + NETCoreSdkVersion = netcoreSdkVersion + }; + string msbuildSdkDir = Path.Combine(msbuildSdksDir, sdkReference.Name, "Sdk"); if (!Directory.Exists(msbuildSdkDir)) { @@ -107,18 +150,114 @@ namespace Microsoft.DotNet.MSBuildSdkResolver return factory.IndicateSuccess(msbuildSdkDir, netcoreSdkVersion); } - private static string GetMinimumMSBuildVersion(string netcoreSdkDir) + private sealed class CompatibleSdkKey : IEquatable { - string minimumVersionFilePath = Path.Combine(netcoreSdkDir, "minimumMSBuildVersion"); - if (!File.Exists(minimumVersionFilePath)) + public readonly string DotnetExeDirectory; + public readonly Version MSBuildVersion; + + public CompatibleSdkKey(string dotnetExeDirectory, Version msbuildVersion) { - // smallest version that had resolver support and also - // greater than or equal to the version required by any - // .NET Core SDK that did not have this file. - return "15.3.0"; + DotnetExeDirectory = dotnetExeDirectory; + MSBuildVersion = msbuildVersion; } - return File.ReadLines(minimumVersionFilePath).First().Trim(); + public bool Equals(CompatibleSdkKey other) + { + return other != null + && DotnetExeDirectory == other.DotnetExeDirectory + && MSBuildVersion == other.MSBuildVersion; + } + + public override bool Equals(object obj) + { + return Equals(obj as CompatibleSdkValue); + } + + public override int GetHashCode() + { + int h1 = DotnetExeDirectory.GetHashCode(); + int h2 = MSBuildVersion.GetHashCode(); + return ((h1 << 5) + h1) ^ h2; + } + } + + private sealed class CompatibleSdkValue + { + public readonly string MostRecentCompatible; + public readonly string MostRecentCompatibleNonPreview; + + public CompatibleSdkValue(string mostRecentCompatible, string mostRecentCompatibleNonPreview) + { + MostRecentCompatible = mostRecentCompatible; + MostRecentCompatibleNonPreview = mostRecentCompatibleNonPreview; + } + } + + private string GetMostCompatibleSdk(string dotnetExeDirectory, Version msbuildVersion) + { + CompatibleSdkValue sdks = GetMostCompatibleSdks(dotnetExeDirectory, msbuildVersion); + if (_vsSettings.DisallowPrerelease()) + { + return sdks.MostRecentCompatibleNonPreview; + } + + return sdks.MostRecentCompatible; + } + + private CompatibleSdkValue GetMostCompatibleSdks(string dotnetExeDirectory, Version msbuildVersion) + { + return s_compatibleSdks.GetOrAdd( + new CompatibleSdkKey(dotnetExeDirectory, msbuildVersion), + key => + { + string mostRecent = null; + string mostRecentNonPreview = null; + + string[] availableSdks = NETCoreSdkResolver.GetAvailableSdks(key.DotnetExeDirectory); + for (int i = availableSdks.Length - 1; i >= 0; i--) + { + string netcoreSdkDir = availableSdks[i]; + string netcoreSdkVersion = new DirectoryInfo(netcoreSdkDir).Name; + Version minimumMSBuildVersion = GetMinimumMSBuildVersion(netcoreSdkDir); + + if (key.MSBuildVersion < minimumMSBuildVersion) + { + continue; + } + + if (mostRecent == null) + { + mostRecent = netcoreSdkDir; + } + + if (netcoreSdkVersion.IndexOf('-') < 0) + { + mostRecentNonPreview = netcoreSdkDir; + break; + } + } + + return new CompatibleSdkValue(mostRecent, mostRecentNonPreview); + }); + } + + private Version GetMinimumMSBuildVersion(string netcoreSdkDir) + { + return s_minimumMSBuildVersions.GetOrAdd( + netcoreSdkDir, + dir => + { + string minimumVersionFilePath = Path.Combine(netcoreSdkDir, "minimumMSBuildVersion"); + if (!File.Exists(minimumVersionFilePath)) + { + // smallest version that had resolver support and also + // greater than or equal to the version required by any + // .NET Core SDK that did not have this file. + return new Version(15, 3, 0); + } + + return Version.Parse(File.ReadLines(minimumVersionFilePath).First().Trim()); + }); } private static string GetMinimumVSDefinedSDKVersion() @@ -156,13 +295,24 @@ namespace Microsoft.DotNet.MSBuildSdkResolver return FXVersion.Compare(netCoreSdkFXVersion, minimumFXVersion) < 0; } - private string ResolveNetcoreSdkDirectory(SdkResolverContext context) + private NETCoreSdkResolver.Result ResolveNETCoreSdkDirectory(SdkResolverContext context, string dotnetExeDir) { - string exeDir = GetDotnetExeDirectory(); - string workingDir = context.SolutionFilePath ?? context.ProjectFilePath; - string netcoreSdkDir = Interop.hostfxr_resolve_sdk(exeDir, workingDir); + string globalJsonStartDir = Path.GetDirectoryName(context.SolutionFilePath ?? context.ProjectFilePath); + var result = NETCoreSdkResolver.ResolveSdk(dotnetExeDir, globalJsonStartDir, _vsSettings.DisallowPrerelease()); - return netcoreSdkDir; + if (result.ResolvedSdkDirectory != null + && result.GlobalJsonPath == null + && context.MSBuildVersion < GetMinimumMSBuildVersion(result.ResolvedSdkDirectory)) + { + string mostCompatible = GetMostCompatibleSdk(dotnetExeDir, context.MSBuildVersion); + + if (mostCompatible != null) + { + result.ResolvedSdkDirectory = mostCompatible; + } + } + + return result; } private string GetDotnetExeDirectory() @@ -176,14 +326,12 @@ namespace Microsoft.DotNet.MSBuildSdkResolver var environmentProvider = new EnvironmentProvider(_getEnvironmentVariable); var dotnetExe = environmentProvider.GetCommandPath("dotnet"); -#if NETSTANDARD2_0 if (dotnetExe != null && !Interop.RunningOnWindows) { // e.g. on Linux the 'dotnet' command from PATH is a symlink so we need to // resolve it to get the actual path to the binary - dotnetExe = Interop.realpath(dotnetExe) ?? dotnetExe; + dotnetExe = Interop.Unix.realpath(dotnetExe) ?? dotnetExe; } -#endif return Path.GetDirectoryName(dotnetExe); } diff --git a/src/Microsoft.DotNet.MSBuildSdkResolver/Microsoft.DotNet.MSBuildSdkResolver.csproj b/src/Microsoft.DotNet.MSBuildSdkResolver/Microsoft.DotNet.MSBuildSdkResolver.csproj index 79c1f4797..894771928 100644 --- a/src/Microsoft.DotNet.MSBuildSdkResolver/Microsoft.DotNet.MSBuildSdkResolver.csproj +++ b/src/Microsoft.DotNet.MSBuildSdkResolver/Microsoft.DotNet.MSBuildSdkResolver.csproj @@ -16,7 +16,7 @@ - + @@ -26,6 +26,7 @@ + @@ -40,4 +41,12 @@ + + + + + true + + + diff --git a/src/Microsoft.DotNet.MSBuildSdkResolver/Microsoft.DotNet.MSBuildSdkResolver.sln b/src/Microsoft.DotNet.MSBuildSdkResolver/Microsoft.DotNet.MSBuildSdkResolver.sln index 08c449079..21c171b2e 100644 --- a/src/Microsoft.DotNet.MSBuildSdkResolver/Microsoft.DotNet.MSBuildSdkResolver.sln +++ b/src/Microsoft.DotNet.MSBuildSdkResolver/Microsoft.DotNet.MSBuildSdkResolver.sln @@ -9,14 +9,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.MSBuildSdk EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.Tools.Tests.Utilities", "..\..\test\Microsoft.DotNet.Tools.Tests.Utilities\Microsoft.DotNet.Tools.Tests.Utilities.csproj", "{E548D3D0-50E3-4485-B531-95585A5D0B85}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.TestFramework", "..\Microsoft.DotNet.TestFramework\Microsoft.DotNet.TestFramework.csproj", "{182FFFA6-AE8F-431C-9B17-2F30B2A8FE42}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TestDependencies", "TestDependencies", "{0F45009E-9053-401D-91CA-8046D9EB310B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.DotNet.Cli.Utils", "..\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj", "{7F68DEFE-F2D3-453C-B155-51B674604D29}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.Cli.Utils", "..\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj", "{7F68DEFE-F2D3-453C-B155-51B674604D29}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.InternalAbstractions", "..\Microsoft.DotNet.InternalAbstractions\Microsoft.DotNet.InternalAbstractions.csproj", "{A54567A1-E8DE-4B8C-9156-D895B9D016DB}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.TestFramework", "..\..\test\Microsoft.DotNet.TestFramework\Microsoft.DotNet.TestFramework.csproj", "{47C99775-27DF-4452-A1A3-2182FFA19BF2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -35,10 +35,6 @@ Global {E548D3D0-50E3-4485-B531-95585A5D0B85}.Debug|Any CPU.Build.0 = Debug|Any CPU {E548D3D0-50E3-4485-B531-95585A5D0B85}.Release|Any CPU.ActiveCfg = Release|Any CPU {E548D3D0-50E3-4485-B531-95585A5D0B85}.Release|Any CPU.Build.0 = Release|Any CPU - {182FFFA6-AE8F-431C-9B17-2F30B2A8FE42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {182FFFA6-AE8F-431C-9B17-2F30B2A8FE42}.Debug|Any CPU.Build.0 = Debug|Any CPU - {182FFFA6-AE8F-431C-9B17-2F30B2A8FE42}.Release|Any CPU.ActiveCfg = Release|Any CPU - {182FFFA6-AE8F-431C-9B17-2F30B2A8FE42}.Release|Any CPU.Build.0 = Release|Any CPU {7F68DEFE-F2D3-453C-B155-51B674604D29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7F68DEFE-F2D3-453C-B155-51B674604D29}.Debug|Any CPU.Build.0 = Debug|Any CPU {7F68DEFE-F2D3-453C-B155-51B674604D29}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -47,14 +43,21 @@ Global {A54567A1-E8DE-4B8C-9156-D895B9D016DB}.Debug|Any CPU.Build.0 = Debug|Any CPU {A54567A1-E8DE-4B8C-9156-D895B9D016DB}.Release|Any CPU.ActiveCfg = Release|Any CPU {A54567A1-E8DE-4B8C-9156-D895B9D016DB}.Release|Any CPU.Build.0 = Release|Any CPU + {47C99775-27DF-4452-A1A3-2182FFA19BF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {47C99775-27DF-4452-A1A3-2182FFA19BF2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {47C99775-27DF-4452-A1A3-2182FFA19BF2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {47C99775-27DF-4452-A1A3-2182FFA19BF2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {E548D3D0-50E3-4485-B531-95585A5D0B85} = {0F45009E-9053-401D-91CA-8046D9EB310B} - {182FFFA6-AE8F-431C-9B17-2F30B2A8FE42} = {0F45009E-9053-401D-91CA-8046D9EB310B} {7F68DEFE-F2D3-453C-B155-51B674604D29} = {0F45009E-9053-401D-91CA-8046D9EB310B} {A54567A1-E8DE-4B8C-9156-D895B9D016DB} = {0F45009E-9053-401D-91CA-8046D9EB310B} + {47C99775-27DF-4452-A1A3-2182FFA19BF2} = {0F45009E-9053-401D-91CA-8046D9EB310B} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {DAE5F0E8-9018-4F6B-BB7F-541CA5E0E98B} EndGlobalSection EndGlobal diff --git a/src/Microsoft.DotNet.MSBuildSdkResolver/NETCoreSdkResolver.cs b/src/Microsoft.DotNet.MSBuildSdkResolver/NETCoreSdkResolver.cs new file mode 100644 index 000000000..e00c618d9 --- /dev/null +++ b/src/Microsoft.DotNet.MSBuildSdkResolver/NETCoreSdkResolver.cs @@ -0,0 +1,76 @@ +// 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.Diagnostics; + +namespace Microsoft.DotNet.MSBuildSdkResolver +{ + internal static class NETCoreSdkResolver + { + public sealed class Result + { + /// + /// Path to .NET Core SDK selected by hostfxr (e.g. C:\Program Files\dotnet\sdk\2.1.300). + /// + public string ResolvedSdkDirectory; + + /// + /// Path to global.json file that impacted resolution. + /// + public string GlobalJsonPath; + + public void Initialize(Interop.hostfxr_resolve_sdk2_result_key_t key, string value) + { + switch (key) + { + case Interop.hostfxr_resolve_sdk2_result_key_t.resolved_sdk_dir: + ResolvedSdkDirectory = value; + break; + case Interop.hostfxr_resolve_sdk2_result_key_t.global_json_path: + GlobalJsonPath = value; + break; + } + } + } + + public static Result ResolveSdk( + string dotnetExeDirectory, + string globalJsonStartDirectory, + bool disallowPrerelease = false) + { + var result = new Result(); + var flags = disallowPrerelease ? Interop.hostfxr_resolve_sdk2_flags_t.disallow_prerelease : 0; + + int errorCode = Interop.RunningOnWindows + ? Interop.Windows.hostfxr_resolve_sdk2(dotnetExeDirectory, globalJsonStartDirectory, flags, result.Initialize) + : Interop.Unix.hostfxr_resolve_sdk2(dotnetExeDirectory, globalJsonStartDirectory, flags, result.Initialize); + + Debug.Assert((errorCode == 0) == (result.ResolvedSdkDirectory != null)); + return result; + } + + private sealed class SdkList + { + public string[] Entries; + + public void Initialize(int count, string[] entries) + { + entries = entries ?? Array.Empty(); + Debug.Assert(count == entries.Length); + Entries = entries; + } + } + + public static string[] GetAvailableSdks(string dotnetExeDirectory) + { + var list = new SdkList(); + + int errorCode = Interop.RunningOnWindows + ? Interop.Windows.hostfxr_get_available_sdks(dotnetExeDirectory, list.Initialize) + : Interop.Unix.hostfxr_get_available_sdks(dotnetExeDirectory, list.Initialize); + + return list.Entries; + } + } +} diff --git a/src/Microsoft.DotNet.MSBuildSdkResolver/VSSettings.cs b/src/Microsoft.DotNet.MSBuildSdkResolver/VSSettings.cs new file mode 100644 index 000000000..46dfda2e6 --- /dev/null +++ b/src/Microsoft.DotNet.MSBuildSdkResolver/VSSettings.cs @@ -0,0 +1,155 @@ +// 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.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; + +#if NET46 +using Microsoft.VisualStudio.Setup.Configuration; +#endif + +namespace Microsoft.DotNet.MSBuildSdkResolver +{ + internal sealed class VSSettings + { + private readonly object _lock = new object(); + private readonly string _settingsFilePath; + private readonly bool _disallowPrereleaseByDefault; + private FileInfo _settingsFile; + private bool _disallowPrerelease; + + // In the product, this singleton is used. It must be safe to use in parallel on multiple threads. + // In tests, mock instances can be created with the test constructor below. + public static readonly VSSettings Ambient = new VSSettings(); + + private VSSettings() + { +#if NET46 + if (!Interop.RunningOnWindows) + { + return; + } + + string instanceId; + string installationVersion; + bool isPrerelease; + + try + { + var configuration = new SetupConfiguration(); + var instance = configuration.GetInstanceForCurrentProcess(); + + instanceId = instance.GetInstanceId(); + installationVersion = instance.GetInstallationVersion(); + isPrerelease = ((ISetupInstanceCatalog)instance).IsPrerelease(); + } + catch (COMException) + { + return; + } + + var version = Version.Parse(installationVersion); + + _settingsFilePath = Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), + "Microsoft", + "VisualStudio", + version.Major + ".0_" + instanceId, + "sdk.txt"); + + _disallowPrereleaseByDefault = !isPrerelease; + _disallowPrerelease = _disallowPrereleaseByDefault; +#endif + } + + // Test constructor + public VSSettings(string settingsFilePath, bool disallowPrereleaseByDefault) + { + _settingsFilePath = settingsFilePath; + _disallowPrereleaseByDefault = disallowPrereleaseByDefault; + _disallowPrerelease = _disallowPrereleaseByDefault; + } + + public bool DisallowPrerelease() + { + if (_settingsFilePath != null) + { + Refresh(); + } + + return _disallowPrerelease; + } + + private void Refresh() + { + Debug.Assert(_settingsFilePath != null); + + var file = new FileInfo(_settingsFilePath); + + // NB: All calls to Exists and LastWriteTimeUtc below will not hit the disk + // They will return data obtained during Refresh() here. + file.Refresh(); + + lock (_lock) + { + // File does not exist -> use default. + if (!file.Exists) + { + _disallowPrerelease = _disallowPrereleaseByDefault; + _settingsFile = file; + return; + } + + // File has not changed -> reuse prior read. + if (_settingsFile?.Exists == true && file.LastWriteTimeUtc <= _settingsFile.LastWriteTimeUtc) + { + return; + } + + // File has changed -> read from disk + // If we encounter an I/O exception, assume writer is in the process of updating file, + // ignore the exception, and use stale settings until the next resolution. + try + { + ReadFromDisk(); + _settingsFile = file; + return; + } + catch (IOException) { } + catch (UnauthorizedAccessException) { } + } + } + + private void ReadFromDisk() + { + using (var reader = new StreamReader(_settingsFilePath)) + { + string line; + while ((line = reader.ReadLine()) != null) + { + int indexOfEquals = line.IndexOf('='); + if (indexOfEquals < 0 || indexOfEquals == (line.Length - 1)) + { + continue; + } + + string key = line.Substring(0, indexOfEquals).Trim(); + string value = line.Substring(indexOfEquals + 1).Trim(); + + if (key.Equals("UsePreviews", StringComparison.OrdinalIgnoreCase) + && bool.TryParse(value, out bool usePreviews)) + { + _disallowPrerelease = !usePreviews; + return; + } + } + } + + // File does not have UsePreviews entry -> use default + _disallowPrerelease = _disallowPrereleaseByDefault; + } + } +} + diff --git a/test/Microsoft.DotNet.MSBuildSdkResolver.Tests/GivenAnMSBuildSdkResolver.cs b/test/Microsoft.DotNet.MSBuildSdkResolver.Tests/GivenAnMSBuildSdkResolver.cs index bea3dde7e..55cac8275 100644 --- a/test/Microsoft.DotNet.MSBuildSdkResolver.Tests/GivenAnMSBuildSdkResolver.cs +++ b/test/Microsoft.DotNet.MSBuildSdkResolver.Tests/GivenAnMSBuildSdkResolver.cs @@ -48,7 +48,7 @@ namespace Microsoft.DotNet.Cli.Utils.Tests var resolver = environment.CreateResolver(); var result = (MockResult)resolver.Resolve( new SdkReference("Some.Test.Sdk", null, null), - new MockContext { ProjectFilePath = environment.TestDirectory.FullName }, + new MockContext { ProjectFileDirectory = environment.TestDirectory }, new MockFactory()); result.Success.Should().BeTrue(); @@ -68,7 +68,7 @@ namespace Microsoft.DotNet.Cli.Utils.Tests var resolver = environment.CreateResolver(); var result = (MockResult)resolver.Resolve( new SdkReference("Some.Test.Sdk", null, "999.99.99"), - new MockContext { ProjectFilePath = environment.TestDirectory.FullName }, + new MockContext { ProjectFileDirectory = environment.TestDirectory }, new MockFactory()); result.Success.Should().BeFalse(); @@ -81,7 +81,7 @@ namespace Microsoft.DotNet.Cli.Utils.Tests } [Fact] - public void ItReturnsNullWhenTheSDKRequiresAHigherVersionOfMSBuildThanTheOneAvailable() + public void ItReturnsNullWhenTheSDKRequiresAHigherVersionOfMSBuildThanAnyOneAvailable() { var environment = new TestEnvironment(); var expected = @@ -94,7 +94,7 @@ namespace Microsoft.DotNet.Cli.Utils.Tests new MockContext { MSBuildVersion = new Version(1, 0), - ProjectFilePath = environment.TestDirectory.FullName + ProjectFileDirectory = environment.TestDirectory }, new MockFactory()); @@ -107,6 +107,73 @@ namespace Microsoft.DotNet.Cli.Utils.Tests + " version that requires the MSBuild version currently available."); } + [Theory] + [InlineData(true)] + [InlineData(false)] + public void ItReturnsHighestSdkAvailableThatIsCompatibleWithMSBuild(bool disallowPreviews) + { + var environment = new TestEnvironment(identifier: disallowPreviews.ToString()) + { + DisallowPrereleaseByDefault = disallowPreviews + }; + + var compatibleRtm = environment.CreateSdkDirectory(ProgramFiles.X64, "Some.Test.Sdk", "98.98.98", new Version(19, 0, 0, 0)); + var compatiblePreview = environment.CreateSdkDirectory(ProgramFiles.X64, "Some.Test.Sdk", "99.99.99-preview", new Version(20, 0, 0, 0)); + var incompatible = environment.CreateSdkDirectory(ProgramFiles.X64, "Some.Test.Sdk", "100.100.100", new Version(21, 0, 0, 0)); + + environment.CreateMuxerAndAddToPath(ProgramFiles.X64); + + var resolver = environment.CreateResolver(); + var result = (MockResult)resolver.Resolve( + new SdkReference("Some.Test.Sdk", null, null), + new MockContext + { + MSBuildVersion = new Version(20, 0, 0, 0), + ProjectFileDirectory = environment.TestDirectory, + }, + new MockFactory()); + + result.Success.Should().BeTrue(); + result.Path.Should().Be((disallowPreviews ? compatibleRtm : compatiblePreview).FullName); + result.Version.Should().Be(disallowPreviews ? "98.98.98" : "99.99.99-preview"); + result.Warnings.Should().BeNullOrEmpty(); + result.Errors.Should().BeNullOrEmpty(); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void ItDoesNotReturnHighestSdkAvailableThatIsCompatibleWithMSBuildWhenVersionInGlobalJsonCannotBeFound(bool disallowPreviews) + { + var environment = new TestEnvironment(callingMethod: "ItDoesNotReturnHighest___", identifier: disallowPreviews.ToString()) + { + DisallowPrereleaseByDefault = disallowPreviews + }; + + var compatibleRtm = environment.CreateSdkDirectory(ProgramFiles.X64, "Some.Test.Sdk", "98.98.98", new Version(19, 0, 0, 0)); + var compatiblePreview = environment.CreateSdkDirectory(ProgramFiles.X64, "Some.Test.Sdk", "99.99.99-preview", new Version(20, 0, 0, 0)); + var incompatible = environment.CreateSdkDirectory(ProgramFiles.X64, "Some.Test.Sdk", "100.100.100", new Version(21, 0, 0, 0)); + + environment.CreateMuxerAndAddToPath(ProgramFiles.X64); + environment.CreateGlobalJson(environment.TestDirectory, "1.2.3"); + + var resolver = environment.CreateResolver(); + var result = (MockResult)resolver.Resolve( + new SdkReference("Some.Test.Sdk", null, null), + new MockContext + { + MSBuildVersion = new Version(20, 0, 0, 0), + ProjectFileDirectory = environment.TestDirectory, + }, + new MockFactory()); + + result.Success.Should().BeFalse(); + result.Path.Should().BeNull(); + result.Version.Should().BeNull();; + result.Warnings.Should().BeNullOrEmpty(); + result.Errors.Should().NotBeEmpty(); + } + [Fact] public void ItReturnsNullWhenTheDefaultVSRequiredSDKVersionIsHigherThanTheSDKVersionAvailable() { @@ -118,7 +185,7 @@ namespace Microsoft.DotNet.Cli.Utils.Tests var resolver = environment.CreateResolver(); var result = (MockResult)resolver.Resolve( new SdkReference("Some.Test.Sdk", null, "1.0.0"), - new MockContext { ProjectFilePath = environment.TestDirectory.FullName }, + new MockContext { ProjectFileDirectory = environment.TestDirectory }, new MockFactory()); result.Success.Should().BeFalse(); @@ -142,7 +209,7 @@ namespace Microsoft.DotNet.Cli.Utils.Tests var resolver = environment.CreateResolver(); var result = (MockResult)resolver.Resolve( new SdkReference("Some.Test.Sdk", null, "1.0.0"), - new MockContext { ProjectFilePath = environment.TestDirectory.FullName }, + new MockContext { ProjectFileDirectory = environment.TestDirectory }, new MockFactory()); result.Success.Should().BeFalse(); @@ -165,7 +232,7 @@ namespace Microsoft.DotNet.Cli.Utils.Tests var resolver = environment.CreateResolver(); var result = (MockResult)resolver.Resolve( new SdkReference("Some.Test.Sdk", null, "99.99.99"), - new MockContext { ProjectFilePath = environment.TestDirectory.FullName }, + new MockContext { ProjectFileDirectory = environment.TestDirectory }, new MockFactory()); result.Success.Should().BeTrue(); @@ -186,7 +253,7 @@ namespace Microsoft.DotNet.Cli.Utils.Tests var resolver = environment.CreateResolver(); var result = (MockResult)resolver.Resolve( new SdkReference("Some.Test.Sdk", null, "99.99.99"), - new MockContext { ProjectFilePath = environment.TestDirectory.FullName }, + new MockContext { ProjectFileDirectory = environment.TestDirectory }, new MockFactory()); result.Success.Should().BeTrue(); @@ -196,6 +263,159 @@ namespace Microsoft.DotNet.Cli.Utils.Tests result.Errors.Should().BeNullOrEmpty(); } + [Theory] + [InlineData(true)] + [InlineData(false)] + public void ItDisallowsPreviewsBasedOnDefault(bool disallowPreviewsByDefault) + { + var environment = new TestEnvironment(identifier: disallowPreviewsByDefault.ToString()); + var rtm = environment.CreateSdkDirectory(ProgramFiles.X64, "Some.Test.Sdk", "10.0.0"); + var preview = environment.CreateSdkDirectory(ProgramFiles.X64, "Some.Test.Sdk", "11.0.0-preview1"); + var expected = disallowPreviewsByDefault ? rtm : preview; + + environment.CreateMuxerAndAddToPath(ProgramFiles.X64); + environment.DisallowPrereleaseByDefault = disallowPreviewsByDefault; + + var resolver = environment.CreateResolver(); + var result = (MockResult)resolver.Resolve( + new SdkReference("Some.Test.Sdk", null, null), + new MockContext { ProjectFileDirectory = environment.TestDirectory }, + new MockFactory()); + + result.Success.Should().BeTrue(); + result.Path.Should().Be(expected.FullName); + result.Version.Should().Be(disallowPreviewsByDefault ? "10.0.0" : "11.0.0-preview1"); + result.Warnings.Should().BeNullOrEmpty(); + result.Errors.Should().BeNullOrEmpty(); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void ItDisallowsPreviewsBasedOnFile(bool disallowPreviews) + { + var environment = new TestEnvironment(identifier: disallowPreviews.ToString()); + var rtm = environment.CreateSdkDirectory(ProgramFiles.X64, "Some.Test.Sdk", "10.0.0"); + var preview = environment.CreateSdkDirectory(ProgramFiles.X64, "Some.Test.Sdk", "11.0.0-preview1"); + var expected = disallowPreviews ? rtm : preview; + + environment.CreateMuxerAndAddToPath(ProgramFiles.X64); + environment.DisallowPrereleaseByDefault = !disallowPreviews; + environment.CreateVSSettingsFile(disallowPreviews); + + var resolver = environment.CreateResolver(); + var result = (MockResult)resolver.Resolve( + new SdkReference("Some.Test.Sdk", null, null), + new MockContext { ProjectFileDirectory = environment.TestDirectory }, + new MockFactory()); + + result.Success.Should().BeTrue(); + result.Path.Should().Be(expected.FullName); + result.Version.Should().Be(disallowPreviews ? "10.0.0" : "11.0.0-preview1"); + result.Warnings.Should().BeNullOrEmpty(); + result.Errors.Should().BeNullOrEmpty(); + } + + [Fact] + public void ItObservesChangesToVSSettingsFile() + { + var environment = new TestEnvironment(); + var rtm = environment.CreateSdkDirectory(ProgramFiles.X64, "Some.Test.Sdk", "10.0.0"); + var preview = environment.CreateSdkDirectory(ProgramFiles.X64, "Some.Test.Sdk", "11.0.0-preview1"); + + environment.CreateMuxerAndAddToPath(ProgramFiles.X64); + environment.CreateVSSettingsFile(disallowPreviews: true); + var resolver = environment.CreateResolver(); + + void Check(bool disallowPreviews, string message) + { + // check twice because file-up-to-date is a separate code path + for (int i = 0; i < 2; i++) + { + + var result = (MockResult)resolver.Resolve( + new SdkReference("Some.Test.Sdk", null, null), + new MockContext { ProjectFileDirectory = environment.TestDirectory }, + new MockFactory()); + + string m = $"{message} ({i})"; + var expected = disallowPreviews ? rtm : preview; + result.Success.Should().BeTrue(m); + result.Path.Should().Be(expected.FullName, m); + result.Version.Should().Be(disallowPreviews ? "10.0.0" : "11.0.0-preview1", m); + result.Warnings.Should().BeNullOrEmpty(m); + result.Errors.Should().BeNullOrEmpty(m); + } + } + + environment.DeleteVSSettingsFile(); + Check(disallowPreviews: false, message: "default with no file"); + + environment.CreateVSSettingsFile(disallowPreviews: true); + Check(disallowPreviews: true, message: "file changed to disallow previews"); + + environment.CreateVSSettingsFile(disallowPreviews: false); + Check(disallowPreviews: false, message: "file changed to not disallow previews"); + + environment.CreateVSSettingsFile(disallowPreviews: true); + Check(disallowPreviews: true, message: "file changed back to disallow previews"); + + environment.DeleteVSSettingsFile(); + Check(disallowPreviews: false, message: "file deleted to return to default"); + } + + [Fact] + public void ItAllowsPreviewWhenGlobalJsonHasPreviewIrrespectiveOfSetting() + { + var environment = new TestEnvironment(); + var rtm = environment.CreateSdkDirectory(ProgramFiles.X64, "Some.Test.Sdk", "10.0.0"); + var preview = environment.CreateSdkDirectory(ProgramFiles.X64, "Some.Test.Sdk", "11.0.0-preview1"); + + environment.CreateMuxerAndAddToPath(ProgramFiles.X64); + environment.DisallowPrereleaseByDefault = true; + environment.CreateGlobalJson(environment.TestDirectory, "11.0.0-preview1"); + + var resolver = environment.CreateResolver(); + var result = (MockResult)resolver.Resolve( + new SdkReference("Some.Test.Sdk", null, null), + new MockContext { ProjectFileDirectory = environment.TestDirectory }, + new MockFactory()); + + result.Success.Should().BeTrue(); + result.Path.Should().Be(preview.FullName); + result.Version.Should().Be("11.0.0-preview1"); + result.Warnings.Should().BeNullOrEmpty(); + result.Errors.Should().BeNullOrEmpty(); + } + + [Fact] + public void ItRespectsAmbientVSSettings() + { + // When run in test explorer in VS, this will actually locate the settings for the current VS instance + // based on location of testhost executable. This gives us some coverage threw that path but we cannot + // fix our expectations since the behavior will vary (by design) based on the current VS instance's settings. + var vsSettings = VSSettings.Ambient; + + var environment = new TestEnvironment(); + var rtm = environment.CreateSdkDirectory(ProgramFiles.X64, "Some.Test.Sdk", "10.0.0"); + var preview = environment.CreateSdkDirectory(ProgramFiles.X64, "Some.Test.Sdk", "11.0.0-preview1"); + var expected = vsSettings.DisallowPrerelease() ? rtm : preview; + + environment.CreateMuxerAndAddToPath(ProgramFiles.X64); + + var resolver = environment.CreateResolver(useAmbientSettings: true); + var result = (MockResult)resolver.Resolve( + new SdkReference("Some.Test.Sdk", null, null), + new MockContext { ProjectFileDirectory = environment.TestDirectory }, + new MockFactory()); + + result.Success.Should().BeTrue(); + result.Path.Should().Be(expected.FullName); + result.Version.Should().Be(vsSettings.DisallowPrerelease() ? "10.0.0" : "11.0.0-preview1"); + result.Warnings.Should().BeNullOrEmpty(); + result.Errors.Should().BeNullOrEmpty(); + } + private enum ProgramFiles { X64, @@ -210,6 +430,8 @@ namespace Microsoft.DotNet.Cli.Utils.Tests public string PathEnvironmentVariable { get; set; } public DirectoryInfo TestDirectory { get; } + public FileInfo VSSettingsFile { get; set; } + public bool DisallowPrereleaseByDefault { get; set; } public TestEnvironment(string identifier = "", [CallerMemberName] string callingMethod = "") { @@ -223,8 +445,12 @@ namespace Microsoft.DotNet.Cli.Utils.Tests PathEnvironmentVariable = string.Empty; } - public SdkResolver CreateResolver() - => new DotNetMSBuildSdkResolver(GetEnvironmentVariable); + public SdkResolver CreateResolver(bool useAmbientSettings = false) + => new DotNetMSBuildSdkResolver( + GetEnvironmentVariable, + useAmbientSettings + ? VSSettings.Ambient + : new VSSettings(VSSettingsFile?.FullName, DisallowPrereleaseByDefault)); public DirectoryInfo GetSdkDirectory(ProgramFiles programFiles, string sdkName, string sdkVersion) => TestDirectory.GetDirectory( @@ -317,6 +543,34 @@ namespace Microsoft.DotNet.Cli.Utils.Tests string baseDirectory = AppContext.BaseDirectory; return Path.Combine(baseDirectory, "minimumVSDefinedSDKVersion"); } + + public void CreateVSSettingsFile(bool disallowPreviews) + { + VSSettingsFile = TestDirectory.GetFile("sdk.txt"); + + // Guard against tests writing too fast for the up-to-date check + // It happens more often on Unix due to https://github.com/dotnet/corefx/issues/12403 + var lastWriteTimeUtc = VSSettingsFile.Exists ? VSSettingsFile.LastWriteTimeUtc : DateTime.MinValue; + for (int sleep = 10; sleep < 3000; sleep *= 2) + { + File.WriteAllText(VSSettingsFile.FullName, $"UsePreviews={!disallowPreviews}"); + VSSettingsFile.Refresh(); + + if (VSSettingsFile.LastWriteTimeUtc > lastWriteTimeUtc) + { + return; + } + + System.Threading.Thread.Sleep(sleep); + } + + throw new InvalidOperationException("LastWriteTime is not changing."); + } + + public void DeleteVSSettingsFile() + { + VSSettingsFile.Delete(); + } } private sealed class MockContext : SdkResolverContext @@ -325,6 +579,12 @@ namespace Microsoft.DotNet.Cli.Utils.Tests public new string SolutionFilePath { get => base.SolutionFilePath; set => base.SolutionFilePath = value; } public new Version MSBuildVersion { get => base.MSBuildVersion; set => base.MSBuildVersion = value; } + public DirectoryInfo ProjectFileDirectory + { + get => new DirectoryInfo(Path.GetDirectoryName(ProjectFilePath)); + set => ProjectFilePath = value.GetFile("test.csproj").FullName; + } + public MockContext() { MSBuildVersion = new Version(15, 3, 0); @@ -352,12 +612,7 @@ namespace Microsoft.DotNet.Cli.Utils.Tests Errors = errors; } - public new bool Success - { - get => base.Success; - private set => base.Success = value; - } - + public override bool Success { get; protected set; } public override string Version { get; protected set; } public override string Path { get; protected set; } public IEnumerable Errors { get; } diff --git a/test/Microsoft.DotNet.MSBuildSdkResolver.Tests/Microsoft.DotNet.MSBuildSdkResolver.Tests.csproj b/test/Microsoft.DotNet.MSBuildSdkResolver.Tests/Microsoft.DotNet.MSBuildSdkResolver.Tests.csproj index b480a818f..1b0636beb 100644 --- a/test/Microsoft.DotNet.MSBuildSdkResolver.Tests/Microsoft.DotNet.MSBuildSdkResolver.Tests.csproj +++ b/test/Microsoft.DotNet.MSBuildSdkResolver.Tests/Microsoft.DotNet.MSBuildSdkResolver.Tests.csproj @@ -2,6 +2,14 @@ net461;$(CliTargetFramework) $(CliTargetFramework) + + + net461 + $(MicrosoftNETCoreAppPackageVersion) Exe ../../tools/Key.snk @@ -19,9 +27,9 @@ - - - + + + @@ -32,7 +40,10 @@ - - + + + From a1fd9b00b26e6072ee752e85304ca18c47202dfa Mon Sep 17 00:00:00 2001 From: Andy Gerlicher Date: Tue, 21 Aug 2018 15:31:20 -0700 Subject: [PATCH 18/18] MSBuild 15.9.8-preview --- build/DependencyVersions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/DependencyVersions.props b/build/DependencyVersions.props index 3d0d589e4..6101670e5 100644 --- a/build/DependencyVersions.props +++ b/build/DependencyVersions.props @@ -15,7 +15,7 @@ 3.0.0-preview1-26816-04 - 15.9.0-preview-000006 + 15.9.0-preview-000008 $(MicrosoftBuildPackageVersion) $(MicrosoftBuildPackageVersion) $(MicrosoftBuildPackageVersion)