diff --git a/src/Microsoft.DotNet.Configurer/DotnetFirstRunConfiguration.cs b/src/Microsoft.DotNet.Configurer/DotnetFirstRunConfiguration.cs new file mode 100644 index 000000000..955337e6e --- /dev/null +++ b/src/Microsoft.DotNet.Configurer/DotnetFirstRunConfiguration.cs @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.DotNet.Configurer +{ + public class DotnetFirstRunConfiguration + { + public bool GenerateAspNetCertificate { get; set; } + + public bool PrintTelemetryMessage { get; set; } + + public bool SkipFirstRunExperience { get; set; } + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.Configurer/DotnetFirstTimeUseConfigurer.cs b/src/Microsoft.DotNet.Configurer/DotnetFirstTimeUseConfigurer.cs index 2cb502256..94478909b 100644 --- a/src/Microsoft.DotNet.Configurer/DotnetFirstTimeUseConfigurer.cs +++ b/src/Microsoft.DotNet.Configurer/DotnetFirstTimeUseConfigurer.cs @@ -12,7 +12,7 @@ namespace Microsoft.DotNet.Configurer public class DotnetFirstTimeUseConfigurer { private IReporter _reporter; - private IEnvironmentProvider _environmentProvider; + private DotnetFirstRunConfiguration _dotnetFirstRunConfiguration; private INuGetCachePrimer _nugetCachePrimer; private INuGetCacheSentinel _nugetCacheSentinel; private IFirstTimeUseNoticeSentinel _firstTimeUseNoticeSentinel; @@ -29,7 +29,7 @@ namespace Microsoft.DotNet.Configurer IAspNetCertificateSentinel aspNetCertificateSentinel, IAspNetCoreCertificateGenerator aspNetCoreCertificateGenerator, IFileSentinel toolPathSentinel, - IEnvironmentProvider environmentProvider, + DotnetFirstRunConfiguration dotnetFirstRunConfiguration, IReporter reporter, string cliFallbackFolderPath, IEnvironmentPath pathAdder) @@ -40,7 +40,7 @@ namespace Microsoft.DotNet.Configurer _aspNetCertificateSentinel = aspNetCertificateSentinel; _aspNetCoreCertificateGenerator = aspNetCoreCertificateGenerator; _toolPathSentinel = toolPathSentinel; - _environmentProvider = environmentProvider; + _dotnetFirstRunConfiguration = dotnetFirstRunConfiguration; _reporter = reporter; _cliFallbackFolderPath = cliFallbackFolderPath; _pathAdder = pathAdder ?? throw new ArgumentNullException(nameof(pathAdder)); @@ -93,11 +93,8 @@ namespace Microsoft.DotNet.Configurer #if EXCLUDE_ASPNETCORE return false; #else - var generateAspNetCertificate = - _environmentProvider.GetEnvironmentVariableAsBool("DOTNET_GENERATE_ASPNET_CERTIFICATE", true); - return ShouldRunFirstRunExperience() && - generateAspNetCertificate && + _dotnetFirstRunConfiguration.GenerateAspNetCertificate && !_aspNetCertificateSentinel.Exists(); #endif } @@ -116,11 +113,8 @@ namespace Microsoft.DotNet.Configurer private bool ShouldPrintFirstTimeUseNotice() { - var showFirstTimeUseNotice = - _environmentProvider.GetEnvironmentVariableAsBool("DOTNET_PRINT_TELEMETRY_MESSAGE", true); - return ShouldRunFirstRunExperience() && - showFirstTimeUseNotice && + _dotnetFirstRunConfiguration.PrintTelemetryMessage && !_firstTimeUseNoticeSentinel.Exists(); } @@ -157,10 +151,7 @@ namespace Microsoft.DotNet.Configurer private bool ShouldRunFirstRunExperience() { - var skipFirstTimeExperience = - _environmentProvider.GetEnvironmentVariableAsBool("DOTNET_SKIP_FIRST_TIME_EXPERIENCE", false); - - return !skipFirstTimeExperience; + return !_dotnetFirstRunConfiguration.SkipFirstRunExperience; } } } diff --git a/src/dotnet/Program.cs b/src/dotnet/Program.cs index 6ae1409ce..1d8d94b90 100644 --- a/src/dotnet/Program.cs +++ b/src/dotnet/Program.cs @@ -141,6 +141,15 @@ namespace Microsoft.DotNet.Cli command = "help"; } + var environmentProvider = new EnvironmentProvider(); + + bool generateAspNetCertificate = + environmentProvider.GetEnvironmentVariableAsBool("DOTNET_GENERATE_ASPNET_CERTIFICATE", true); + bool printTelemetryMessage = + environmentProvider.GetEnvironmentVariableAsBool("DOTNET_PRINT_TELEMETRY_MESSAGE", true); + bool skipFirstRunExperience = + environmentProvider.GetEnvironmentVariableAsBool("DOTNET_SKIP_FIRST_TIME_EXPERIENCE", false); + topLevelCommandParserResult = new TopLevelCommandParserResult(command); var hasSuperUserAccess = false; if (IsDotnetBeingInvokedFromNativeInstaller(topLevelCommandParserResult)) @@ -149,15 +158,28 @@ namespace Microsoft.DotNet.Cli firstTimeUseNoticeSentinel = new NoOpFirstTimeUseNoticeSentinel(); toolPathSentinel = new NoOpFileSentinel(); hasSuperUserAccess = true; + + // When running through a native installer, we want the cache expansion to happen, so + // we need to override this. + skipFirstRunExperience = false; } + var dotnetFirstRunConfiguration = new DotnetFirstRunConfiguration + { + GenerateAspNetCertificate = generateAspNetCertificate, + PrintTelemetryMessage = printTelemetryMessage, + SkipFirstRunExperience = skipFirstRunExperience + }; + ConfigureDotNetForFirstTimeUse( nugetCacheSentinel, firstTimeUseNoticeSentinel, aspNetCertificateSentinel, toolPathSentinel, cliFallbackFolderPathCalculator, - hasSuperUserAccess); + hasSuperUserAccess, + dotnetFirstRunConfiguration, + environmentProvider); break; } @@ -222,15 +244,17 @@ namespace Microsoft.DotNet.Cli IAspNetCertificateSentinel aspNetCertificateSentinel, IFileSentinel toolPathSentinel, CliFolderPathCalculator cliFolderPathCalculator, - bool hasSuperUserAccess) + bool hasSuperUserAccess, + DotnetFirstRunConfiguration dotnetFirstRunConfiguration, + IEnvironmentProvider environmentProvider) { - var environmentProvider = new EnvironmentProvider(); - using (PerfTrace.Current.CaptureTiming()) { var nugetPackagesArchiver = new NuGetPackagesArchiver(); - var environmentPath = - EnvironmentPathFactory.CreateEnvironmentPath(cliFolderPathCalculator, hasSuperUserAccess, environmentProvider); + var environmentPath = EnvironmentPathFactory.CreateEnvironmentPath( + cliFolderPathCalculator, + hasSuperUserAccess, + environmentProvider); var commandFactory = new DotNetCommandFactory(alwaysRunOutOfProc: true); var nugetCachePrimer = new NuGetCachePrimer( nugetPackagesArchiver, @@ -244,7 +268,7 @@ namespace Microsoft.DotNet.Cli aspNetCertificateSentinel, aspnetCertificateGenerator, toolPathSentinel, - environmentProvider, + dotnetFirstRunConfiguration, Reporter.Output, cliFolderPathCalculator.CliFallbackFolderPath, environmentPath); diff --git a/test/Microsoft.DotNet.Configurer.UnitTests/GivenADotnetFirstTimeUseConfigurer.cs b/test/Microsoft.DotNet.Configurer.UnitTests/GivenADotnetFirstTimeUseConfigurer.cs index 115acacd7..cc5ac83e7 100644 --- a/test/Microsoft.DotNet.Configurer.UnitTests/GivenADotnetFirstTimeUseConfigurer.cs +++ b/test/Microsoft.DotNet.Configurer.UnitTests/GivenADotnetFirstTimeUseConfigurer.cs @@ -21,7 +21,6 @@ namespace Microsoft.DotNet.Configurer.UnitTests private Mock _aspNetCertificateSentinelMock; private Mock _aspNetCoreCertificateGeneratorMock; private Mock _toolPathSentinelMock; - private Mock _environmentProviderMock; private Mock _reporterMock; private Mock _pathAdderMock; @@ -33,16 +32,8 @@ namespace Microsoft.DotNet.Configurer.UnitTests _aspNetCertificateSentinelMock = new Mock(); _aspNetCoreCertificateGeneratorMock = new Mock(); _toolPathSentinelMock = new Mock(); - _environmentProviderMock = new Mock(); _reporterMock = new Mock(); _pathAdderMock = new Mock(); - - _environmentProviderMock - .Setup(e => e.GetEnvironmentVariableAsBool("DOTNET_SKIP_FIRST_TIME_EXPERIENCE", false)) - .Returns(false); - _environmentProviderMock - .Setup(e => e.GetEnvironmentVariableAsBool("DOTNET_PRINT_TELEMETRY_MESSAGE", true)) - .Returns(true); } [Fact] @@ -57,7 +48,11 @@ namespace Microsoft.DotNet.Configurer.UnitTests _aspNetCertificateSentinelMock.Object, _aspNetCoreCertificateGeneratorMock.Object, _toolPathSentinelMock.Object, - _environmentProviderMock.Object, + new DotnetFirstRunConfiguration + { + SkipFirstRunExperience = false, + PrintTelemetryMessage = true + }, _reporterMock.Object, CliFallbackFolderPath, _pathAdderMock.Object); @@ -72,9 +67,6 @@ namespace Microsoft.DotNet.Configurer.UnitTests public void It_does_not_print_the_first_time_use_notice_when_the_user_has_set_the_DOTNET_SKIP_FIRST_TIME_EXPERIENCE_environemnt_variable() { _firstTimeUseNoticeSentinelMock.Setup(n => n.Exists()).Returns(false); - _environmentProviderMock - .Setup(e => e.GetEnvironmentVariableAsBool("DOTNET_SKIP_FIRST_TIME_EXPERIENCE", false)) - .Returns(true); var dotnetFirstTimeUseConfigurer = new DotnetFirstTimeUseConfigurer( _nugetCachePrimerMock.Object, @@ -83,7 +75,11 @@ namespace Microsoft.DotNet.Configurer.UnitTests _aspNetCertificateSentinelMock.Object, _aspNetCoreCertificateGeneratorMock.Object, _toolPathSentinelMock.Object, - _environmentProviderMock.Object, + new DotnetFirstRunConfiguration + { + SkipFirstRunExperience = true, + PrintTelemetryMessage = true + }, _reporterMock.Object, CliFallbackFolderPath, _pathAdderMock.Object); @@ -98,9 +94,6 @@ namespace Microsoft.DotNet.Configurer.UnitTests public void It_does_not_print_the_first_time_use_notice_when_the_user_has_set_the_DOTNET_PRINT_TELEMETRY_MESSAGE_environemnt_variable() { _firstTimeUseNoticeSentinelMock.Setup(n => n.Exists()).Returns(false); - _environmentProviderMock - .Setup(e => e.GetEnvironmentVariableAsBool("DOTNET_PRINT_TELEMETRY_MESSAGE", true)) - .Returns(false); var dotnetFirstTimeUseConfigurer = new DotnetFirstTimeUseConfigurer( _nugetCachePrimerMock.Object, @@ -109,7 +102,11 @@ namespace Microsoft.DotNet.Configurer.UnitTests _aspNetCertificateSentinelMock.Object, _aspNetCoreCertificateGeneratorMock.Object, _toolPathSentinelMock.Object, - _environmentProviderMock.Object, + new DotnetFirstRunConfiguration + { + SkipFirstRunExperience = false, + PrintTelemetryMessage = false + }, _reporterMock.Object, CliFallbackFolderPath, _pathAdderMock.Object); @@ -132,7 +129,11 @@ namespace Microsoft.DotNet.Configurer.UnitTests _aspNetCertificateSentinelMock.Object, _aspNetCoreCertificateGeneratorMock.Object, _toolPathSentinelMock.Object, - _environmentProviderMock.Object, + new DotnetFirstRunConfiguration + { + SkipFirstRunExperience = false, + PrintTelemetryMessage = true + }, _reporterMock.Object, CliFallbackFolderPath, _pathAdderMock.Object); @@ -155,7 +156,11 @@ namespace Microsoft.DotNet.Configurer.UnitTests _aspNetCertificateSentinelMock.Object, _aspNetCoreCertificateGeneratorMock.Object, _toolPathSentinelMock.Object, - _environmentProviderMock.Object, + new DotnetFirstRunConfiguration + { + SkipFirstRunExperience = false, + PrintTelemetryMessage = true + }, _reporterMock.Object, CliFallbackFolderPath, _pathAdderMock.Object); @@ -177,7 +182,11 @@ namespace Microsoft.DotNet.Configurer.UnitTests _aspNetCertificateSentinelMock.Object, _aspNetCoreCertificateGeneratorMock.Object, _toolPathSentinelMock.Object, - _environmentProviderMock.Object, + new DotnetFirstRunConfiguration + { + SkipFirstRunExperience = false, + PrintTelemetryMessage = true + }, _reporterMock.Object, CliFallbackFolderPath, _pathAdderMock.Object); @@ -199,7 +208,11 @@ namespace Microsoft.DotNet.Configurer.UnitTests _aspNetCertificateSentinelMock.Object, _aspNetCoreCertificateGeneratorMock.Object, _toolPathSentinelMock.Object, - _environmentProviderMock.Object, + new DotnetFirstRunConfiguration + { + SkipFirstRunExperience = false, + PrintTelemetryMessage = true + }, _reporterMock.Object, CliFallbackFolderPath, _pathAdderMock.Object); @@ -210,12 +223,9 @@ namespace Microsoft.DotNet.Configurer.UnitTests } [Fact] - public void It_does_not_prime_the_cache_if_the_sentinel_exists_but_the_user_has_set_the_DOTNET_SKIP_FIRST_TIME_EXPERIENCE_environemnt_variable() + public void It_does_not_prime_the_cache_if_the_sentinel_does_not_exist_but_the_user_has_set_the_DOTNET_SKIP_FIRST_TIME_EXPERIENCE_environment_variable() { _nugetCacheSentinelMock.Setup(n => n.Exists()).Returns(false); - _environmentProviderMock - .Setup(e => e.GetEnvironmentVariableAsBool("DOTNET_SKIP_FIRST_TIME_EXPERIENCE", false)) - .Returns(true); var dotnetFirstTimeUseConfigurer = new DotnetFirstTimeUseConfigurer( _nugetCachePrimerMock.Object, @@ -224,7 +234,11 @@ namespace Microsoft.DotNet.Configurer.UnitTests _aspNetCertificateSentinelMock.Object, _aspNetCoreCertificateGeneratorMock.Object, _toolPathSentinelMock.Object, - _environmentProviderMock.Object, + new DotnetFirstRunConfiguration + { + SkipFirstRunExperience = true, + PrintTelemetryMessage = true + }, _reporterMock.Object, CliFallbackFolderPath, _pathAdderMock.Object); @@ -246,7 +260,11 @@ namespace Microsoft.DotNet.Configurer.UnitTests _aspNetCertificateSentinelMock.Object, _aspNetCoreCertificateGeneratorMock.Object, _toolPathSentinelMock.Object, - _environmentProviderMock.Object, + new DotnetFirstRunConfiguration + { + SkipFirstRunExperience = false, + PrintTelemetryMessage = true + }, _reporterMock.Object, CliFallbackFolderPath, _pathAdderMock.Object); @@ -269,7 +287,11 @@ namespace Microsoft.DotNet.Configurer.UnitTests _aspNetCertificateSentinelMock.Object, _aspNetCoreCertificateGeneratorMock.Object, _toolPathSentinelMock.Object, - _environmentProviderMock.Object, + new DotnetFirstRunConfiguration + { + SkipFirstRunExperience = false, + PrintTelemetryMessage = true + }, _reporterMock.Object, CliFallbackFolderPath, _pathAdderMock.Object); @@ -295,7 +317,11 @@ namespace Microsoft.DotNet.Configurer.UnitTests _aspNetCertificateSentinelMock.Object, _aspNetCoreCertificateGeneratorMock.Object, _toolPathSentinelMock.Object, - _environmentProviderMock.Object, + new DotnetFirstRunConfiguration + { + SkipFirstRunExperience = false, + PrintTelemetryMessage = true + }, _reporterMock.Object, CliFallbackFolderPath, _pathAdderMock.Object); @@ -322,7 +348,11 @@ namespace Microsoft.DotNet.Configurer.UnitTests _aspNetCertificateSentinelMock.Object, _aspNetCoreCertificateGeneratorMock.Object, _toolPathSentinelMock.Object, - _environmentProviderMock.Object, + new DotnetFirstRunConfiguration + { + SkipFirstRunExperience = false, + PrintTelemetryMessage = true + }, _reporterMock.Object, CliFallbackFolderPath, _pathAdderMock.Object); @@ -345,7 +375,12 @@ namespace Microsoft.DotNet.Configurer.UnitTests _aspNetCertificateSentinelMock.Object, _aspNetCoreCertificateGeneratorMock.Object, _toolPathSentinelMock.Object, - _environmentProviderMock.Object, + new DotnetFirstRunConfiguration + { + SkipFirstRunExperience = false, + PrintTelemetryMessage = true, + GenerateAspNetCertificate = true + }, _reporterMock.Object, CliFallbackFolderPath, _pathAdderMock.Object); @@ -368,7 +403,11 @@ namespace Microsoft.DotNet.Configurer.UnitTests _aspNetCertificateSentinelMock.Object, _aspNetCoreCertificateGeneratorMock.Object, _toolPathSentinelMock.Object, - _environmentProviderMock.Object, + new DotnetFirstRunConfiguration + { + SkipFirstRunExperience = false, + PrintTelemetryMessage = true + }, _reporterMock.Object, CliFallbackFolderPath, _pathAdderMock.Object); @@ -398,7 +437,11 @@ namespace Microsoft.DotNet.Configurer.UnitTests _aspNetCertificateSentinelMock.Object, _aspNetCoreCertificateGeneratorMock.Object, _toolPathSentinelMock.Object, - _environmentProviderMock.Object, + new DotnetFirstRunConfiguration + { + SkipFirstRunExperience = false, + PrintTelemetryMessage = true + }, _reporterMock.Object, CliFallbackFolderPath, _pathAdderMock.Object); @@ -420,7 +463,11 @@ namespace Microsoft.DotNet.Configurer.UnitTests _aspNetCertificateSentinelMock.Object, _aspNetCoreCertificateGeneratorMock.Object, _toolPathSentinelMock.Object, - _environmentProviderMock.Object, + new DotnetFirstRunConfiguration + { + SkipFirstRunExperience = false, + PrintTelemetryMessage = true + }, _reporterMock.Object, CliFallbackFolderPath, _pathAdderMock.Object); @@ -435,9 +482,6 @@ namespace Microsoft.DotNet.Configurer.UnitTests public void It_does_not_generate_the_aspnet_https_development_certificate_when_the_user_has_set_the_DOTNET_SKIP_FIRST_TIME_EXPERIENCE_environment_variable() { _aspNetCertificateSentinelMock.Setup(n => n.Exists()).Returns(false); - _environmentProviderMock - .Setup(e => e.GetEnvironmentVariableAsBool("DOTNET_SKIP_FIRST_TIME_EXPERIENCE", false)) - .Returns(true); var dotnetFirstTimeUseConfigurer = new DotnetFirstTimeUseConfigurer( _nugetCachePrimerMock.Object, @@ -446,7 +490,11 @@ namespace Microsoft.DotNet.Configurer.UnitTests _aspNetCertificateSentinelMock.Object, _aspNetCoreCertificateGeneratorMock.Object, _toolPathSentinelMock.Object, - _environmentProviderMock.Object, + new DotnetFirstRunConfiguration + { + SkipFirstRunExperience = false, + PrintTelemetryMessage = true + }, _reporterMock.Object, CliFallbackFolderPath, _pathAdderMock.Object); @@ -461,9 +509,6 @@ namespace Microsoft.DotNet.Configurer.UnitTests public void It_does_not_generate_the_aspnet_https_development_certificate_when_the_user_has_set_the_DOTNET_GENERATE_ASPNET_CERTIFICATE_environment_variable() { _aspNetCertificateSentinelMock.Setup(n => n.Exists()).Returns(false); - _environmentProviderMock - .Setup(e => e.GetEnvironmentVariableAsBool("DOTNET_GENERATE_ASPNET_CERTIFICATE", true)) - .Returns(false); var dotnetFirstTimeUseConfigurer = new DotnetFirstTimeUseConfigurer( _nugetCachePrimerMock.Object, @@ -472,7 +517,11 @@ namespace Microsoft.DotNet.Configurer.UnitTests _aspNetCertificateSentinelMock.Object, _aspNetCoreCertificateGeneratorMock.Object, _toolPathSentinelMock.Object, - _environmentProviderMock.Object, + new DotnetFirstRunConfiguration + { + SkipFirstRunExperience = false, + PrintTelemetryMessage = true + }, _reporterMock.Object, CliFallbackFolderPath, _pathAdderMock.Object); @@ -487,8 +536,6 @@ namespace Microsoft.DotNet.Configurer.UnitTests public void It_generates_the_aspnet_https_development_certificate_if_the_sentinel_does_not_exist() { _aspNetCertificateSentinelMock.Setup(n => n.Exists()).Returns(false); - _environmentProviderMock.Setup(e => e.GetEnvironmentVariableAsBool("DOTNET_GENERATE_ASPNET_CERTIFICATE", true)) - .Returns(true); var dotnetFirstTimeUseConfigurer = new DotnetFirstTimeUseConfigurer( _nugetCachePrimerMock.Object, @@ -497,7 +544,12 @@ namespace Microsoft.DotNet.Configurer.UnitTests _aspNetCertificateSentinelMock.Object, _aspNetCoreCertificateGeneratorMock.Object, _toolPathSentinelMock.Object, - _environmentProviderMock.Object, + new DotnetFirstRunConfiguration + { + SkipFirstRunExperience = false, + PrintTelemetryMessage = true, + GenerateAspNetCertificate = true + }, _reporterMock.Object, CliFallbackFolderPath, _pathAdderMock.Object); @@ -520,7 +572,12 @@ namespace Microsoft.DotNet.Configurer.UnitTests _aspNetCertificateSentinelMock.Object, _aspNetCoreCertificateGeneratorMock.Object, _toolPathSentinelMock.Object, - _environmentProviderMock.Object, + new DotnetFirstRunConfiguration + { + SkipFirstRunExperience = false, + PrintTelemetryMessage = true, + GenerateAspNetCertificate = true + }, _reporterMock.Object, CliFallbackFolderPath, _pathAdderMock.Object); @@ -533,10 +590,6 @@ namespace Microsoft.DotNet.Configurer.UnitTests [Fact] public void It_does_not_add_the_tool_path_to_the_environment_if_the_first_run_experience_is_skipped() { - _environmentProviderMock - .Setup(e => e.GetEnvironmentVariableAsBool("DOTNET_SKIP_FIRST_TIME_EXPERIENCE", false)) - .Returns(true); - var dotnetFirstTimeUseConfigurer = new DotnetFirstTimeUseConfigurer( _nugetCachePrimerMock.Object, _nugetCacheSentinelMock.Object, @@ -544,7 +597,12 @@ namespace Microsoft.DotNet.Configurer.UnitTests _aspNetCertificateSentinelMock.Object, _aspNetCoreCertificateGeneratorMock.Object, _toolPathSentinelMock.Object, - _environmentProviderMock.Object, + new DotnetFirstRunConfiguration + { + SkipFirstRunExperience = true, + PrintTelemetryMessage = true, + GenerateAspNetCertificate = true + }, _reporterMock.Object, CliFallbackFolderPath, _pathAdderMock.Object);