Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ public enum DotnetInstallErrorCode
/// Distinct from <see cref="NoMatchingReleaseFileForPlatform"/>
/// </summary>
NoUserInstallableArtifact,

/// <summary>
/// An access mode reached a workflow that does not support it, indicating inconsistent
/// product state rather than invalid user input.
/// </summary>
InvalidModeSelection,
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ public static WalkthroughPlan ResolveWalkthroughPlan(
List<ResolvedInstallRequest>? 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 })
{
Expand All @@ -41,22 +45,36 @@ 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());

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;

/// <summary>
/// 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -15,8 +16,12 @@ namespace Microsoft.DotNet.Tools.Bootstrapper.Commands.Init;
/// <param name="AccessMode">The recommended access mode.</param>
/// <param name="Migrations">The system installs eligible for migration under the recommended mode.</param>
/// <param name="ChannelDisplay">Display information for the SDK channel line.</param>
/// <param name="ShellProvider">The resolved shell provider used to recommend and describe terminal mode.</param>
/// <param name="InstallRootGlobalJsonPath">The global.json that supplied the install root, if any.</param>
internal sealed record WalkthroughPlan(
DotnetInstallRoot InstallRoot,
DotnetAccessMode AccessMode,
List<MigrationWorkflow.MigrationSelection> Migrations,
DefaultChannelDisplay ChannelDisplay);
DefaultChannelDisplay ChannelDisplay,
IEnvShellProvider? ShellProvider,
string? InstallRootGlobalJsonPath);
52 changes: 52 additions & 0 deletions src/Installer/dotnetup.Library/Commands/Init/WalkthroughSummary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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,
Comment thread
nagilson marked this conversation as resolved.
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()))),
Comment thread
nagilson marked this conversation as resolved.
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)
Expand Down
15 changes: 15 additions & 0 deletions src/Installer/dotnetup.Library/Strings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,21 @@ Or open a new terminal.</value>
<value>current: {0}</value>
<comment>{0} is the user's currently configured mode name. Shown in parentheses after the recommended mode.</comment>
</data>
<data name="SummaryModeConfiguration" xml:space="preserve">
<value>{0} modifies {1} to set {2} and {3} to prefer {4}.</value>
<comment>{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.</comment>
</data>
<data name="SummaryModeSystemEnvironmentVariables" xml:space="preserve">
<value>the system environment variables</value>
</data>
<data name="SummaryModeInstallRootGlobalJsonSuffix" xml:space="preserve">
<value>(inferred from {0})</value>
<comment>{0} is the path to the global.json file that supplied the dotnetup install root.</comment>
</data>
<data name="SummaryModeUnsupportedShell" xml:space="preserve">
<value>{0} is suggested because the current shell ({1}) cannot be detected or is not supported. Supported shells: {2}.</value>
<comment>{0} is the suggested isolation mode name; {1} is the current SHELL value or "(not set)"; {2} is the list of supported shell names.</comment>
</data>
<data name="SummaryMigrateHeader" xml:space="preserve">
<value>System installs to migrate:</value>
</data>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 20 additions & 0 deletions src/Installer/dotnetup.Library/xlf/Strings.cs.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions src/Installer/dotnetup.Library/xlf/Strings.de.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions src/Installer/dotnetup.Library/xlf/Strings.es.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions src/Installer/dotnetup.Library/xlf/Strings.fr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading