diff --git a/src/Installer/Microsoft.Dotnet.Installation/DotnetInstallException.cs b/src/Installer/Microsoft.Dotnet.Installation/DotnetInstallException.cs index 5437a918faeb..4568453316dd 100644 --- a/src/Installer/Microsoft.Dotnet.Installation/DotnetInstallException.cs +++ b/src/Installer/Microsoft.Dotnet.Installation/DotnetInstallException.cs @@ -133,6 +133,12 @@ public enum DotnetInstallErrorCode /// Distinct from /// NoUserInstallableArtifact, + + /// + /// An access mode reached a workflow that does not support it, indicating inconsistent + /// product state rather than invalid user input. + /// + InvalidModeSelection, } /// diff --git a/src/Installer/dotnetup.Library/Commands/Init/InitWorkflowDefaults.cs b/src/Installer/dotnetup.Library/Commands/Init/InitWorkflowDefaults.cs index 443f64e2aab1..2f1fce951d57 100644 --- a/src/Installer/dotnetup.Library/Commands/Init/InitWorkflowDefaults.cs +++ b/src/Installer/dotnetup.Library/Commands/Init/InitWorkflowDefaults.cs @@ -28,7 +28,11 @@ public static WalkthroughPlan ResolveWalkthroughPlan( List? preResolvedRequests, IDotnetEnvironmentManager dotnetEnvironment) { - DotnetAccessMode accessMode = GetDefaultAccessMode(command.ShellProvider); + IEnvShellProvider? shellProvider = command.ShellProvider ?? ShellDetection.GetCurrentShellProvider(); + DotnetAccessMode accessMode = GetDefaultAccessMode(shellProvider); + var globalJson = GlobalJsonModifier.GetGlobalJsonInfo(Environment.CurrentDirectory); + var pathResolution = new InstallPathResolver(dotnetEnvironment).Resolve( + command.InstallPath, globalJson); if (preResolvedRequests is { Count: > 0 }) { @@ -41,12 +45,11 @@ public static WalkthroughPlan ResolveWalkthroughPlan( resolvedRoot, accessMode, resolvedMigrations, - new DefaultChannelDisplay(first.Request.Channel.Name, first.Request.Options.GlobalJsonPath)); + new DefaultChannelDisplay(first.Request.Channel.Name, first.Request.Options.GlobalJsonPath), + shellProvider, + GetInstallRootGlobalJsonPath(pathResolution, globalJson, resolvedRoot)); } - var globalJson = GlobalJsonModifier.GetGlobalJsonInfo(Environment.CurrentDirectory); - var pathResolution = new InstallPathResolver(dotnetEnvironment).Resolve( - command.InstallPath, globalJson); var installRoot = new DotnetInstallRoot( pathResolution.ResolvedInstallPath, InstallerUtilities.GetDefaultInstallArchitecture()); @@ -54,9 +57,24 @@ public static WalkthroughPlan ResolveWalkthroughPlan( var migrations = ResolveDefaultMigrations( dotnetEnvironment, accessMode, installRoot, command.ManifestPath, existingRequests: null); - return new WalkthroughPlan(installRoot, accessMode, migrations, ResolveChannelDisplay(globalJson)); + return new WalkthroughPlan( + installRoot, + accessMode, + migrations, + ResolveChannelDisplay(globalJson), + shellProvider, + GetInstallRootGlobalJsonPath(pathResolution, globalJson, installRoot)); } + private static string? GetInstallRootGlobalJsonPath( + InstallPathResolver.InstallPathResolutionResult pathResolution, + GlobalJsonInfo globalJson, + DotnetInstallRoot installRoot) + => pathResolution.PathSource is PathSource.GlobalJson + && DotnetupUtilities.PathsEqual(pathResolution.ResolvedInstallPath, installRoot.Path) + ? globalJson.GlobalJsonPath + : null; + /// /// Resolves the default install requests. Uses the pre-resolved requests when supplied; /// otherwise resolves the default SDK channel (from global.json or "latest"). This performs diff --git a/src/Installer/dotnetup.Library/Commands/Init/WalkthroughPlan.cs b/src/Installer/dotnetup.Library/Commands/Init/WalkthroughPlan.cs index 2d419f493ee8..ad5885351958 100644 --- a/src/Installer/dotnetup.Library/Commands/Init/WalkthroughPlan.cs +++ b/src/Installer/dotnetup.Library/Commands/Init/WalkthroughPlan.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.DotNet.Tools.Bootstrapper.Commands.Shared; +using Microsoft.DotNet.Tools.Bootstrapper.Shell; namespace Microsoft.DotNet.Tools.Bootstrapper.Commands.Init; @@ -15,8 +16,12 @@ namespace Microsoft.DotNet.Tools.Bootstrapper.Commands.Init; /// The recommended access mode. /// The system installs eligible for migration under the recommended mode. /// Display information for the SDK channel line. +/// The resolved shell provider used to recommend and describe terminal mode. +/// The global.json that supplied the install root, if any. internal sealed record WalkthroughPlan( DotnetInstallRoot InstallRoot, DotnetAccessMode AccessMode, List Migrations, - DefaultChannelDisplay ChannelDisplay); + DefaultChannelDisplay ChannelDisplay, + IEnvShellProvider? ShellProvider, + string? InstallRootGlobalJsonPath); diff --git a/src/Installer/dotnetup.Library/Commands/Init/WalkthroughSummary.cs b/src/Installer/dotnetup.Library/Commands/Init/WalkthroughSummary.cs index 22b290276ea4..a49ba025c027 100644 --- a/src/Installer/dotnetup.Library/Commands/Init/WalkthroughSummary.cs +++ b/src/Installer/dotnetup.Library/Commands/Init/WalkthroughSummary.cs @@ -3,6 +3,7 @@ using System.Globalization; using Microsoft.DotNet.Tools.Bootstrapper.Commands.Shared; +using Microsoft.DotNet.Tools.Bootstrapper.Shell; using Spectre.Console; using SpectreAnsiConsole = Spectre.Console.AnsiConsole; @@ -97,11 +98,62 @@ private static void RenderSummaryBlock(WalkthroughPlan plan, DotnetAccessMode? c RenderChannelLine(plan.ChannelDisplay); RenderModeLine(plan.AccessMode, configuredAccessMode); + SpectreAnsiConsole.WriteLine(); + SpectreAnsiConsole.MarkupLine(BuildModeDescription(plan)); RenderMigrationSummary(plan.Migrations); SpectreAnsiConsole.WriteLine(); } + internal static string BuildModeDescription(WalkthroughPlan plan) + { + string mode = DotnetupTheme.Accent(DotnetAccessModeDisplay.GetName(plan.AccessMode).EscapeMarkup()); + + if (plan.AccessMode is DotnetAccessMode.None) + { + string currentShell = DotnetupTheme.Accent(ShellDetection.GetCurrentShellDisplayName().EscapeMarkup()); + string supportedShells = DotnetupTheme.Accent( + string.Join(", ", ShellDetection.s_supportedShells.Select(shell => shell.ArgumentName)).EscapeMarkup()); + + return string.Format( + CultureInfo.InvariantCulture, + Strings.SummaryModeUnsupportedShell, + mode, + currentShell, + supportedShells); + } + + string configurationTarget = plan.AccessMode switch + { + DotnetAccessMode.Shell when plan.ShellProvider is { } shellProvider => string.Join( + ", ", + shellProvider.GetProfilePaths().Select(path => DotnetupTheme.Accent(path.EscapeMarkup()))), + DotnetAccessMode.Everywhere => DotnetupTheme.Accent( + Strings.SummaryModeSystemEnvironmentVariables.EscapeMarkup()), + _ => throw new DotnetInstallException( + DotnetInstallErrorCode.InvalidModeSelection, + $"Unable to describe access mode '{plan.AccessMode}' with the resolved shell provider."), + }; + + string installRoot = DotnetupTheme.Accent(plan.InstallRoot.Path.EscapeMarkup()); + if (plan.InstallRootGlobalJsonPath is { } globalJsonPath) + { + installRoot += " " + DotnetupTheme.Dim(string.Format( + CultureInfo.InvariantCulture, + Strings.SummaryModeInstallRootGlobalJsonSuffix, + globalJsonPath.EscapeMarkup())); + } + + return string.Format( + CultureInfo.InvariantCulture, + Strings.SummaryModeConfiguration, + mode, + configurationTarget, + DotnetupTheme.Accent("PATH"), + DotnetupTheme.Accent("DOTNET_ROOT"), + installRoot); + } + private static void RenderChannelLine(DefaultChannelDisplay channel) { if (channel.ChannelLabel is null) diff --git a/src/Installer/dotnetup.Library/Strings.resx b/src/Installer/dotnetup.Library/Strings.resx index 2561ae57c2d0..f64470c9a2ee 100644 --- a/src/Installer/dotnetup.Library/Strings.resx +++ b/src/Installer/dotnetup.Library/Strings.resx @@ -450,6 +450,21 @@ Or open a new terminal. current: {0} {0} is the user's currently configured mode name. Shown in parentheses after the recommended mode. + + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} is the suggested mode name; {1} is one or more shell profile paths or the system environment variables; {2} is PATH; {3} is DOTNET_ROOT; {4} is the dotnetup install path. + + + the system environment variables + + + (inferred from {0}) + {0} is the path to the global.json file that supplied the dotnetup install root. + + + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is the suggested isolation mode name; {1} is the current SHELL value or "(not set)"; {2} is the list of supported shell names. + System installs to migrate: diff --git a/src/Installer/dotnetup.Library/Telemetry/ErrorCategoryClassifier.cs b/src/Installer/dotnetup.Library/Telemetry/ErrorCategoryClassifier.cs index be11b4d32578..bda21ec044e4 100644 --- a/src/Installer/dotnetup.Library/Telemetry/ErrorCategoryClassifier.cs +++ b/src/Installer/dotnetup.Library/Telemetry/ErrorCategoryClassifier.cs @@ -57,6 +57,7 @@ internal static ErrorCategory ClassifyInstallError(DotnetInstallErrorCode errorC DotnetInstallErrorCode.UninstallTargetNotFound => ErrorCategory.User, DotnetInstallErrorCode.UnsignedDownloadBlockedByPolicy => ErrorCategory.User, DotnetInstallErrorCode.NoUserInstallableArtifact => ErrorCategory.User, + DotnetInstallErrorCode.InvalidModeSelection => ErrorCategory.Product, DotnetInstallErrorCode.Unknown => ErrorCategory.Product, _ => ErrorCategory.Product diff --git a/src/Installer/dotnetup.Library/xlf/Strings.cs.xlf b/src/Installer/dotnetup.Library/xlf/Strings.cs.xlf index baae108b7241..f760e287d16c 100644 --- a/src/Installer/dotnetup.Library/xlf/Strings.cs.xlf +++ b/src/Installer/dotnetup.Library/xlf/Strings.cs.xlf @@ -501,16 +501,36 @@ Or open a new terminal. ... and {0} more {0} is the count of additional migration candidates not individually listed. + + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} is the suggested mode name; {1} is one or more shell profile paths or the system environment variables; {2} is PATH; {3} is DOTNET_ROOT; {4} is the dotnetup install path. + current: {0} current: {0} {0} is the user's currently configured mode name. Shown in parentheses after the recommended mode. + + (inferred from {0}) + (inferred from {0}) + {0} is the path to the global.json file that supplied the dotnetup install root. + Mode: Mode: + + the system environment variables + the system environment variables + + + + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is the suggested isolation mode name; {1} is the current SHELL value or "(not set)"; {2} is the list of supported shell names. + Replace your current settings with the recommended ones above. Replace your current settings with the recommended ones above. diff --git a/src/Installer/dotnetup.Library/xlf/Strings.de.xlf b/src/Installer/dotnetup.Library/xlf/Strings.de.xlf index 20944814a5ac..5994482e6c56 100644 --- a/src/Installer/dotnetup.Library/xlf/Strings.de.xlf +++ b/src/Installer/dotnetup.Library/xlf/Strings.de.xlf @@ -501,16 +501,36 @@ Or open a new terminal. ... and {0} more {0} is the count of additional migration candidates not individually listed. + + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} is the suggested mode name; {1} is one or more shell profile paths or the system environment variables; {2} is PATH; {3} is DOTNET_ROOT; {4} is the dotnetup install path. + current: {0} current: {0} {0} is the user's currently configured mode name. Shown in parentheses after the recommended mode. + + (inferred from {0}) + (inferred from {0}) + {0} is the path to the global.json file that supplied the dotnetup install root. + Mode: Mode: + + the system environment variables + the system environment variables + + + + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is the suggested isolation mode name; {1} is the current SHELL value or "(not set)"; {2} is the list of supported shell names. + Replace your current settings with the recommended ones above. Replace your current settings with the recommended ones above. diff --git a/src/Installer/dotnetup.Library/xlf/Strings.es.xlf b/src/Installer/dotnetup.Library/xlf/Strings.es.xlf index 40e906dab3df..07a56d3dcaf6 100644 --- a/src/Installer/dotnetup.Library/xlf/Strings.es.xlf +++ b/src/Installer/dotnetup.Library/xlf/Strings.es.xlf @@ -501,16 +501,36 @@ Or open a new terminal. ... and {0} more {0} is the count of additional migration candidates not individually listed. + + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} is the suggested mode name; {1} is one or more shell profile paths or the system environment variables; {2} is PATH; {3} is DOTNET_ROOT; {4} is the dotnetup install path. + current: {0} current: {0} {0} is the user's currently configured mode name. Shown in parentheses after the recommended mode. + + (inferred from {0}) + (inferred from {0}) + {0} is the path to the global.json file that supplied the dotnetup install root. + Mode: Mode: + + the system environment variables + the system environment variables + + + + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is the suggested isolation mode name; {1} is the current SHELL value or "(not set)"; {2} is the list of supported shell names. + Replace your current settings with the recommended ones above. Replace your current settings with the recommended ones above. diff --git a/src/Installer/dotnetup.Library/xlf/Strings.fr.xlf b/src/Installer/dotnetup.Library/xlf/Strings.fr.xlf index 538aff16acb5..48f7621257ab 100644 --- a/src/Installer/dotnetup.Library/xlf/Strings.fr.xlf +++ b/src/Installer/dotnetup.Library/xlf/Strings.fr.xlf @@ -501,16 +501,36 @@ Or open a new terminal. ... and {0} more {0} is the count of additional migration candidates not individually listed. + + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} is the suggested mode name; {1} is one or more shell profile paths or the system environment variables; {2} is PATH; {3} is DOTNET_ROOT; {4} is the dotnetup install path. + current: {0} current: {0} {0} is the user's currently configured mode name. Shown in parentheses after the recommended mode. + + (inferred from {0}) + (inferred from {0}) + {0} is the path to the global.json file that supplied the dotnetup install root. + Mode: Mode: + + the system environment variables + the system environment variables + + + + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is the suggested isolation mode name; {1} is the current SHELL value or "(not set)"; {2} is the list of supported shell names. + Replace your current settings with the recommended ones above. Replace your current settings with the recommended ones above. diff --git a/src/Installer/dotnetup.Library/xlf/Strings.it.xlf b/src/Installer/dotnetup.Library/xlf/Strings.it.xlf index 23dd3ed3abba..6b84441da423 100644 --- a/src/Installer/dotnetup.Library/xlf/Strings.it.xlf +++ b/src/Installer/dotnetup.Library/xlf/Strings.it.xlf @@ -501,16 +501,36 @@ Or open a new terminal. ... and {0} more {0} is the count of additional migration candidates not individually listed. + + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} is the suggested mode name; {1} is one or more shell profile paths or the system environment variables; {2} is PATH; {3} is DOTNET_ROOT; {4} is the dotnetup install path. + current: {0} current: {0} {0} is the user's currently configured mode name. Shown in parentheses after the recommended mode. + + (inferred from {0}) + (inferred from {0}) + {0} is the path to the global.json file that supplied the dotnetup install root. + Mode: Mode: + + the system environment variables + the system environment variables + + + + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is the suggested isolation mode name; {1} is the current SHELL value or "(not set)"; {2} is the list of supported shell names. + Replace your current settings with the recommended ones above. Replace your current settings with the recommended ones above. diff --git a/src/Installer/dotnetup.Library/xlf/Strings.ja.xlf b/src/Installer/dotnetup.Library/xlf/Strings.ja.xlf index 8084a2728f7e..5d58ec89ffa2 100644 --- a/src/Installer/dotnetup.Library/xlf/Strings.ja.xlf +++ b/src/Installer/dotnetup.Library/xlf/Strings.ja.xlf @@ -501,16 +501,36 @@ Or open a new terminal. ... and {0} more {0} is the count of additional migration candidates not individually listed. + + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} is the suggested mode name; {1} is one or more shell profile paths or the system environment variables; {2} is PATH; {3} is DOTNET_ROOT; {4} is the dotnetup install path. + current: {0} current: {0} {0} is the user's currently configured mode name. Shown in parentheses after the recommended mode. + + (inferred from {0}) + (inferred from {0}) + {0} is the path to the global.json file that supplied the dotnetup install root. + Mode: Mode: + + the system environment variables + the system environment variables + + + + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is the suggested isolation mode name; {1} is the current SHELL value or "(not set)"; {2} is the list of supported shell names. + Replace your current settings with the recommended ones above. Replace your current settings with the recommended ones above. diff --git a/src/Installer/dotnetup.Library/xlf/Strings.ko.xlf b/src/Installer/dotnetup.Library/xlf/Strings.ko.xlf index 507538618652..c1d804c37f4d 100644 --- a/src/Installer/dotnetup.Library/xlf/Strings.ko.xlf +++ b/src/Installer/dotnetup.Library/xlf/Strings.ko.xlf @@ -501,16 +501,36 @@ Or open a new terminal. ... and {0} more {0} is the count of additional migration candidates not individually listed. + + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} is the suggested mode name; {1} is one or more shell profile paths or the system environment variables; {2} is PATH; {3} is DOTNET_ROOT; {4} is the dotnetup install path. + current: {0} current: {0} {0} is the user's currently configured mode name. Shown in parentheses after the recommended mode. + + (inferred from {0}) + (inferred from {0}) + {0} is the path to the global.json file that supplied the dotnetup install root. + Mode: Mode: + + the system environment variables + the system environment variables + + + + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is the suggested isolation mode name; {1} is the current SHELL value or "(not set)"; {2} is the list of supported shell names. + Replace your current settings with the recommended ones above. Replace your current settings with the recommended ones above. diff --git a/src/Installer/dotnetup.Library/xlf/Strings.pl.xlf b/src/Installer/dotnetup.Library/xlf/Strings.pl.xlf index 4bcdd94a0694..9e6bf3f94b38 100644 --- a/src/Installer/dotnetup.Library/xlf/Strings.pl.xlf +++ b/src/Installer/dotnetup.Library/xlf/Strings.pl.xlf @@ -501,16 +501,36 @@ Or open a new terminal. ... and {0} more {0} is the count of additional migration candidates not individually listed. + + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} is the suggested mode name; {1} is one or more shell profile paths or the system environment variables; {2} is PATH; {3} is DOTNET_ROOT; {4} is the dotnetup install path. + current: {0} current: {0} {0} is the user's currently configured mode name. Shown in parentheses after the recommended mode. + + (inferred from {0}) + (inferred from {0}) + {0} is the path to the global.json file that supplied the dotnetup install root. + Mode: Mode: + + the system environment variables + the system environment variables + + + + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is the suggested isolation mode name; {1} is the current SHELL value or "(not set)"; {2} is the list of supported shell names. + Replace your current settings with the recommended ones above. Replace your current settings with the recommended ones above. diff --git a/src/Installer/dotnetup.Library/xlf/Strings.pt-BR.xlf b/src/Installer/dotnetup.Library/xlf/Strings.pt-BR.xlf index 54c0ad32a4fc..342352d466b1 100644 --- a/src/Installer/dotnetup.Library/xlf/Strings.pt-BR.xlf +++ b/src/Installer/dotnetup.Library/xlf/Strings.pt-BR.xlf @@ -501,16 +501,36 @@ Or open a new terminal. ... and {0} more {0} is the count of additional migration candidates not individually listed. + + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} is the suggested mode name; {1} is one or more shell profile paths or the system environment variables; {2} is PATH; {3} is DOTNET_ROOT; {4} is the dotnetup install path. + current: {0} current: {0} {0} is the user's currently configured mode name. Shown in parentheses after the recommended mode. + + (inferred from {0}) + (inferred from {0}) + {0} is the path to the global.json file that supplied the dotnetup install root. + Mode: Mode: + + the system environment variables + the system environment variables + + + + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is the suggested isolation mode name; {1} is the current SHELL value or "(not set)"; {2} is the list of supported shell names. + Replace your current settings with the recommended ones above. Replace your current settings with the recommended ones above. diff --git a/src/Installer/dotnetup.Library/xlf/Strings.ru.xlf b/src/Installer/dotnetup.Library/xlf/Strings.ru.xlf index bcc012228438..8726d4326e44 100644 --- a/src/Installer/dotnetup.Library/xlf/Strings.ru.xlf +++ b/src/Installer/dotnetup.Library/xlf/Strings.ru.xlf @@ -501,16 +501,36 @@ Or open a new terminal. ... and {0} more {0} is the count of additional migration candidates not individually listed. + + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} is the suggested mode name; {1} is one or more shell profile paths or the system environment variables; {2} is PATH; {3} is DOTNET_ROOT; {4} is the dotnetup install path. + current: {0} current: {0} {0} is the user's currently configured mode name. Shown in parentheses after the recommended mode. + + (inferred from {0}) + (inferred from {0}) + {0} is the path to the global.json file that supplied the dotnetup install root. + Mode: Mode: + + the system environment variables + the system environment variables + + + + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is the suggested isolation mode name; {1} is the current SHELL value or "(not set)"; {2} is the list of supported shell names. + Replace your current settings with the recommended ones above. Replace your current settings with the recommended ones above. diff --git a/src/Installer/dotnetup.Library/xlf/Strings.tr.xlf b/src/Installer/dotnetup.Library/xlf/Strings.tr.xlf index bca6f27b1598..57d6b7ca41a1 100644 --- a/src/Installer/dotnetup.Library/xlf/Strings.tr.xlf +++ b/src/Installer/dotnetup.Library/xlf/Strings.tr.xlf @@ -501,16 +501,36 @@ Or open a new terminal. ... and {0} more {0} is the count of additional migration candidates not individually listed. + + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} is the suggested mode name; {1} is one or more shell profile paths or the system environment variables; {2} is PATH; {3} is DOTNET_ROOT; {4} is the dotnetup install path. + current: {0} current: {0} {0} is the user's currently configured mode name. Shown in parentheses after the recommended mode. + + (inferred from {0}) + (inferred from {0}) + {0} is the path to the global.json file that supplied the dotnetup install root. + Mode: Mode: + + the system environment variables + the system environment variables + + + + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is the suggested isolation mode name; {1} is the current SHELL value or "(not set)"; {2} is the list of supported shell names. + Replace your current settings with the recommended ones above. Replace your current settings with the recommended ones above. diff --git a/src/Installer/dotnetup.Library/xlf/Strings.zh-Hans.xlf b/src/Installer/dotnetup.Library/xlf/Strings.zh-Hans.xlf index 82fb041deab3..747eeb4006dd 100644 --- a/src/Installer/dotnetup.Library/xlf/Strings.zh-Hans.xlf +++ b/src/Installer/dotnetup.Library/xlf/Strings.zh-Hans.xlf @@ -501,16 +501,36 @@ Or open a new terminal. ... and {0} more {0} is the count of additional migration candidates not individually listed. + + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} is the suggested mode name; {1} is one or more shell profile paths or the system environment variables; {2} is PATH; {3} is DOTNET_ROOT; {4} is the dotnetup install path. + current: {0} current: {0} {0} is the user's currently configured mode name. Shown in parentheses after the recommended mode. + + (inferred from {0}) + (inferred from {0}) + {0} is the path to the global.json file that supplied the dotnetup install root. + Mode: Mode: + + the system environment variables + the system environment variables + + + + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is the suggested isolation mode name; {1} is the current SHELL value or "(not set)"; {2} is the list of supported shell names. + Replace your current settings with the recommended ones above. Replace your current settings with the recommended ones above. diff --git a/src/Installer/dotnetup.Library/xlf/Strings.zh-Hant.xlf b/src/Installer/dotnetup.Library/xlf/Strings.zh-Hant.xlf index 2e98b3f4022d..10bc51d65230 100644 --- a/src/Installer/dotnetup.Library/xlf/Strings.zh-Hant.xlf +++ b/src/Installer/dotnetup.Library/xlf/Strings.zh-Hant.xlf @@ -501,16 +501,36 @@ Or open a new terminal. ... and {0} more {0} is the count of additional migration candidates not individually listed. + + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} modifies {1} to set {2} and {3} to prefer {4}. + {0} is the suggested mode name; {1} is one or more shell profile paths or the system environment variables; {2} is PATH; {3} is DOTNET_ROOT; {4} is the dotnetup install path. + current: {0} current: {0} {0} is the user's currently configured mode name. Shown in parentheses after the recommended mode. + + (inferred from {0}) + (inferred from {0}) + {0} is the path to the global.json file that supplied the dotnetup install root. + Mode: Mode: + + the system environment variables + the system environment variables + + + + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}. + {0} is the suggested isolation mode name; {1} is the current SHELL value or "(not set)"; {2} is the list of supported shell names. + Replace your current settings with the recommended ones above. Replace your current settings with the recommended ones above. diff --git a/test/dotnetup.Tests/WalkthroughSummaryTests.cs b/test/dotnetup.Tests/WalkthroughSummaryTests.cs index 6017aa0fed28..8466b985270e 100644 --- a/test/dotnetup.Tests/WalkthroughSummaryTests.cs +++ b/test/dotnetup.Tests/WalkthroughSummaryTests.cs @@ -2,7 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. using FluentAssertions; +using Microsoft.Dotnet.Installation; +using Microsoft.DotNet.Tools.Bootstrapper; using Microsoft.DotNet.Tools.Bootstrapper.Commands.Init; +using Microsoft.DotNet.Tools.Bootstrapper.Shell; +using Microsoft.DotNet.Tools.Bootstrapper.Telemetry; namespace Microsoft.DotNet.Tools.Dotnetup.Tests; @@ -55,4 +59,91 @@ public void GetDefaultChoiceIndex_Configured_DefaultsToCustomize() choices[index].Decision.Should().Be(WalkthroughDecision.Customize); } + + [TestMethod] + public void BuildModeDescription_TerminalMode_ShowsProfilePathsAndInstallRoot() + { + var shellProvider = new TestShellProvider("profile-root", ".bashrc", ".profile"); + var plan = CreatePlan(DotnetAccessMode.Shell, shellProvider); + + string description = WalkthroughSummary.BuildModeDescription(plan); + + description.Should().Contain(DotnetupTheme.Accent("Terminal Mode")); + foreach (string path in shellProvider.GetProfilePaths()) + { + description.Should().Contain(DotnetupTheme.Accent(path)); + } + + description.Should().Contain(DotnetupTheme.Accent("PATH")); + description.Should().Contain(DotnetupTheme.Accent("DOTNET_ROOT")); + description.Should().Contain(DotnetupTheme.Accent(plan.InstallRoot.Path)); + } + + [TestMethod] + public void BuildModeDescription_EverywhereMode_ShowsSystemEnvironmentVariablesAndInstallRoot() + { + var plan = CreatePlan(DotnetAccessMode.Everywhere, shellProvider: null); + + string description = WalkthroughSummary.BuildModeDescription(plan); + + description.Should().Contain(DotnetupTheme.Accent("Everywhere Mode")); + description.Should().Contain(DotnetupTheme.Accent( + Microsoft.DotNet.Tools.Bootstrapper.Strings.SummaryModeSystemEnvironmentVariables)); + description.Should().Contain(DotnetupTheme.Accent("PATH")); + description.Should().Contain(DotnetupTheme.Accent("DOTNET_ROOT")); + description.Should().Contain(DotnetupTheme.Accent(plan.InstallRoot.Path)); + } + + [TestMethod] + public void BuildModeDescription_GlobalJsonInstallRoot_ShowsSourcePath() + { + const string globalJsonPath = "repo-root/global.json"; + var plan = CreatePlan( + DotnetAccessMode.Everywhere, + shellProvider: null, + installRootGlobalJsonPath: globalJsonPath); + + string description = WalkthroughSummary.BuildModeDescription(plan); + + description.Should().Contain(DotnetupTheme.Dim($"(inferred from {globalJsonPath})")); + } + + [TestMethod] + public void BuildModeDescription_IsolationMode_ExplainsUnsupportedShell() + { + var plan = CreatePlan(DotnetAccessMode.None, shellProvider: null); + + string description = WalkthroughSummary.BuildModeDescription(plan); + + description.Should().Contain(DotnetupTheme.Accent("Isolation Mode")); + description.Should().Contain("cannot be detected or is not supported"); + foreach (IEnvShellProvider supportedShell in ShellDetection.s_supportedShells) + { + description.Should().Contain(supportedShell.ArgumentName); + } + } + + [TestMethod] + public void BuildModeDescription_TerminalModeWithoutShellProvider_ThrowsProductException() + { + var plan = CreatePlan(DotnetAccessMode.Shell, shellProvider: null); + + var exception = Assert.ThrowsExactly( + () => WalkthroughSummary.BuildModeDescription(plan)); + + exception.ErrorCode.Should().Be(DotnetInstallErrorCode.InvalidModeSelection); + ErrorCategoryClassifier.ClassifyInstallError(exception.ErrorCode).Should().Be(ErrorCategory.Product); + } + + private static WalkthroughPlan CreatePlan( + DotnetAccessMode accessMode, + IEnvShellProvider? shellProvider, + string? installRootGlobalJsonPath = null) + => new( + new DotnetInstallRoot("dotnetup-hive", InstallArchitecture.x64), + accessMode, + [], + new DefaultChannelDisplay("latest", GlobalJsonPath: null), + shellProvider, + installRootGlobalJsonPath); }