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);
}