diff --git a/Microsoft.DotNet.Cli.sln b/Microsoft.DotNet.Cli.sln index 3733528eb..271579431 100644 --- a/Microsoft.DotNet.Cli.sln +++ b/Microsoft.DotNet.Cli.sln @@ -147,8 +147,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.TestFramew EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "redist", "src\redist\redist.csproj", "{098D9321-1201-4974-A75E-F58EBCD98ACF}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "tool_roslyn", "src\tool_roslyn\tool_roslyn.csproj", "{A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "tool_msbuild", "src\tool_msbuild\tool_msbuild.csproj", "{D82A3246-9831-4024-A9B2-1932EEF3D56F}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "tool_nuget", "src\tool_nuget\tool_nuget.csproj", "{BE4C655A-DC54-4408-B739-743456D34111}" @@ -705,30 +703,6 @@ Global {098D9321-1201-4974-A75E-F58EBCD98ACF}.RelWithDebInfo|x64.Build.0 = Release|Any CPU {098D9321-1201-4974-A75E-F58EBCD98ACF}.RelWithDebInfo|x86.ActiveCfg = Release|Any CPU {098D9321-1201-4974-A75E-F58EBCD98ACF}.RelWithDebInfo|x86.Build.0 = Release|Any CPU - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}.Debug|x64.ActiveCfg = Release|Any CPU - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}.Debug|x64.Build.0 = Release|Any CPU - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}.Debug|x86.ActiveCfg = Release|Any CPU - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}.Debug|x86.Build.0 = Release|Any CPU - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}.MinSizeRel|Any CPU.ActiveCfg = Release|Any CPU - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}.MinSizeRel|Any CPU.Build.0 = Release|Any CPU - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}.MinSizeRel|x64.ActiveCfg = Release|Any CPU - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}.MinSizeRel|x64.Build.0 = Release|Any CPU - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}.MinSizeRel|x86.ActiveCfg = Release|Any CPU - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}.MinSizeRel|x86.Build.0 = Release|Any CPU - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}.Release|Any CPU.Build.0 = Release|Any CPU - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}.Release|x64.ActiveCfg = Release|Any CPU - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}.Release|x64.Build.0 = Release|Any CPU - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}.Release|x86.ActiveCfg = Release|Any CPU - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}.Release|x86.Build.0 = Release|Any CPU - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}.RelWithDebInfo|x64.Build.0 = Release|Any CPU - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}.RelWithDebInfo|x86.ActiveCfg = Release|Any CPU - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C}.RelWithDebInfo|x86.Build.0 = Release|Any CPU {D82A3246-9831-4024-A9B2-1932EEF3D56F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D82A3246-9831-4024-A9B2-1932EEF3D56F}.Debug|Any CPU.Build.0 = Debug|Any CPU {D82A3246-9831-4024-A9B2-1932EEF3D56F}.Debug|x64.ActiveCfg = Release|Any CPU @@ -1625,7 +1599,6 @@ Global {570950AD-A080-4F32-980C-F50E312910DF} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} {6592A22C-2386-4E83-A4D3-FC08075C723A} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} {098D9321-1201-4974-A75E-F58EBCD98ACF} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} - {A0670C63-BA7A-4C1B-B9A7-1CA26A7F235C} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} {D82A3246-9831-4024-A9B2-1932EEF3D56F} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} {BE4C655A-DC54-4408-B739-743456D34111} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} {2DFCC95F-75F7-46E1-8F56-256DB4CA98B2} = {0722D325-24C8-4E83-B5AF-0A083E7F0749} diff --git a/README.md b/README.md index b7981d26c..e6d7174b4 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 v1.0.1 release of the .NET Core tools (CLI, MSBuild and the new csproj), see https://dot.net/core. -> **Note:** the release/2.0.0 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/15.5 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? @@ -64,7 +64,7 @@ To download the .NET Core runtime **without** the SDK, visit https://github.com/ > **Note:** Be aware that the following installers are the **latest bits**. If you > want to install the latest released versions, check out the [preceding section](#looking-for-v1-of-the-net-core-tooling). -| Platform | Latest Daily Build
*release/2.0.0*
[![][version-badge]][version] | +| Platform | Latest Daily Build
*release/15.5*
[![][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] | @@ -80,7 +80,7 @@ To download the .NET Core runtime **without** the SDK, visit https://github.com/ | **OpenSUSE 42.1** | tar.gz - See **Linux x64** | -| Latest Coherent Build2
*release/2.0.0* | +| Latest Coherent Build2
*release/15.5* | |:------:| | [![][coherent-version-badge]][coherent-version] | @@ -89,43 +89,43 @@ Reference notes: >

**2**: *A 'coherent' build is defined as a build where the Runtime version matches between the CLI and Asp.NET.* [comment]: # (The latest versions are always the same across all platforms. Just need one to show, so picking win-x64's svg.) -[version]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.0.0/latest.version -[version-badge]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.0.0/win_x64_Release_version_badge.svg -[coherent-version]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.0.0/latest.coherent.version -[coherent-version-badge]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.0.0/win_x86_Release_coherent_badge.svg +[version]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/15.5/latest.version +[version-badge]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/15.5/win_x64_Release_version_badge.svg +[coherent-version]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/15.5/latest.coherent.version +[coherent-version-badge]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/15.5/win_x86_Release_coherent_badge.svg -[win-x64-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.0.0/dotnet-sdk-latest-win-x64.exe -[win-x64-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.0.0/dotnet-sdk-latest-win-x64.exe.sha -[win-x64-zip]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.0.0/dotnet-sdk-latest-win-x64.zip -[win-x64-zip-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.0.0/dotnet-sdk-latest-win-x64.zip.sha +[win-x64-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/15.5/dotnet-sdk-latest-win-x64.exe +[win-x64-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/15.5/dotnet-sdk-latest-win-x64.exe.sha +[win-x64-zip]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/15.5/dotnet-sdk-latest-win-x64.zip +[win-x64-zip-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/15.5/dotnet-sdk-latest-win-x64.zip.sha -[win-x86-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.0.0/dotnet-sdk-latest-win-x86.exe -[win-x86-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.0.0/dotnet-sdk-latest-win-x86.exe.sha -[win-x86-zip]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.0.0/dotnet-sdk-latest-win-x86.zip -[win-x86-zip-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.0.0/dotnet-sdk-latest-win-x86.zip.sha +[win-x86-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/15.5/dotnet-sdk-latest-win-x86.exe +[win-x86-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/15.5/dotnet-sdk-latest-win-x86.exe.sha +[win-x86-zip]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/15.5/dotnet-sdk-latest-win-x86.zip +[win-x86-zip-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/15.5/dotnet-sdk-latest-win-x86.zip.sha -[osx-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.0.0/dotnet-sdk-latest-osx-x64.pkg -[osx-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.0.0/dotnet-sdk-latest-osx-x64.pkg.sha -[osx-targz]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.0.0/dotnet-sdk-latest-osx-x64.tar.gz -[osx-targz-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.0.0/dotnet-sdk-latest-osx-x64.tar.gz.sha +[osx-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/15.5/dotnet-sdk-latest-osx-x64.pkg +[osx-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/15.5/dotnet-sdk-latest-osx-x64.pkg.sha +[osx-targz]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/15.5/dotnet-sdk-latest-osx-x64.tar.gz +[osx-targz-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/15.5/dotnet-sdk-latest-osx-x64.tar.gz.sha -[linux-targz]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.0.0/dotnet-sdk-latest-linux-x64.tar.gz -[linux-targz-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.0.0/dotnet-sdk-latest-linux-x64.tar.gz.sha +[linux-targz]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/15.5/dotnet-sdk-latest-linux-x64.tar.gz +[linux-targz-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/15.5/dotnet-sdk-latest-linux-x64.tar.gz.sha -[ubuntu-14.04-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.0.0/dotnet-sdk-latest-ubuntu-x64.deb -[ubuntu-14.04-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.0.0/dotnet-sdk-latest-ubuntu-x64.deb.sha +[ubuntu-14.04-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/15.5/dotnet-sdk-latest-ubuntu-x64.deb +[ubuntu-14.04-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/15.5/dotnet-sdk-latest-ubuntu-x64.deb.sha -[ubuntu-16.04-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.0.0/dotnet-sdk-latest-ubuntu.16.04-x64.deb -[ubuntu-16.04-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.0.0/dotnet-sdk-latest-ubuntu.16.04-x64.deb.sha +[ubuntu-16.04-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/15.5/dotnet-sdk-latest-ubuntu.16.04-x64.deb +[ubuntu-16.04-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/15.5/dotnet-sdk-latest-ubuntu.16.04-x64.deb.sha -[ubuntu-16.10-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.0.0/dotnet-sdk-latest-ubuntu.16.10-x64.deb -[ubuntu-16.10-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.0.0/dotnet-sdk-latest-ubuntu.16.10-x64.deb.sha +[ubuntu-16.10-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/15.5/dotnet-sdk-latest-ubuntu.16.10-x64.deb +[ubuntu-16.10-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/15.5/dotnet-sdk-latest-ubuntu.16.10-x64.deb.sha -[debian-8-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.0.0/dotnet-sdk-latest-debian-x64.deb -[debian-8-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.0.0/dotnet-sdk-latest-debian-x64.deb.sha +[debian-8-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/15.5/dotnet-sdk-latest-debian-x64.deb +[debian-8-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/15.5/dotnet-sdk-latest-debian-x64.deb.sha -[rhel-7-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/2.0.0/dotnet-sdk-latest-rhel-x64.rpm -[rhel-7-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/2.0.0/dotnet-sdk-latest-rhel-x64.rpm.sha +[rhel-7-installer]: https://dotnetcli.blob.core.windows.net/dotnet/Sdk/release/15.5/dotnet-sdk-latest-rhel-x64.rpm +[rhel-7-installer-checksum]: https://dotnetclichecksums.blob.core.windows.net/dotnet/Sdk/release/15.5/dotnet-sdk-latest-rhel-x64.rpm.sha # Debian daily feed diff --git a/TestAssets/TestProjects/MSBuildIntegration/build.proj b/TestAssets/TestProjects/MSBuildIntegration/build.proj index 203f96df3..8b2a7851e 100644 --- a/TestAssets/TestProjects/MSBuildIntegration/build.proj +++ b/TestAssets/TestProjects/MSBuildIntegration/build.proj @@ -29,9 +29,6 @@ - - diff --git a/build/BranchInfo.props b/build/BranchInfo.props index 0d146ab2a..f048a677e 100644 --- a/build/BranchInfo.props +++ b/build/BranchInfo.props @@ -1,6 +1,6 @@ - release/2.0.0 - release/2.0.0 + release/15.5 + release/15.5 diff --git a/build/Branding.props b/build/Branding.props index 7b126782e..53775a170 100644 --- a/build/Branding.props +++ b/build/Branding.props @@ -1,6 +1,6 @@ - Microsoft .NET Core SDK - 2.0.3 + Microsoft .NET Core SDK - 2.1.1 .NET Standard Support for Visual Studio 2015 Microsoft .NET Core Runtime - 2.0.1 Microsoft .NET Core Host - 2.0.1 diff --git a/build/DependencyVersions.props b/build/DependencyVersions.props index 96de35ea2..741bd54e4 100644 --- a/build/DependencyVersions.props +++ b/build/DependencyVersions.props @@ -2,29 +2,31 @@ 2.0.3 - 15.4.8 - 2.3.2-beta1-61921-05 - 2.3.0-pre-20170727-1 + 15.5.179 + 2.6.0-beta3-62309-01 1.6.0-beta2-25304 - 4.2.0-rtm-171027-0 - 4.4.1-pre-20170727-1 + 4.2.0-rtm-171104-0 + pre-20171012-1 + 2.6.0-$(CLI_Deps_Satellites_Build) + 4.4.1-$(CLI_Deps_Satellites_Build) - 2.0.3-servicing-20171109-3 + 15.5.0-preview-20171116-1 $(CLI_NETSDK_Version) - 4.4.0-preview3-4475 - 2.0.0-preview3-25514-04 - 2.0.0-rel-20170908-653 - 15.3.0-preview-20170628-02 + 4.5.0-rtm-4651 + 2.0.1-servicing-25908-02 + 2.0.0-rel-20171010-665 + 15.5.0 $(CLI_SharedFrameworkVersion) $(CLI_SharedFrameworkVersion) $(CLI_SharedFrameworkVersion) - 1.0.0-beta2-20170810-304 - 1.0.0-beta2-20170810-304 - 1.0.0-beta2-20170810-304 + 1.0.0-beta2-20171004-309 + 1.0.0-beta3-20171110-312 + 1.0.0-beta3-20171110-312 + 1.0.0-beta2-20170810-304 2.0.0 2.0.0 0.1.1-alpha-167 diff --git a/build/Microsoft.DotNet.Cli.tasks b/build/Microsoft.DotNet.Cli.tasks index 901a48f84..1c846d8b0 100644 --- a/build/Microsoft.DotNet.Cli.tasks +++ b/build/Microsoft.DotNet.Cli.tasks @@ -1,6 +1,7 @@ + diff --git a/build/Version.props b/build/Version.props index 2f7ba1395..4c47fdeba 100644 --- a/build/Version.props +++ b/build/Version.props @@ -1,9 +1,9 @@ 2 - 0 - 3 - servicing + 1 + 1 + preview $(VersionMajor).$(VersionMinor).$(VersionPatch)-$(ReleaseSuffix) $(VersionMajor).$(VersionMinor).$(VersionPatch).$(CommitCount) diff --git a/build_projects/Microsoft.DotNet.Cli.Build.SelfTest/InvokeWithStage2.proj b/build_projects/Microsoft.DotNet.Cli.Build.SelfTest/InvokeWithStage2.proj index 1493128e7..cb833d480 100644 --- a/build_projects/Microsoft.DotNet.Cli.Build.SelfTest/InvokeWithStage2.proj +++ b/build_projects/Microsoft.DotNet.Cli.Build.SelfTest/InvokeWithStage2.proj @@ -7,8 +7,6 @@ false true - false - true false true diff --git a/build_projects/dotnet-cli-build/AddToDeps.cs b/build_projects/dotnet-cli-build/AddToDeps.cs new file mode 100644 index 000000000..ca02cd474 --- /dev/null +++ b/build_projects/dotnet-cli-build/AddToDeps.cs @@ -0,0 +1,67 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.IO; +using System.Linq; + +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using Microsoft.Extensions.DependencyModel; + +namespace Microsoft.DotNet.Cli.Build +{ + /// + /// Merges additional .deps.json files into target .deps.json files. + /// + public class AddToDeps : Task + { + /// + /// Paths to target .deps.json files, into which will be merged. + /// These files will be overwritten with the merge result. + /// + [Required] + public string[] TargetDeps { get; set; } + + /// + /// Paths to additional .deps.json files to merge into . + /// + [Required] + public string[] AdditionalDeps { get; set; } + + public override bool Execute() + { + DependencyContext additionalContext = Read(AdditionalDeps.First()); + + foreach (string additionalPath in AdditionalDeps.Skip(1)) + { + additionalContext = additionalContext.Merge(Read(additionalPath)); + } + + foreach (string targetPath in TargetDeps) + { + DependencyContext targetContext = Read(targetPath).Merge(additionalContext); + Write(targetContext, targetPath); + } + + return true; + } + + private static DependencyContext Read(string path) + { + using (FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read)) + using (var reader = new DependencyContextJsonReader()) + { + return reader.Read(stream); + } + } + + private static void Write(DependencyContext context, string path) + { + using (FileStream stream = File.Open(path, FileMode.Create, FileAccess.Write, FileShare.Read)) + { + var writer = new DependencyContextWriter(); // unlike reader, writer is not disposable + writer.Write(context, stream); + } + } + } +} \ No newline at end of file diff --git a/build_projects/dotnet-cli-build/dotnet-cli-build.csproj b/build_projects/dotnet-cli-build/dotnet-cli-build.csproj index 86531abc4..07a4de29d 100644 --- a/build_projects/dotnet-cli-build/dotnet-cli-build.csproj +++ b/build_projects/dotnet-cli-build/dotnet-cli-build.csproj @@ -30,5 +30,6 @@ + diff --git a/resources/MSBuildImports/15.0/Microsoft.Common.targets/ImportAfter/Microsoft.NuGet.ImportAfter.targets b/resources/MSBuildImports/15.0/Microsoft.Common.targets/ImportAfter/Microsoft.NuGet.ImportAfter.targets deleted file mode 100644 index 433922aac..000000000 --- a/resources/MSBuildImports/15.0/Microsoft.Common.targets/ImportAfter/Microsoft.NuGet.ImportAfter.targets +++ /dev/null @@ -1,18 +0,0 @@ - - - - - $(MSBuildExtensionsPath)\NuGet.targets - - - diff --git a/src/Microsoft.DotNet.Cli.Utils/MSBuildForwardingAppWithoutLogging.cs b/src/Microsoft.DotNet.Cli.Utils/MSBuildForwardingAppWithoutLogging.cs index 500ab7b30..39c7fb2df 100644 --- a/src/Microsoft.DotNet.Cli.Utils/MSBuildForwardingAppWithoutLogging.cs +++ b/src/Microsoft.DotNet.Cli.Utils/MSBuildForwardingAppWithoutLogging.cs @@ -23,9 +23,8 @@ namespace Microsoft.DotNet.Cli.Utils new Dictionary { { "MSBuildExtensionsPath", AppContext.BaseDirectory }, - { "CscToolExe", GetRunCscPath() }, - { "VbcToolExe", GetRunVbcPath() }, - { "MSBuildSDKsPath", GetMSBuildSDKsPath() } + { "MSBuildSDKsPath", GetMSBuildSDKsPath() }, + { "DOTNET_HOST_PATH", GetDotnetPath() }, }; private readonly IEnumerable _msbuildRequiredParameters = @@ -78,20 +77,9 @@ namespace Microsoft.DotNet.Cli.Utils SdksDirectoryName); } - private static string GetRunVbcPath() + private static string GetDotnetPath() { - return GetRunToolPath("Vbc"); - } - - private static string GetRunCscPath() - { - return GetRunToolPath("Csc"); - } - - private static string GetRunToolPath(string compilerName) - { - var scriptExtension = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".cmd" : ".sh"; - return Path.Combine(AppContext.BaseDirectory, "Roslyn", $"Run{compilerName}{scriptExtension}"); + return new Muxer().MuxerPath; } } } diff --git a/src/Microsoft.DotNet.Cli.Utils/TelemetryEventEntry.cs b/src/Microsoft.DotNet.Cli.Utils/TelemetryEventEntry.cs index fbbf9d559..7b8214c5b 100644 --- a/src/Microsoft.DotNet.Cli.Utils/TelemetryEventEntry.cs +++ b/src/Microsoft.DotNet.Cli.Utils/TelemetryEventEntry.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; namespace Microsoft.DotNet.Cli.Utils { @@ -83,5 +84,11 @@ namespace Microsoft.DotNet.Cli.Utils public string EventName { get; } public IDictionary Properties { get; } public IDictionary Measurements { get; } + + public ApplicationInsightsEntryFormat WithAppliedToPropertiesValue(Func func) + { + var appliedProperties = Properties.ToDictionary(p => p.Key, p => func(p.Value)); + return new ApplicationInsightsEntryFormat(EventName, appliedProperties, Measurements); + } } } diff --git a/src/dotnet/Program.cs b/src/dotnet/Program.cs index 6a929f4ce..6fb3c6512 100644 --- a/src/dotnet/Program.cs +++ b/src/dotnet/Program.cs @@ -82,6 +82,7 @@ namespace Microsoft.DotNet.Cli var command = string.Empty; var lastArg = 0; var cliFallbackFolderPathCalculator = new CliFallbackFolderPathCalculator(); + TopLevelCommandParserResult topLevelCommandParserResult = TopLevelCommandParserResult.Empty; using (INuGetCacheSentinel nugetCacheSentinel = new NuGetCacheSentinel(cliFallbackFolderPathCalculator)) using (IFirstTimeUseNoticeSentinel disposableFirstTimeUseNoticeSentinel = new FirstTimeUseNoticeSentinel(cliFallbackFolderPathCalculator)) @@ -120,7 +121,13 @@ namespace Microsoft.DotNet.Cli // It's the command, and we're done! command = args[lastArg]; - if (IsDotnetBeingInvokedFromNativeInstaller(command)) + if (string.IsNullOrEmpty(command)) + { + command = "help"; + } + + topLevelCommandParserResult = new TopLevelCommandParserResult(args[lastArg]); + if (IsDotnetBeingInvokedFromNativeInstaller(topLevelCommandParserResult)) { firstTimeUseNoticeSentinel = new NoOpFirstTimeUseNoticeSentinel(); } @@ -144,7 +151,7 @@ namespace Microsoft.DotNet.Cli telemetryClient = new Telemetry.Telemetry(firstTimeUseNoticeSentinel); } TelemetryEventEntry.Subscribe(telemetryClient.TrackEvent); - TelemetryEventEntry.TelemetryFilter = new TelemetryFilter(); + TelemetryEventEntry.TelemetryFilter = new TelemetryFilter(Sha256Hasher.HashWithNormalizedCasing); } IEnumerable appArgs = @@ -158,23 +165,18 @@ namespace Microsoft.DotNet.Cli Console.WriteLine($"Telemetry is: {(telemetryClient.Enabled ? "Enabled" : "Disabled")}"); } - if (string.IsNullOrEmpty(command)) - { - command = "help"; - } - - TelemetryEventEntry.TrackEvent(command, null, null); + TelemetryEventEntry.SendFiltered(topLevelCommandParserResult); int exitCode; - if (BuiltInCommandsCatalog.Commands.TryGetValue(command, out var builtIn)) + if (BuiltInCommandsCatalog.Commands.TryGetValue(topLevelCommandParserResult.Command, out var builtIn)) { - TelemetryEventEntry.SendFiltered(Parser.Instance.ParseFrom($"dotnet {command}", appArgs.ToArray())); + TelemetryEventEntry.SendFiltered(Parser.Instance.ParseFrom($"dotnet {topLevelCommandParserResult.Command}", appArgs.ToArray())); exitCode = builtIn.Command(appArgs.ToArray()); } else { CommandResult result = Command.Create( - "dotnet-" + command, + "dotnet-" + topLevelCommandParserResult.Command, appArgs, FrameworkConstants.CommonFrameworks.NetStandardApp15) .Execute(); @@ -183,9 +185,9 @@ namespace Microsoft.DotNet.Cli return exitCode; } - private static bool IsDotnetBeingInvokedFromNativeInstaller(string command) + private static bool IsDotnetBeingInvokedFromNativeInstaller(TopLevelCommandParserResult parseResult) { - return command == "internal-reportinstallsuccess"; + return parseResult.Command == "internal-reportinstallsuccess"; } private static void ConfigureDotNetForFirstTimeUse( @@ -268,7 +270,7 @@ namespace Microsoft.DotNet.Cli string currentRid = RuntimeEnvironment.GetRuntimeIdentifier(); - // if the current RID isn't supported by the shared framework, display the RID the CLI was + // if the current RID isn't supported by the shared framework, display the RID the CLI was // built with instead, so the user knows which RID they should put in their "runtimes" section. return fxDepsFile.IsRuntimeSupported(currentRid) ? currentRid : diff --git a/src/dotnet/Telemetry/AllowListToSendFirstAppliedOptions.cs b/src/dotnet/Telemetry/AllowListToSendFirstAppliedOptions.cs index 5670f6687..dd7c43883 100644 --- a/src/dotnet/Telemetry/AllowListToSendFirstAppliedOptions.cs +++ b/src/dotnet/Telemetry/AllowListToSendFirstAppliedOptions.cs @@ -29,9 +29,10 @@ namespace Microsoft.DotNet.Cli.Telemetry if (firstOption != null) { result.Add(new ApplicationInsightsEntryFormat( - "dotnet-" + topLevelCommandNameFromParse, + "sublevelparser/command", new Dictionary { + { "verb", topLevelCommandNameFromParse}, {"argument", firstOption} })); } diff --git a/src/dotnet/Telemetry/AllowListToSendFirstArgument.cs b/src/dotnet/Telemetry/AllowListToSendFirstArgument.cs index b18c6e4f4..1b30384de 100644 --- a/src/dotnet/Telemetry/AllowListToSendFirstArgument.cs +++ b/src/dotnet/Telemetry/AllowListToSendFirstArgument.cs @@ -31,9 +31,10 @@ namespace Microsoft.DotNet.Cli.Telemetry if (firstArgument != null) { result.Add(new ApplicationInsightsEntryFormat( - "dotnet-" + topLevelCommandNameFromParse, + "sublevelparser/command", new Dictionary { + {"verb", topLevelCommandNameFromParse}, {"argument", firstArgument} })); } diff --git a/src/dotnet/Telemetry/Sha256Hasher.cs b/src/dotnet/Telemetry/Sha256Hasher.cs index bbe7cfdfb..f077b8fb8 100644 --- a/src/dotnet/Telemetry/Sha256Hasher.cs +++ b/src/dotnet/Telemetry/Sha256Hasher.cs @@ -17,6 +17,11 @@ namespace Microsoft.DotNet.Cli.Telemetry return HashInFormat(sha256, text); } + public static string HashWithNormalizedCasing(string text) + { + return Hash(text.ToUpperInvariant()); + } + private static string HashInFormat(SHA256 sha256, string text) { byte[] bytes = Encoding.UTF8.GetBytes(text); diff --git a/src/dotnet/Telemetry/Telemetry.cs b/src/dotnet/Telemetry/Telemetry.cs index fe1209339..2a88de24f 100644 --- a/src/dotnet/Telemetry/Telemetry.cs +++ b/src/dotnet/Telemetry/Telemetry.cs @@ -120,7 +120,7 @@ namespace Microsoft.DotNet.Cli.Telemetry Dictionary eventProperties = GetEventProperties(properties); Dictionary eventMeasurements = GetEventMeasures(measurements); - _client.TrackEvent(eventName, eventProperties, eventMeasurements); + _client.TrackEvent(PrependProducerNamespace(eventName), eventProperties, eventMeasurements); _client.Flush(); } catch (Exception e) @@ -129,6 +129,11 @@ namespace Microsoft.DotNet.Cli.Telemetry } } + private static string PrependProducerNamespace(string eventName) + { + return "dotnet/cli/" + eventName; + } + private Dictionary GetEventMeasures(IDictionary measurements) { Dictionary eventMeasurements = new Dictionary(_commonMeasurements); diff --git a/src/dotnet/Telemetry/TelemetryFilter.cs b/src/dotnet/Telemetry/TelemetryFilter.cs index 6d44ef58d..e71b76306 100644 --- a/src/dotnet/Telemetry/TelemetryFilter.cs +++ b/src/dotnet/Telemetry/TelemetryFilter.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Collections.Generic; +using System; using System.Linq; using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.Utils; @@ -11,48 +12,15 @@ namespace Microsoft.DotNet.Cli.Telemetry internal class TelemetryFilter : ITelemetryFilter { private const string DotnetName = "dotnet"; + private readonly Func _hash; + + public TelemetryFilter(Func hash) + { + _hash = hash ?? throw new ArgumentNullException(nameof(hash)); + } public IEnumerable Filter(object objectToFilter) { - var ruleSet = new List - { new AllowListToSendFirstArgument(new HashSet{ "new", "help" }), - new AllowListToSendFirstAppliedOptions(new HashSet{ "add", "remove", "list", "sln", "nuget" }), - new TopLevelCommandNameAndOptionToLog - ( - topLevelCommandName: new HashSet { "new" }, - optionsToLog: new HashSet { "language" } - ), - new TopLevelCommandNameAndOptionToLog - ( - topLevelCommandName: new HashSet { "build", "publish" }, - optionsToLog: new HashSet { "framework", "runtime", "configuration" } - ), - new TopLevelCommandNameAndOptionToLog - ( - topLevelCommandName: new HashSet { "run", "clean", "test" }, - optionsToLog: new HashSet { "framework", "configuration" } - ), - new TopLevelCommandNameAndOptionToLog - ( - topLevelCommandName: new HashSet { "pack" }, - optionsToLog: new HashSet { "configuration" } - ), - new TopLevelCommandNameAndOptionToLog - ( - topLevelCommandName: new HashSet { "migrate" }, - optionsToLog: new HashSet { "sdk-package-version" } - ), - new TopLevelCommandNameAndOptionToLog - ( - topLevelCommandName: new HashSet { "vstest" }, - optionsToLog: new HashSet { "platform", "framework", "logger" } - ), - new TopLevelCommandNameAndOptionToLog - ( - topLevelCommandName: new HashSet { "publish" }, - optionsToLog: new HashSet { "runtime" } - ) - }; var result = new List(); if (objectToFilter is ParseResult parseResult) @@ -62,16 +30,73 @@ namespace Microsoft.DotNet.Cli.Telemetry { LogVerbosityForAllTopLevelCommand(result, parseResult, topLevelCommandName); - foreach (IParseResultLogRule rule in ruleSet) + foreach (IParseResultLogRule rule in ParseResultLogRules) { result.AddRange(rule.AllowList(parseResult)); } } } + else if(objectToFilter is TopLevelCommandParserResult topLevelCommandParserResult) + { + result.Add(new ApplicationInsightsEntryFormat( + "toplevelparser/command", + new Dictionary() + {{ "verb", topLevelCommandParserResult.Command}} + )); - return result; + } + else if (objectToFilter is InstallerSuccessReport installerSuccessReport) + { + result.Add(new ApplicationInsightsEntryFormat( + "install/reportsuccess", + new Dictionary {{ "exeName", installerSuccessReport.ExeName}} + )); + } + + return result.Select(r => r.WithAppliedToPropertiesValue(_hash)).ToList(); } + private static List ParseResultLogRules => new List + { + new AllowListToSendFirstArgument(new HashSet {"new", "help"}), + new AllowListToSendFirstAppliedOptions(new HashSet {"add", "remove", "list", "sln", "nuget"}), + new TopLevelCommandNameAndOptionToLog + ( + topLevelCommandName: new HashSet {"new"}, + optionsToLog: new HashSet {"language"} + ), + new TopLevelCommandNameAndOptionToLog + ( + topLevelCommandName: new HashSet {"build", "publish"}, + optionsToLog: new HashSet {"framework", "runtime", "configuration"} + ), + new TopLevelCommandNameAndOptionToLog + ( + topLevelCommandName: new HashSet {"run", "clean", "test"}, + optionsToLog: new HashSet {"framework", "configuration"} + ), + new TopLevelCommandNameAndOptionToLog + ( + topLevelCommandName: new HashSet {"pack"}, + optionsToLog: new HashSet {"configuration"} + ), + new TopLevelCommandNameAndOptionToLog + ( + topLevelCommandName: new HashSet {"migrate"}, + optionsToLog: new HashSet {"sdk-package-version"} + ), + new TopLevelCommandNameAndOptionToLog + ( + topLevelCommandName: new HashSet {"vstest"}, + optionsToLog: new HashSet {"platform", "framework", "logger"} + ), + new TopLevelCommandNameAndOptionToLog + ( + topLevelCommandName: new HashSet {"publish"}, + optionsToLog: new HashSet {"runtime"} + ) + }; + private static void LogVerbosityForAllTopLevelCommand( ICollection result, ParseResult parseResult, @@ -84,9 +109,10 @@ namespace Microsoft.DotNet.Cli.Telemetry parseResult[DotnetName][topLevelCommandName].AppliedOptions["verbosity"]; result.Add(new ApplicationInsightsEntryFormat( - "dotnet-" + topLevelCommandName, + "sublevelparser/command", new Dictionary() { + { "verb", topLevelCommandName}, {"verbosity", appliedOptions.Arguments.ElementAt(0)} })); } diff --git a/src/dotnet/Telemetry/TopLevelCommandNameAndOptionToLog.cs b/src/dotnet/Telemetry/TopLevelCommandNameAndOptionToLog.cs index 38a234541..9a9e6a449 100644 --- a/src/dotnet/Telemetry/TopLevelCommandNameAndOptionToLog.cs +++ b/src/dotnet/Telemetry/TopLevelCommandNameAndOptionToLog.cs @@ -36,9 +36,10 @@ namespace Microsoft.DotNet.Cli.Telemetry parseResult[DotnetName][topLevelCommandName] .AppliedOptions[option]; result.Add(new ApplicationInsightsEntryFormat( - "dotnet-" + topLevelCommandName, + "sublevelparser/command", new Dictionary { + { "verb", topLevelCommandName}, {option, appliedOptions.Arguments.ElementAt(0)} })); } diff --git a/src/dotnet/TopLevelCommandParserResult.cs b/src/dotnet/TopLevelCommandParserResult.cs new file mode 100644 index 000000000..64a9b837e --- /dev/null +++ b/src/dotnet/TopLevelCommandParserResult.cs @@ -0,0 +1,21 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + + +namespace Microsoft.DotNet.Cli +{ + internal class TopLevelCommandParserResult + { + public static TopLevelCommandParserResult Empty + { + get { return new TopLevelCommandParserResult(string.Empty); } + } + + public string Command { get; } + + public TopLevelCommandParserResult(string command) + { + Command = command; + } + } +} diff --git a/src/dotnet/commands/RestoringCommand.cs b/src/dotnet/commands/RestoringCommand.cs index 0239fd69b..8d4f3c923 100644 --- a/src/dotnet/commands/RestoringCommand.cs +++ b/src/dotnet/commands/RestoringCommand.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System; using System.Collections.Generic; using System.Linq; using Microsoft.DotNet.Tools.MSBuild; @@ -10,26 +11,7 @@ namespace Microsoft.DotNet.Tools { public class RestoringCommand : MSBuildForwardingApp { - private bool NoRestore { get; } - - private IEnumerable ParsedArguments { get; } - - private IEnumerable TrailingArguments { get; } - - private IEnumerable ArgsToForwardToRestore() - { - var restoreArguments = ParsedArguments.Where(a => - !a.StartsWith("/p:TargetFramework")); - - if (!restoreArguments.Any(a => a.StartsWith("/verbosity:"))) - { - restoreArguments = restoreArguments.Concat(new string[] { "/verbosity:q" }); - } - - return restoreArguments.Concat(TrailingArguments); - } - - private bool ShouldRunImplicitRestore => !NoRestore; + public RestoreCommand SeparateRestoreCommand { get; } public RestoringCommand( IEnumerable msbuildArgs, @@ -37,18 +19,64 @@ namespace Microsoft.DotNet.Tools IEnumerable trailingArguments, bool noRestore, string msbuildPath = null) - : base(msbuildArgs, msbuildPath) + : base(GetCommandArguments(msbuildArgs, parsedArguments, noRestore), msbuildPath) { - NoRestore = noRestore; - ParsedArguments = parsedArguments; - TrailingArguments = trailingArguments; + SeparateRestoreCommand = GetSeparateRestoreCommand(parsedArguments, trailingArguments, noRestore, msbuildPath); } + private static IEnumerable GetCommandArguments( + IEnumerable msbuildArgs, + IEnumerable parsedArguments, + bool noRestore) + { + if (noRestore) + { + return msbuildArgs; + } + + if (HasArgumentToExcludeFromRestore(parsedArguments)) + { + return Prepend("/nologo", msbuildArgs); + } + + return Prepend("/restore", msbuildArgs); + } + + private static RestoreCommand GetSeparateRestoreCommand( + IEnumerable parsedArguments, + IEnumerable trailingArguments, + bool noRestore, + string msbuildPath) + { + if (noRestore || !HasArgumentToExcludeFromRestore(parsedArguments)) + { + return null; + } + + var restoreArguments = parsedArguments + .Where(a => !IsExcludedFromRestore(a)) + .Concat(trailingArguments); + + return RestoreCommand.FromArgs( + restoreArguments.ToArray(), + msbuildPath, + noLogo: false); + } + + private static IEnumerable Prepend(string argument, IEnumerable arguments) + => new[] { argument }.Concat(arguments); + + private static bool HasArgumentToExcludeFromRestore(IEnumerable arguments) + => arguments.Any(a => IsExcludedFromRestore(a)); + + private static bool IsExcludedFromRestore(string argument) + => argument.StartsWith("/p:TargetFramework=", StringComparison.Ordinal); + public override int Execute() { - if (ShouldRunImplicitRestore) + if (SeparateRestoreCommand != null) { - int exitCode = RestoreCommand.Run(ArgsToForwardToRestore().ToArray()); + int exitCode = SeparateRestoreCommand.Execute(); if (exitCode != 0) { return exitCode; diff --git a/src/dotnet/commands/dotnet-build/BuildCommand.cs b/src/dotnet/commands/dotnet-build/BuildCommand.cs index c7127353b..3fcee0925 100644 --- a/src/dotnet/commands/dotnet-build/BuildCommand.cs +++ b/src/dotnet/commands/dotnet-build/BuildCommand.cs @@ -37,6 +37,8 @@ namespace Microsoft.DotNet.Tools.Build var appliedBuildOptions = result["dotnet"]["build"]; + msbuildArgs.Add($"/clp:Summary"); + if (appliedBuildOptions.HasOption("--no-incremental")) { msbuildArgs.Add("/t:Rebuild"); @@ -50,8 +52,6 @@ namespace Microsoft.DotNet.Tools.Build msbuildArgs.AddRange(appliedBuildOptions.Arguments); - msbuildArgs.Add($"/clp:Summary"); - bool noRestore = appliedBuildOptions.HasOption("--no-restore"); return new BuildCommand( diff --git a/src/dotnet/commands/dotnet-internal-reportinstallsuccess/InternalReportinstallsuccessCommand.cs b/src/dotnet/commands/dotnet-internal-reportinstallsuccess/InternalReportinstallsuccessCommand.cs index b44e9b41c..dc91364e5 100644 --- a/src/dotnet/commands/dotnet-internal-reportinstallsuccess/InternalReportinstallsuccessCommand.cs +++ b/src/dotnet/commands/dotnet-internal-reportinstallsuccess/InternalReportinstallsuccessCommand.cs @@ -5,6 +5,7 @@ using System; using System.Linq; using System.IO; using System.Collections.Generic; +using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Configurer; using Microsoft.DotNet.Cli.Telemetry; @@ -28,12 +29,13 @@ namespace Microsoft.DotNet.Cli var result = parser.ParseFrom("dotnet internal-reportinstallsuccess", args); var internalReportinstallsuccess = result["dotnet"]["internal-reportinstallsuccess"]; - var exeName = Path.GetFileName(internalReportinstallsuccess.Arguments.Single()); - telemetry.TrackEvent( - "reportinstallsuccess", - new Dictionary { { "exeName", exeName } }, - new Dictionary()); + + var filter = new TelemetryFilter(Sha256Hasher.HashWithNormalizedCasing); + foreach (var e in filter.Filter(new InstallerSuccessReport(exeName))) + { + telemetry.TrackEvent(e.EventName, e.Properties, null); + } } internal class ThreadBlockingTelemetry : ITelemetry @@ -54,4 +56,14 @@ namespace Microsoft.DotNet.Cli } } } + + internal class InstallerSuccessReport + { + public string ExeName { get; } + + public InstallerSuccessReport(string exeName) + { + ExeName = exeName ?? throw new ArgumentNullException(nameof(exeName)); + } + } } \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-msbuild/MSBuildLogger.cs b/src/dotnet/commands/dotnet-msbuild/MSBuildLogger.cs index ef9d7d93e..1a6433f90 100644 --- a/src/dotnet/commands/dotnet-msbuild/MSBuildLogger.cs +++ b/src/dotnet/commands/dotnet-msbuild/MSBuildLogger.cs @@ -7,6 +7,7 @@ using Microsoft.Build.Utilities; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.Telemetry; using Microsoft.DotNet.Configurer; +using System.Collections.Generic; namespace Microsoft.DotNet.Tools.MSBuild { @@ -15,6 +16,9 @@ namespace Microsoft.DotNet.Tools.MSBuild private readonly IFirstTimeUseNoticeSentinel _sentinel = new FirstTimeUseNoticeSentinel(new CliFallbackFolderPathCalculator()); private readonly ITelemetry _telemetry; + private const string NewEventName = "msbuild"; + private const string TargetFrameworkTelemetryEventName = "targetframeworkeval"; + private const string TargetFrameworkVersionTelemetryPropertyKey= "TargetFrameworkVersion"; public MSBuildLogger() { @@ -52,9 +56,24 @@ namespace Microsoft.DotNet.Tools.MSBuild } } + internal static void FormatAndSend(ITelemetry telemetry, TelemetryEventArgs args) + { + if (args.EventName == TargetFrameworkTelemetryEventName) + { + var newEventName = $"msbuild/{TargetFrameworkTelemetryEventName}"; + Dictionary maskedProperties = new Dictionary(); + if (args.Properties.TryGetValue(TargetFrameworkVersionTelemetryPropertyKey, out string value)) + { + maskedProperties.Add(TargetFrameworkVersionTelemetryPropertyKey, Sha256Hasher.HashWithNormalizedCasing(value)); + } + + telemetry.TrackEvent(newEventName, maskedProperties, measurements: null); + } + } + private void OnTelemetryLogged(object sender, TelemetryEventArgs args) { - _telemetry.TrackEvent(args.EventName, args.Properties, measurements: null); + FormatAndSend(_telemetry, args); } public override void Shutdown() diff --git a/src/dotnet/commands/dotnet-new/NewCommandShim.cs b/src/dotnet/commands/dotnet-new/NewCommandShim.cs index cf30e3ca4..4b92bdaa8 100644 --- a/src/dotnet/commands/dotnet-new/NewCommandShim.cs +++ b/src/dotnet/commands/dotnet-new/NewCommandShim.cs @@ -41,7 +41,7 @@ namespace Microsoft.DotNet.Tools.New { if (telemetry.Enabled) { - telemetry.TrackEvent(name, props, measures); + telemetry.TrackEvent($"template/{name}", props, measures); } }); } diff --git a/src/dotnet/commands/dotnet-restore/Program.cs b/src/dotnet/commands/dotnet-restore/Program.cs index b0269370f..b432150c3 100644 --- a/src/dotnet/commands/dotnet-restore/Program.cs +++ b/src/dotnet/commands/dotnet-restore/Program.cs @@ -19,7 +19,7 @@ namespace Microsoft.DotNet.Tools.Restore { } - public static RestoreCommand FromArgs(string[] args, string msbuildPath = null) + public static RestoreCommand FromArgs(string[] args, string msbuildPath = null, bool noLogo = true) { DebugHelper.HandleDebugSwitch(ref args); @@ -31,17 +31,15 @@ namespace Microsoft.DotNet.Tools.Restore var parsedRestore = result["dotnet"]["restore"]; - var msbuildArgs = new List - { - "/NoLogo", - "/t:Restore" - }; + var msbuildArgs = new List(); - if (!HasVerbosityOption(parsedRestore)) + if (noLogo) { - msbuildArgs.Add("/ConsoleLoggerParameters:Verbosity=Minimal"); + msbuildArgs.Add("/nologo"); } + msbuildArgs.Add("/t:Restore"); + msbuildArgs.AddRange(parsedRestore.OptionValuesToBeForwarded()); msbuildArgs.AddRange(parsedRestore.Arguments); @@ -65,12 +63,5 @@ namespace Microsoft.DotNet.Tools.Restore return cmd.Execute(); } - - private static bool HasVerbosityOption(AppliedOption parsedRestore) - { - return parsedRestore.HasOption("verbosity") || - parsedRestore.Arguments.Any(a => a.Contains("/v:")) || - parsedRestore.Arguments.Any(a => a.Contains("/verbosity:")); - } } } \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-run/LocalizableStrings.resx b/src/dotnet/commands/dotnet-run/LocalizableStrings.resx index 8cab1941e..a939d42a8 100644 --- a/src/dotnet/commands/dotnet-run/LocalizableStrings.resx +++ b/src/dotnet/commands/dotnet-run/LocalizableStrings.resx @@ -177,7 +177,7 @@ The current {1} is '{2}'. Using launch settings from {0}... - Launch profile is not a JSON object. + A profile with the specified name could not be found or is not a valid JSON object. The launch profile type '{0}' is not supported. diff --git a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.cs.xlf b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.cs.xlf index 60ce2ef7b..ac8c36c54 100644 --- a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.cs.xlf +++ b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.cs.xlf @@ -103,8 +103,8 @@ Aktuální {1} je {2}. - Launch profile is not a JSON object. - Profil spuštění není objektem JSON. + A profile with the specified name could not be found or is not a valid JSON object. + Profil se zadaným názvem se nenašel nebo nepředstavuje platný objekt JSON. diff --git a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.de.xlf b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.de.xlf index 2349aafdc..6cd88af92 100644 --- a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.de.xlf +++ b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.de.xlf @@ -103,8 +103,8 @@ Ein ausführbares Projekt sollte ein ausführbares TFM (z.B. netcoreapp2.0) verw - Launch profile is not a JSON object. - Das Startprofil ist kein JSON-Objekt. + A profile with the specified name could not be found or is not a valid JSON object. + Ein Profil mit dem angegebenen Namen wurde nicht gefunden oder ist kein gültiges JSON-Objekt. diff --git a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.es.xlf b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.es.xlf index 4c05cc144..5b7eae94b 100644 --- a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.es.xlf +++ b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.es.xlf @@ -103,8 +103,8 @@ El actual {1} es "{2}". - Launch profile is not a JSON object. - El perfil de inicio no es un objeto JSON. + A profile with the specified name could not be found or is not a valid JSON object. + No se ha encontrado ningún perfil con el nombre especificado o el que se ha encontrado no es un objeto JSON válido. diff --git a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.fr.xlf b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.fr.xlf index f62af586a..6c1b28f07 100644 --- a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.fr.xlf +++ b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.fr.xlf @@ -103,8 +103,8 @@ Le {1} actuel est '{2}'. - Launch profile is not a JSON object. - Le profil de lancement n'est pas un objet JSON. + A profile with the specified name could not be found or is not a valid JSON object. + Un profil avec le nom spécifié est introuvable ou n'est pas un objet JSON valide. diff --git a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.it.xlf b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.it.xlf index ba7512823..2d180a233 100644 --- a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.it.xlf +++ b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.it.xlf @@ -103,8 +103,8 @@ Il valore corrente di {1} è '{2}'. - Launch profile is not a JSON object. - Il profilo di avvio non è un oggetto JSON. + A profile with the specified name could not be found or is not a valid JSON object. + Non è stato possibile trovare alcun profilo con il nome specificato oppure il profilo non è un oggetto JSON valido. diff --git a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.ja.xlf b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.ja.xlf index fa08955ee..dee300d42 100644 --- a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.ja.xlf +++ b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.ja.xlf @@ -103,8 +103,8 @@ The current {1} is '{2}'. - Launch profile is not a JSON object. - 起動プロファイルが JSON オブジェクトではありません。 + A profile with the specified name could not be found or is not a valid JSON object. + 指定された名前のプロファイルは見つからないか、有効な JSON オブジェクトではありません。 diff --git a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.ko.xlf b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.ko.xlf index 41a2ec94e..b3e5d55c4 100644 --- a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.ko.xlf +++ b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.ko.xlf @@ -103,8 +103,8 @@ The current {1} is '{2}'. - Launch profile is not a JSON object. - 시작 프로필이 JSON 개체가 아닙니다. + A profile with the specified name could not be found or is not a valid JSON object. + 지정된 이름을 가진 프로필을 찾을 수 없거나 유효한 JSON 개체가 아닙니다. diff --git a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.pl.xlf b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.pl.xlf index aab3a4913..768e31fd1 100644 --- a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.pl.xlf +++ b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.pl.xlf @@ -103,8 +103,8 @@ Bieżący element {1}: „{2}”. - Launch profile is not a JSON object. - Profil uruchamiania nie jest obiektem JSON. + A profile with the specified name could not be found or is not a valid JSON object. + Nie można znaleźć profilu o określonej nazwie lub nie jest to prawidłowy obiekt JSON. diff --git a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.pt-BR.xlf b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.pt-BR.xlf index 2843c82ef..f398083f8 100644 --- a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.pt-BR.xlf @@ -103,8 +103,8 @@ O {1} atual é '{2}'. - Launch profile is not a JSON object. - O perfil de inicialização não é um objeto JSON. + A profile with the specified name could not be found or is not a valid JSON object. + Um perfil com o nome especificado não pôde ser encontrado ou não é um objeto JSON válido. diff --git a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.ru.xlf b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.ru.xlf index 95b1e0400..cb41939f1 100644 --- a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.ru.xlf +++ b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.ru.xlf @@ -103,8 +103,8 @@ The current {1} is '{2}'. - Launch profile is not a JSON object. - Профиль запуска не является объектом JSON. + A profile with the specified name could not be found or is not a valid JSON object. + Не удается найти профиль с указанным именем, или он не является допустимым объектом JSON. diff --git a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.tr.xlf b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.tr.xlf index a3a9211fb..c38bf1e18 100644 --- a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.tr.xlf +++ b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.tr.xlf @@ -103,8 +103,8 @@ Geçerli {1}: '{2}'. - Launch profile is not a JSON object. - Başlatma profili bir JSON nesnesi değil. + A profile with the specified name could not be found or is not a valid JSON object. + Belirtilen isme sahip profil bulunamadı veya geçerli bir JSON nesnesi değil. diff --git a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.zh-Hans.xlf b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.zh-Hans.xlf index a4b5c43c2..9775bb8bd 100644 --- a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.zh-Hans.xlf @@ -103,8 +103,8 @@ The current {1} is '{2}'. - Launch profile is not a JSON object. - 启动配置文件不是 JSON 对象。 + A profile with the specified name could not be found or is not a valid JSON object. + 找不到具有指定名称的配置文件或该配置文件不是有效的 JSON 对象。 diff --git a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.zh-Hant.xlf b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.zh-Hant.xlf index b9bd6e9c3..6c88ba3c0 100644 --- a/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/dotnet/commands/dotnet-run/xlf/LocalizableStrings.zh-Hant.xlf @@ -103,8 +103,8 @@ The current {1} is '{2}'. - Launch profile is not a JSON object. - 啟動設定檔並非 JSON 物件。 + A profile with the specified name could not be found or is not a valid JSON object. + 找不到具有指定名稱的設定檔,或不是有效的 JSON 物件。 diff --git a/src/redist/redist.csproj b/src/redist/redist.csproj index b8e179c3b..dcfa97725 100644 --- a/src/redist/redist.csproj +++ b/src/redist/redist.csproj @@ -17,15 +17,13 @@ - - - + + All + @@ -74,9 +72,33 @@ - + + + + + + + + + + + + + + "version": ".*" + "version": "$(CLI_SharedFrameworkVersion)" + + + + + + + + + - + + - + - + - + + + - - + + + + + + + + - + + + + + + + + + + - - - - false - + + + + + - - diff --git a/src/tool_roslyn/RunCsc.cmd b/src/tool_roslyn/RunCsc.cmd deleted file mode 100644 index 7398082b2..000000000 --- a/src/tool_roslyn/RunCsc.cmd +++ /dev/null @@ -1,6 +0,0 @@ -@echo off - -REM Copyright (c) .NET Foundation and contributors. All rights reserved. -REM Licensed under the MIT license. See LICENSE file in the project root for full license information. - -"%~dp0..\..\..\dotnet" "%~dp0csc.exe" %* diff --git a/src/tool_roslyn/RunCsc.sh b/src/tool_roslyn/RunCsc.sh deleted file mode 100755 index 47aed63d1..000000000 --- a/src/tool_roslyn/RunCsc.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash -# -# 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. -# - -set -e - -SOURCE="${BASH_SOURCE[0]}" -while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink - DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - SOURCE="$(readlink "$SOURCE")" - [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located -done -DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - -"$DIR/../../../dotnet" "$DIR/csc.exe" "$@" diff --git a/src/tool_roslyn/RunVbc.cmd b/src/tool_roslyn/RunVbc.cmd deleted file mode 100644 index e891b1bf5..000000000 --- a/src/tool_roslyn/RunVbc.cmd +++ /dev/null @@ -1,6 +0,0 @@ -@echo off - -REM Copyright (c) .NET Foundation and contributors. All rights reserved. -REM Licensed under the MIT license. See LICENSE file in the project root for full license information. - -"%~dp0..\..\..\dotnet" "%~dp0vbc.exe" %* diff --git a/src/tool_roslyn/RunVbc.sh b/src/tool_roslyn/RunVbc.sh deleted file mode 100755 index 3dda886a0..000000000 --- a/src/tool_roslyn/RunVbc.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash -# -# 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. -# - -set -e - -SOURCE="${BASH_SOURCE[0]}" -while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink - DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - SOURCE="$(readlink "$SOURCE")" - [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located -done -DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - -"$DIR/../../../dotnet" "$DIR/vbc.exe" "$@" diff --git a/src/tool_roslyn/tool_roslyn.csproj b/src/tool_roslyn/tool_roslyn.csproj deleted file mode 100644 index bd702ca7c..000000000 --- a/src/tool_roslyn/tool_roslyn.csproj +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - $(CliVersionPrefix) - netcoreapp2.0 - $(CLI_SharedFrameworkVersion) - true - $(RoslynDirectory) - $(CommitCount) - - - - - - - - - - - - - - PreserveNewest - PreserveNewest - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/tool_roslyn_satellites/tool_roslyn_satellites.csproj b/src/tool_roslyn_satellites/tool_roslyn_satellites.csproj new file mode 100644 index 000000000..d42c632b0 --- /dev/null +++ b/src/tool_roslyn_satellites/tool_roslyn_satellites.csproj @@ -0,0 +1,35 @@ + + + + + + $(CliVersionPrefix) + $(CliTargetFramework) + $(CLI_SharedFrameworkVersion) + $(RoslynDirectory)/bincore + $(CommitCount) + false + false + false + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/dotnet-msbuild.Tests/GivenDotnetBuildInvocation.cs b/test/dotnet-msbuild.Tests/GivenDotnetBuildInvocation.cs index 259d5e257..64b7ecda5 100644 --- a/test/dotnet-msbuild.Tests/GivenDotnetBuildInvocation.cs +++ b/test/dotnet-msbuild.Tests/GivenDotnetBuildInvocation.cs @@ -10,7 +10,6 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests public class GivenDotnetBuildInvocation { const string ExpectedPrefix = "exec /m /v:m"; - const string ExpectedSuffix = "/clp:Summary"; [Theory] [InlineData(new string[] { }, "/t:Build")] @@ -19,8 +18,6 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests [InlineData(new string[] { "--output", "foo" }, "/t:Build /p:OutputPath=foo")] [InlineData(new string[] { "-o", "foo1 foo2" }, "/t:Build \"/p:OutputPath=foo1 foo2\"")] [InlineData(new string[] { "--no-incremental" }, "/t:Rebuild")] - [InlineData(new string[] { "-f", "tfm" }, "/t:Build /p:TargetFramework=tfm")] - [InlineData(new string[] { "--framework", "tfm" }, "/t:Build /p:TargetFramework=tfm")] [InlineData(new string[] { "-r", "rid" }, "/t:Build /p:RuntimeIdentifier=rid")] [InlineData(new string[] { "--runtime", "rid" }, "/t:Build /p:RuntimeIdentifier=rid")] [InlineData(new string[] { "-c", "config" }, "/t:Build /p:Configuration=config")] @@ -29,14 +26,45 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests [InlineData(new string[] { "--no-dependencies" }, "/t:Build /p:BuildProjectReferences=false")] [InlineData(new string[] { "-v", "diag" }, "/t:Build /verbosity:diag")] [InlineData(new string[] { "--verbosity", "diag" }, "/t:Build /verbosity:diag")] - [InlineData(new string[] { "--no-incremental", "-o", "myoutput", "-r", "myruntime", "-v", "diag" }, "/t:Rebuild /p:OutputPath=myoutput /p:RuntimeIdentifier=myruntime /verbosity:diag")] + [InlineData(new string[] { "--no-incremental", "-o", "myoutput", "-r", "myruntime", "-v", "diag", "/ArbitrarySwitchForMSBuild" }, + "/t:Rebuild /p:OutputPath=myoutput /p:RuntimeIdentifier=myruntime /verbosity:diag /ArbitrarySwitchForMSBuild")] public void MsbuildInvocationIsCorrect(string[] args, string expectedAdditionalArgs) { expectedAdditionalArgs = (string.IsNullOrEmpty(expectedAdditionalArgs) ? "" : $" {expectedAdditionalArgs}"); var msbuildPath = ""; - BuildCommand.FromArgs(args, msbuildPath) - .GetProcessStartInfo().Arguments.Should().Be($"{ExpectedPrefix}{expectedAdditionalArgs} {ExpectedSuffix}"); + var command = BuildCommand.FromArgs(args, msbuildPath); + + command.SeparateRestoreCommand.Should().BeNull(); + + command.GetProcessStartInfo() + .Arguments.Should() + .Be($"{ExpectedPrefix} /restore /clp:Summary{expectedAdditionalArgs}"); + } + + [Theory] + [InlineData(new string[] { "-f", "tfm" }, "/t:Restore", "/t:Build /p:TargetFramework=tfm")] + [InlineData(new string[] { "-o", "myoutput", "-f", "tfm", "-v", "diag", "/ArbitrarySwitchForMSBuild" }, + "/t:Restore /p:OutputPath=myoutput /verbosity:diag /ArbitrarySwitchForMSBuild", + "/t:Build /p:OutputPath=myoutput /p:TargetFramework=tfm /verbosity:diag /ArbitrarySwitchForMSBuild")] + public void MsbuildInvocationIsCorrectForSeparateRestore( + string[] args, + string expectedAdditionalArgsForRestore, + string expectedAdditionalArgs) + { + expectedAdditionalArgs = (string.IsNullOrEmpty(expectedAdditionalArgs) ? "" : $" {expectedAdditionalArgs}"); + + var msbuildPath = ""; + var command = BuildCommand.FromArgs(args, msbuildPath); + + command.SeparateRestoreCommand.GetProcessStartInfo() + .Arguments.Should() + .Be($"{ExpectedPrefix} {expectedAdditionalArgsForRestore}"); + + command.GetProcessStartInfo() + .Arguments.Should() + .Be($"{ExpectedPrefix} /nologo /clp:Summary{expectedAdditionalArgs}"); + } } } diff --git a/test/dotnet-msbuild.Tests/GivenDotnetPackInvocation.cs b/test/dotnet-msbuild.Tests/GivenDotnetPackInvocation.cs index aba1b15a6..74559a6fa 100644 --- a/test/dotnet-msbuild.Tests/GivenDotnetPackInvocation.cs +++ b/test/dotnet-msbuild.Tests/GivenDotnetPackInvocation.cs @@ -11,7 +11,7 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests { public class GivenDotnetPackInvocation { - const string ExpectedPrefix = "exec /m /v:m /t:pack"; + const string ExpectedPrefix = "exec /m /v:m /restore /t:pack"; [Theory] [InlineData(new string[] { }, "")] @@ -33,8 +33,10 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests expectedAdditionalArgs = (string.IsNullOrEmpty(expectedAdditionalArgs) ? "" : $" {expectedAdditionalArgs}"); var msbuildPath = ""; - PackCommand.FromArgs(args, msbuildPath) - .GetProcessStartInfo().Arguments.Should().Be($"{ExpectedPrefix}{expectedAdditionalArgs}"); + var command = PackCommand.FromArgs(args, msbuildPath); + + command.SeparateRestoreCommand.Should().BeNull(); + command.GetProcessStartInfo().Arguments.Should().Be($"{ExpectedPrefix}{expectedAdditionalArgs}"); } } } diff --git a/test/dotnet-msbuild.Tests/GivenDotnetPublishInvocation.cs b/test/dotnet-msbuild.Tests/GivenDotnetPublishInvocation.cs index f7cf3838d..4ece567bc 100644 --- a/test/dotnet-msbuild.Tests/GivenDotnetPublishInvocation.cs +++ b/test/dotnet-msbuild.Tests/GivenDotnetPublishInvocation.cs @@ -20,12 +20,10 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests this.output = output; } - const string ExpectedPrefix = "exec /m /v:m /t:Publish"; + const string ExpectedPrefix = "exec /m /v:m"; [Theory] [InlineData(new string[] { }, "")] - [InlineData(new string[] { "-f", "" }, "/p:TargetFramework=")] - [InlineData(new string[] { "--framework", "" }, "/p:TargetFramework=")] [InlineData(new string[] { "-r", "" }, "/p:RuntimeIdentifier=")] [InlineData(new string[] { "--runtime", "" }, "/p:RuntimeIdentifier=")] [InlineData(new string[] { "-o", "" }, "/p:PublishDir=")] @@ -43,10 +41,35 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests expectedAdditionalArgs = (string.IsNullOrEmpty(expectedAdditionalArgs) ? "" : $" {expectedAdditionalArgs}"); var msbuildPath = ""; - PublishCommand.FromArgs(args, msbuildPath) - .GetProcessStartInfo() - .Arguments.Should() - .Be($"{ExpectedPrefix}{expectedAdditionalArgs}"); + var command = PublishCommand.FromArgs(args, msbuildPath); + + command.SeparateRestoreCommand + .Should() + .BeNull(); + + command.GetProcessStartInfo() + .Arguments.Should() + .Be($"{ExpectedPrefix} /restore /t:Publish{expectedAdditionalArgs}"); + } + + [Theory] + [InlineData(new string[] { "-f", "" }, "/p:TargetFramework=")] + [InlineData(new string[] { "--framework", "" }, "/p:TargetFramework=")] + public void MsbuildInvocationIsCorrectForSeparateRestore(string[] args, string expectedAdditionalArgs) + { + expectedAdditionalArgs = (string.IsNullOrEmpty(expectedAdditionalArgs) ? "" : $" {expectedAdditionalArgs}"); + + var msbuildPath = ""; + var command = PublishCommand.FromArgs(args, msbuildPath); + + command.SeparateRestoreCommand + .GetProcessStartInfo() + .Arguments.Should() + .Be($"{ExpectedPrefix} /t:Restore"); + + command.GetProcessStartInfo() + .Arguments.Should() + .Be($"{ExpectedPrefix} /nologo /t:Publish{expectedAdditionalArgs}"); } [Theory] diff --git a/test/dotnet-msbuild.Tests/GivenDotnetRestoreInvocation.cs b/test/dotnet-msbuild.Tests/GivenDotnetRestoreInvocation.cs index dd55e2abd..eb8ea6163 100644 --- a/test/dotnet-msbuild.Tests/GivenDotnetRestoreInvocation.cs +++ b/test/dotnet-msbuild.Tests/GivenDotnetRestoreInvocation.cs @@ -11,10 +11,7 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests public class GivenDotnetRestoreInvocation { private const string ExpectedPrefix = - "exec /m /v:m /NoLogo /t:Restore"; - - private string ExpectedPrefixWithConsoleLoggerParamaters = - $"{ExpectedPrefix} /ConsoleLoggerParameters:Verbosity=Minimal"; + "exec /m /v:m /nologo /t:Restore"; [Theory] [InlineData(new string[] { }, "")] @@ -30,19 +27,9 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests [InlineData(new string[] { "--no-cache" }, "/p:RestoreNoCache=true")] [InlineData(new string[] { "--ignore-failed-sources" }, "/p:RestoreIgnoreFailedSources=true")] [InlineData(new string[] { "--no-dependencies" }, "/p:RestoreRecursive=false")] - public void MsbuildInvocationWithConsoleLoggerParametersIsCorrect(string[] args, string expectedAdditionalArgs) - { - expectedAdditionalArgs = (string.IsNullOrEmpty(expectedAdditionalArgs) ? "" : $" {expectedAdditionalArgs}"); - - var msbuildPath = ""; - RestoreCommand.FromArgs(args, msbuildPath) - .GetProcessStartInfo().Arguments - .Should().Be($"{ExpectedPrefixWithConsoleLoggerParamaters}{expectedAdditionalArgs}"); - } - [InlineData(new string[] { "-v", "minimal" }, @"/verbosity:minimal")] [InlineData(new string[] { "--verbosity", "minimal" }, @"/verbosity:minimal")] - public void MsbuildInvocationWithVerbosityIsCorrect(string[] args, string expectedAdditionalArgs) + public void MsbuildInvocationIsCorrect(string[] args, string expectedAdditionalArgs) { expectedAdditionalArgs = (string.IsNullOrEmpty(expectedAdditionalArgs) ? "" : $" {expectedAdditionalArgs}"); diff --git a/test/dotnet-msbuild.Tests/GivenMSBuildLogger.cs b/test/dotnet-msbuild.Tests/GivenMSBuildLogger.cs new file mode 100644 index 000000000..7e0521d9f --- /dev/null +++ b/test/dotnet-msbuild.Tests/GivenMSBuildLogger.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 FluentAssertions; +using Xunit; +using Microsoft.DotNet.Tools.MSBuild; +using Microsoft.DotNet.Cli.Telemetry; +using Microsoft.Build.Framework; +using System.Collections.Generic; + +namespace Microsoft.DotNet.Cli.MSBuild.Tests +{ + public class GivenMSBuildLogger + { + [Fact(DisplayName = "It blocks telemetry that is not in the list")] + public void ItBlocks() + { + var fakeTelemetry = new FakeTelemetry(); + var telemetryEventArgs = new TelemetryEventArgs + { + EventName = "User Defined Event Name", + Properties = new Dictionary + { + { "User Defined Key", "User Defined Value"}, + } + }; + + MSBuildLogger.FormatAndSend(fakeTelemetry, telemetryEventArgs); + + fakeTelemetry.LogEntry.Should().BeNull(); + } + + [Fact(DisplayName = "It masks event name with targetframeworkeval only on TargetFrameworkVersion")] + public void ItMasksTargetFrameworkEventname() + { + var fakeTelemetry = new FakeTelemetry(); + var telemetryEventArgs = new TelemetryEventArgs + { + EventName = "targetframeworkeval", + Properties = new Dictionary + { + { "TargetFrameworkVersion", ".NETStandard,Version=v2.0"}, + } + }; + + MSBuildLogger.FormatAndSend(fakeTelemetry, telemetryEventArgs); + + fakeTelemetry.LogEntry.EventName.Should().Be("msbuild/targetframeworkeval"); + fakeTelemetry.LogEntry.Properties.Keys.Count.Should().Be(1); + var expectedKey = "TargetFrameworkVersion"; + fakeTelemetry.LogEntry.Properties.Should().ContainKey(expectedKey); + fakeTelemetry.LogEntry.Properties[expectedKey].Should().Be(Sha256Hasher.Hash(".NETSTANDARD,VERSION=V2.0")); + } + + public class FakeTelemetry : ITelemetry + { + public bool Enabled { get; set; } + + public void TrackEvent(string eventName, IDictionary properties, IDictionary measurements) + { + LogEntry = new LogEntry { EventName = eventName, Properties = properties, Measurement = measurements }; + + } + + public LogEntry LogEntry { get; private set; } + + } + + public class LogEntry + { + public string EventName { get; set; } + public IDictionary Properties { get; set; } + public IDictionary Measurement { get; set; } + } + } +} diff --git a/test/dotnet-msbuild.Tests/GivenMsbuildForwardingApp.cs b/test/dotnet-msbuild.Tests/GivenMsbuildForwardingApp.cs index 4450258ee..a40e23b5a 100644 --- a/test/dotnet-msbuild.Tests/GivenMsbuildForwardingApp.cs +++ b/test/dotnet-msbuild.Tests/GivenMsbuildForwardingApp.cs @@ -31,8 +31,6 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests [Theory] [InlineData("MSBuildExtensionsPath")] - [InlineData("CscToolExe")] - [InlineData("VbcToolExe")] [InlineData("MSBuildSDKsPath")] [InlineData("DOTNET_CLI_TELEMETRY_SESSIONID")] public void ItSetsEnvironmentalVariables(string envVarName) @@ -66,28 +64,6 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests .Exist(); } - [Fact] - public void ItSetsCscToolExePathToValidPath() - { - var msbuildPath = ""; - var envVar = "CscToolExe"; - new FileInfo(new MSBuildForwardingApp(new string[0], msbuildPath) - .GetProcessStartInfo() - .Environment[envVar]) - .Should().NotBeNull("constructor will throw on invalid path"); - } - - [Fact] - public void ItSetsVbcToolExePathToValidPath() - { - var msbuildPath = ""; - var envVar = "VbcToolExe"; - new FileInfo(new MSBuildForwardingApp(new string[0], msbuildPath) - .GetProcessStartInfo() - .Environment[envVar]) - .Should().NotBeNull("constructor will throw on invalid path"); - } - [Fact] public void ItSetsOrIgnoresTelemetrySessionId() { diff --git a/test/dotnet-test.Tests/GivenDotnetTestBuildsAndRunsTestFromCsprojForMultipleTFM.cs b/test/dotnet-test.Tests/GivenDotnetTestBuildsAndRunsTestFromCsprojForMultipleTFM.cs index adfc7b0d4..0a6e2e0fd 100644 --- a/test/dotnet-test.Tests/GivenDotnetTestBuildsAndRunsTestFromCsprojForMultipleTFM.cs +++ b/test/dotnet-test.Tests/GivenDotnetTestBuildsAndRunsTestFromCsprojForMultipleTFM.cs @@ -39,9 +39,9 @@ namespace Microsoft.DotNet.Cli.Test.Tests { result.StdOut .Should().Contain("Total tests: 3. Passed: 2. Failed: 1. Skipped: 0.", "because .NET 4.6 tests will pass") - .And.Contain("Passed TestNamespace.VSTestTests.VSTestPassTestDesktop", "because .NET 4.6 tests will pass") + .And.Contain("Passed VSTestPassTestDesktop", "because .NET 4.6 tests will pass") .And.Contain("Total tests: 3. Passed: 1. Failed: 2. Skipped: 0.", "because netcoreapp2.0 tests will fail") - .And.Contain("Failed TestNamespace.VSTestTests.VSTestFailTestNetCoreApp", "because netcoreapp2.0 tests will fail"); + .And.Contain("Failed VSTestFailTestNetCoreApp", "because netcoreapp2.0 tests will fail"); } result.ExitCode.Should().Be(1); } diff --git a/test/dotnet-test.Tests/GivenDotnetTestBuildsAndRunsTestfromCsproj.cs b/test/dotnet-test.Tests/GivenDotnetTestBuildsAndRunsTestfromCsproj.cs index 807688463..050b547e1 100644 --- a/test/dotnet-test.Tests/GivenDotnetTestBuildsAndRunsTestfromCsproj.cs +++ b/test/dotnet-test.Tests/GivenDotnetTestBuildsAndRunsTestfromCsproj.cs @@ -28,8 +28,8 @@ namespace Microsoft.DotNet.Cli.Test.Tests if (!DotnetUnderTest.IsLocalized()) { result.StdOut.Should().Contain("Total tests: 2. Passed: 1. Failed: 1. Skipped: 0."); - result.StdOut.Should().Contain("Passed TestNamespace.VSTestTests.VSTestPassTest"); - result.StdOut.Should().Contain("Failed TestNamespace.VSTestTests.VSTestFailTest"); + result.StdOut.Should().Contain("Passed VSTestPassTest"); + result.StdOut.Should().Contain("Failed VSTestFailTest"); } result.ExitCode.Should().Be(1); @@ -52,8 +52,8 @@ namespace Microsoft.DotNet.Cli.Test.Tests if (!DotnetUnderTest.IsLocalized()) { result.StdOut.Should().Contain("Total tests: 2. Passed: 1. Failed: 1. Skipped: 0."); - result.StdOut.Should().Contain("Passed TestNamespace.VSTestTests.VSTestPassTest"); - result.StdOut.Should().Contain("Failed TestNamespace.VSTestTests.VSTestFailTest"); + result.StdOut.Should().Contain("Passed VSTestPassTest"); + result.StdOut.Should().Contain("Failed VSTestFailTest"); } result.ExitCode.Should().Be(1); @@ -227,8 +227,8 @@ namespace Microsoft.DotNet.Cli.Test.Tests if (!DotnetUnderTest.IsLocalized()) { result.StdOut.Should().Contain("Total tests: 2. Passed: 1. Failed: 1. Skipped: 0."); - result.StdOut.Should().Contain("Passed TestNamespace.VSTestTests.VSTestPassTest"); - result.StdOut.Should().Contain("Failed TestNamespace.VSTestTests.VSTestFailTest"); + result.StdOut.Should().Contain("Passed VSTestPassTest"); + result.StdOut.Should().Contain("Failed VSTestFailTest"); } result.ExitCode.Should().Be(1); diff --git a/test/dotnet-vstest.Tests/VSTestTests.cs b/test/dotnet-vstest.Tests/VSTestTests.cs index 47eae7e89..d1de1e8e8 100644 --- a/test/dotnet-vstest.Tests/VSTestTests.cs +++ b/test/dotnet-vstest.Tests/VSTestTests.cs @@ -42,8 +42,8 @@ namespace Microsoft.DotNet.Cli.VSTest.Tests { result.StdOut .Should().Contain("Total tests: 2. Passed: 1. Failed: 1. Skipped: 0.") - .And.Contain("Passed TestNamespace.VSTestTests.VSTestPassTest") - .And.Contain("Failed TestNamespace.VSTestTests.VSTestFailTest"); + .And.Contain("Passed VSTestPassTest") + .And.Contain("Failed VSTestFailTest"); } result.ExitCode.Should().Be(1); diff --git a/test/dotnet.Tests/TelemetryCommandTest.cs b/test/dotnet.Tests/TelemetryCommandTest.cs index 356667009..af231ecc7 100644 --- a/test/dotnet.Tests/TelemetryCommandTest.cs +++ b/test/dotnet.Tests/TelemetryCommandTest.cs @@ -16,116 +16,144 @@ namespace Microsoft.DotNet.Tests private readonly FakeRecordEventNameTelemetry _fakeTelemetry; public string EventName { get; set; } + public IDictionary Properties { get; set; } + public TelemetryCommandTests() { _fakeTelemetry = new FakeRecordEventNameTelemetry(); TelemetryEventEntry.Subscribe(_fakeTelemetry.TrackEvent); - TelemetryEventEntry.TelemetryFilter = new TelemetryFilter(); + TelemetryEventEntry.TelemetryFilter = new TelemetryFilter(Sha256Hasher.HashWithNormalizedCasing); } [Fact] public void TopLevelCommandNameShouldBeSentToTelemetry() { - string[] args = {"help"}; + string[] args = { "help" }; Cli.Program.ProcessArgs(args); - _fakeTelemetry.LogEntries.Should().Contain(e => e.EventName == args[0]); + + _fakeTelemetry.LogEntries.Should().Contain(e => e.EventName == "toplevelparser/command" && + e.Properties.ContainsKey("verb") && + e.Properties["verb"] == Sha256Hasher.Hash("HELP")); } [Fact] public void DotnetNewCommandFirstArgumentShouldBeSentToTelemetry() { const string argumentToSend = "console"; - string[] args = {"new", argumentToSend}; + string[] args = { "new", argumentToSend }; Cli.Program.ProcessArgs(args); _fakeTelemetry .LogEntries.Should() - .Contain(e => e.EventName == "dotnet-new" && e.Properties.ContainsKey("argument") && - e.Properties["argument"] == argumentToSend); + .Contain(e => e.EventName == "sublevelparser/command" && + e.Properties.ContainsKey("argument") && + e.Properties["argument"] == Sha256Hasher.Hash(argumentToSend.ToUpper()) && + e.Properties.ContainsKey("verb") && + e.Properties["verb"] == Sha256Hasher.Hash("NEW")); } [Fact] public void DotnetHelpCommandFirstArgumentShouldBeSentToTelemetry() { const string argumentToSend = "something"; - string[] args = {"help", argumentToSend}; + string[] args = { "help", argumentToSend }; Cli.Program.ProcessArgs(args); _fakeTelemetry .LogEntries.Should() - .Contain(e => e.EventName == "dotnet-help" && e.Properties.ContainsKey("argument") && - e.Properties["argument"] == argumentToSend); + .Contain(e => e.EventName == "sublevelparser/command" && + e.Properties.ContainsKey("argument") && + e.Properties["argument"] == Sha256Hasher.Hash(argumentToSend.ToUpper()) && + e.Properties.ContainsKey("verb") && + e.Properties["verb"] == Sha256Hasher.Hash("HELP")); } [Fact] public void DotnetAddCommandFirstArgumentShouldBeSentToTelemetry() { const string argumentToSend = "package"; - string[] args = {"add", argumentToSend, "aPackageName"}; + string[] args = { "add", argumentToSend, "aPackageName" }; Cli.Program.ProcessArgs(args); _fakeTelemetry .LogEntries.Should() - .Contain(e => e.EventName == "dotnet-add" && e.Properties.ContainsKey("argument") && - e.Properties["argument"] == argumentToSend); + .Contain(e => e.EventName == "sublevelparser/command" && + e.Properties.ContainsKey("argument") && + e.Properties["argument"] == Sha256Hasher.Hash(argumentToSend.ToUpper()) && + e.Properties.ContainsKey("verb") && + e.Properties["verb"] == Sha256Hasher.Hash("ADD")); } [Fact] public void DotnetAddCommandFirstArgumentShouldBeSentToTelemetry2() { const string argumentToSend = "reference"; - string[] args = {"add", argumentToSend, "aPackageName"}; + string[] args = { "add", argumentToSend, "aPackageName" }; Cli.Program.ProcessArgs(args); _fakeTelemetry .LogEntries.Should() - .Contain(e => e.EventName == "dotnet-add" && e.Properties.ContainsKey("argument") && - e.Properties["argument"] == argumentToSend); + .Contain(e => e.EventName == "sublevelparser/command" && + e.Properties.ContainsKey("argument") && + e.Properties["argument"] == Sha256Hasher.Hash(argumentToSend.ToUpper()) && + e.Properties.ContainsKey("verb") && + e.Properties["verb"] == Sha256Hasher.Hash("ADD")); } [Fact] public void DotnetRemoveCommandFirstArgumentShouldBeSentToTelemetry() { const string argumentToSend = "package"; - string[] args = {"remove", argumentToSend, "aPackageName"}; + string[] args = { "remove", argumentToSend, "aPackageName" }; Cli.Program.ProcessArgs(args); _fakeTelemetry .LogEntries.Should() - .Contain(e => e.EventName == "dotnet-remove" && e.Properties.ContainsKey("argument") && - e.Properties["argument"] == argumentToSend); + .Contain(e => e.EventName == "sublevelparser/command" && + e.Properties.ContainsKey("argument") && + e.Properties["argument"] == Sha256Hasher.Hash(argumentToSend.ToUpper()) && + e.Properties.ContainsKey("verb") && + e.Properties["verb"] == Sha256Hasher.Hash("REMOVE")); } [Fact] public void DotnetListCommandFirstArgumentShouldBeSentToTelemetry() { const string argumentToSend = "reference"; - string[] args = {"list", argumentToSend, "aPackageName"}; + string[] args = { "list", argumentToSend, "aPackageName" }; Cli.Program.ProcessArgs(args); _fakeTelemetry .LogEntries.Should() - .Contain(e => e.EventName == "dotnet-list" && e.Properties.ContainsKey("argument") && - e.Properties["argument"] == argumentToSend); + .Contain(e => e.EventName == "sublevelparser/command" && e.Properties.ContainsKey("argument") && + e.Properties["argument"] == Sha256Hasher.Hash(argumentToSend.ToUpper()) && + e.Properties.ContainsKey("verb") && + e.Properties["verb"] == Sha256Hasher.Hash("LIST")); } [Fact] public void DotnetSlnCommandFirstArgumentShouldBeSentToTelemetry() { const string argumentToSend = "list"; - string[] args = {"sln", "aSolution", argumentToSend}; + string[] args = { "sln", "aSolution", argumentToSend }; Cli.Program.ProcessArgs(args); _fakeTelemetry .LogEntries.Should() - .Contain(e => e.EventName == "dotnet-sln" && e.Properties.ContainsKey("argument") && - e.Properties["argument"] == argumentToSend); + .Contain(e => e.EventName == "sublevelparser/command" && + e.Properties.ContainsKey("argument") && + e.Properties["argument"] == Sha256Hasher.Hash(argumentToSend.ToUpper()) && + e.Properties.ContainsKey("verb") && + e.Properties["verb"] == Sha256Hasher.Hash("SLN")); } [Fact] public void DotnetNugetCommandFirstArgumentShouldBeSentToTelemetry() { const string argumentToSend = "push"; - string[] args = {"nuget", argumentToSend, "aRoot"}; + string[] args = { "nuget", argumentToSend, "aRoot" }; Cli.Program.ProcessArgs(args); _fakeTelemetry .LogEntries.Should() - .Contain(e => e.EventName == "dotnet-nuget" && e.Properties.ContainsKey("argument") && - e.Properties["argument"] == argumentToSend); + .Contain(e => e.EventName == "sublevelparser/command" && + e.Properties.ContainsKey("argument") && + e.Properties["argument"] == Sha256Hasher.Hash(argumentToSend.ToUpper()) && + e.Properties.ContainsKey("verb") && + e.Properties["verb"] == Sha256Hasher.Hash("NUGET")); } [Fact] @@ -133,12 +161,14 @@ namespace Microsoft.DotNet.Tests { const string optionKey = "language"; const string optionValueToSend = "c#"; - string[] args = {"new", "console", "--" + optionKey, optionValueToSend}; + string[] args = { "new", "console", "--" + optionKey, optionValueToSend }; Cli.Program.ProcessArgs(args); _fakeTelemetry .LogEntries.Should() - .Contain(e => e.EventName == "dotnet-new" && e.Properties.ContainsKey(optionKey) && - e.Properties[optionKey] == optionValueToSend); + .Contain(e => e.EventName == "sublevelparser/command" && e.Properties.ContainsKey(optionKey) && + e.Properties[optionKey] == Sha256Hasher.Hash(optionValueToSend.ToUpper()) && + e.Properties.ContainsKey("verb") && + e.Properties["verb"] == Sha256Hasher.Hash("NEW")); } [Fact] @@ -146,12 +176,15 @@ namespace Microsoft.DotNet.Tests { const string optionKey = "verbosity"; const string optionValueToSend = "minimal"; - string[] args = {"restore", "--" + optionKey, optionValueToSend}; + string[] args = { "restore", "--" + optionKey, optionValueToSend }; Cli.Program.ProcessArgs(args); _fakeTelemetry .LogEntries.Should() - .Contain(e => e.EventName == "dotnet-restore" && e.Properties.ContainsKey(optionKey) && - e.Properties[optionKey] == optionValueToSend); + .Contain(e => e.EventName == "sublevelparser/command" && + e.Properties.ContainsKey(optionKey) && + e.Properties[optionKey] == Sha256Hasher.Hash(optionValueToSend.ToUpper()) && + e.Properties.ContainsKey("verb") && + e.Properties["verb"] == Sha256Hasher.Hash("RESTORE")); } [Fact] @@ -159,12 +192,15 @@ namespace Microsoft.DotNet.Tests { const string optionKey = "configuration"; const string optionValueToSend = "Debug"; - string[] args = {"build", "--" + optionKey, optionValueToSend}; + string[] args = { "build", "--" + optionKey, optionValueToSend }; Cli.Program.ProcessArgs(args); _fakeTelemetry .LogEntries.Should() - .Contain(e => e.EventName == "dotnet-build" && e.Properties.ContainsKey(optionKey) && - e.Properties[optionKey] == optionValueToSend); + .Contain(e => e.EventName == "sublevelparser/command" && + e.Properties.ContainsKey(optionKey) && + e.Properties[optionKey] == Sha256Hasher.Hash(optionValueToSend.ToUpper()) && + e.Properties.ContainsKey("verb") && + e.Properties["verb"] == Sha256Hasher.Hash("BUILD")); } [Fact] @@ -176,40 +212,51 @@ namespace Microsoft.DotNet.Tests Cli.Program.ProcessArgs(args); _fakeTelemetry .LogEntries.Should() - .Contain(e => e.EventName == "dotnet-publish" && e.Properties.ContainsKey(optionKey) && - e.Properties[optionKey] == optionValueToSend); + .Contain(e => e.EventName == "sublevelparser/command" && + e.Properties.ContainsKey(optionKey) && + e.Properties[optionKey] == Sha256Hasher.Hash(optionValueToSend.ToUpper()) && + e.Properties.ContainsKey("verb") && + e.Properties["verb"] == Sha256Hasher.Hash("PUBLISH")); } [Fact] public void DotnetBuildAndPublishCommandOpinionsShouldBeSentToTelemetryWhenThereIsMultipleOption() { - string[] args = {"build", "--configuration", "Debug", "--runtime", "osx.10.11-x64"}; + string[] args = { "build", "--configuration", "Debug", "--runtime", "osx.10.11-x64" }; Cli.Program.ProcessArgs(args); _fakeTelemetry .LogEntries.Should() - .Contain(e => e.EventName == "dotnet-build" && e.Properties.ContainsKey("configuration") && - e.Properties["configuration"] == "Debug"); + .Contain(e => e.EventName == "sublevelparser/command" && e.Properties.ContainsKey("configuration") && + e.Properties["configuration"] == Sha256Hasher.Hash("DEBUG") && + e.Properties.ContainsKey("verb") && + e.Properties["verb"] == Sha256Hasher.Hash("BUILD")); _fakeTelemetry .LogEntries.Should() - .Contain(e => e.EventName == "dotnet-build" && e.Properties.ContainsKey("runtime") && - e.Properties["runtime"] == "osx.10.11-x64"); + .Contain(e => e.EventName == "sublevelparser/command" && e.Properties.ContainsKey("runtime") && + e.Properties["runtime"] == Sha256Hasher.Hash("OSX.10.11-X64") && + e.Properties.ContainsKey("verb") && + e.Properties["verb"] == Sha256Hasher.Hash("BUILD")); } [Fact] public void DotnetRunCleanTestCommandOpinionsShouldBeSentToTelemetryWhenThereIsMultipleOption() { - string[] args = {"clean", "--configuration", "Debug", "--framework", "netcoreapp1.0"}; + string[] args = { "clean", "--configuration", "Debug", "--framework", "netcoreapp1.0" }; Cli.Program.ProcessArgs(args); _fakeTelemetry .LogEntries.Should() - .Contain(e => e.EventName == "dotnet-clean" && e.Properties.ContainsKey("configuration") && - e.Properties["configuration"] == "Debug"); + .Contain(e => e.EventName == "sublevelparser/command" && e.Properties.ContainsKey("configuration") && + e.Properties["configuration"] == Sha256Hasher.Hash("DEBUG") && + e.Properties.ContainsKey("verb") && + e.Properties["verb"] == Sha256Hasher.Hash("CLEAN")); _fakeTelemetry .LogEntries.Should() - .Contain(e => e.EventName == "dotnet-clean" && e.Properties.ContainsKey("framework") && - e.Properties["framework"] == "netcoreapp1.0"); + .Contain(e => e.EventName == "sublevelparser/command" && e.Properties.ContainsKey("framework") && + e.Properties["framework"] == Sha256Hasher.Hash("NETCOREAPP1.0") && + e.Properties.ContainsKey("verb") && + e.Properties["verb"] == Sha256Hasher.Hash("CLEAN")); } [WindowsOnlyFact] @@ -222,8 +269,8 @@ namespace Microsoft.DotNet.Tests fakeTelemetry .LogEntries.Should() - .Contain(e => e.EventName == "reportinstallsuccess" && e.Properties.ContainsKey("exeName") && - e.Properties["exeName"] == "dotnet-sdk-latest-win-x64.exe"); + .Contain(e => e.EventName == "install/reportsuccess" && e.Properties.ContainsKey("exeName") && + e.Properties["exeName"] == Sha256Hasher.Hash("DOTNET-SDK-LATEST-WIN-X64.EXE")); } [Fact] diff --git a/test/msbuild.IntegrationTests/FakeRecordEventNameTelemetry.cs b/test/msbuild.IntegrationTests/FakeRecordEventNameTelemetry.cs deleted file mode 100644 index 091ededb3..000000000 --- a/test/msbuild.IntegrationTests/FakeRecordEventNameTelemetry.cs +++ /dev/null @@ -1,38 +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.Collections.Concurrent; -using System.Collections.Generic; -using Microsoft.DotNet.Cli; - -namespace Microsoft.DotNet.Cli.MSBuild.IntegrationTests -{ - public class FakeRecordEventNameTelemetry - { - public bool Enabled { get; set; } - - public string EventName { get; set; } - - public void TrackEvent(string eventName, - IDictionary properties, - IDictionary measurements) - { - LogEntries.Add( - new LogEntry - { - EventName = eventName, - Measurement = measurements, - Properties = properties - }); - } - - public ConcurrentBag LogEntries { get; set; } = new ConcurrentBag(); - - public class LogEntry - { - public string EventName { get; set; } - public IDictionary Properties { get; set; } - public IDictionary Measurement { get; set; } - } - } -}