Skip to content
Draft
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 @@ -23,15 +23,10 @@ internal class ChannelVersionResolver
/// </summary>
public const string LtsChannel = "lts";

/// <summary>
/// Channel keyword for the latest Standard Term Support (STS) release.
/// </summary>
public const string StsChannel = "sts";

/// <summary>
/// Known channel keywords that are always valid.
/// </summary>
public static readonly IReadOnlyList<string> KnownChannelKeywords = [LatestChannel, PreviewChannel, LtsChannel, StsChannel];
public static readonly IReadOnlyList<string> KnownChannelKeywords = [LatestChannel, PreviewChannel, LtsChannel];

/// <summary>
/// Maximum reasonable major version number. .NET versions are currently single-digit;
Expand Down Expand Up @@ -204,16 +199,15 @@ private static (int Major, int Minor, string? FeatureBand, bool IsFullySpecified
/// <summary>
/// Finds the latest fully specified version for a given channel string (major, major.minor, or feature band).
/// </summary>
/// <param name="channel">Channel string (e.g., "9", "9.0", "9.0.1xx", "9.0.103", "lts", "sts", "preview")</param>
/// <param name="channel">Channel string (e.g., "9", "9.0", "9.0.1xx", "9.0.103", "lts", "preview")</param>
/// <param name="component">The component to check (ie SDK or runtime)</param>
/// <returns>Latest fully specified version string, or null if not found</returns>
public ReleaseVersion? GetLatestVersionForChannel(UpdateChannel channel, InstallComponent component)
{
if (string.Equals(channel.Name, LtsChannel, StringComparison.OrdinalIgnoreCase) || string.Equals(channel.Name, StsChannel, StringComparison.OrdinalIgnoreCase))
if (string.Equals(channel.Name, LtsChannel, StringComparison.OrdinalIgnoreCase))
{
var releaseType = string.Equals(channel.Name, LtsChannel, StringComparison.OrdinalIgnoreCase) ? ReleaseType.LTS : ReleaseType.STS;
var productIndex = _releaseManifest.GetReleasesIndex();
return GetLatestVersionByReleaseType(productIndex, releaseType, component);
return GetLatestVersionByReleaseType(productIndex, ReleaseType.LTS, component);
}
else if (string.Equals(channel.Name, PreviewChannel, StringComparison.OrdinalIgnoreCase))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public bool IsSdkVersionOrFeatureBand()

/// <summary>
/// Checks if the given version matches this channel pattern.
/// Supports exact versions, named channels (latest, lts, sts, preview),
/// Supports exact versions, named channels (latest, lts, preview),
/// major-only, major.minor, and feature band patterns.
/// </summary>
public bool Matches(ReleaseVersion version)
Expand All @@ -84,11 +84,7 @@ public bool Matches(ReleaseVersion version)

// These channels match any version. The "preview" channel may resolve to a stable version
// when no preview exists yet (e.g., after a major release before the next preview).
// The "sts" channel includes both STS and LTS releases, since users on this channel want
// newer versions quickly regardless of support lifecycle. GC still keeps only the latest
// version per channel, so broad matching here doesn't prevent cleanup.
if (Name.Equals("latest", StringComparison.OrdinalIgnoreCase) ||
Name.Equals("sts", StringComparison.OrdinalIgnoreCase) ||
Name.Equals("preview", StringComparison.OrdinalIgnoreCase))
{
return true;
Expand Down
18 changes: 0 additions & 18 deletions src/Installer/dotnetup/Commands/Shared/InstallWalkthrough.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,16 @@ namespace Microsoft.DotNet.Tools.Bootstrapper.Commands.Shared;
internal class InstallWalkthrough
{
private readonly IDotnetInstallManager _dotnetInstaller;
private readonly ChannelVersionResolver _channelVersionResolver;
private readonly InstallWorkflow.InstallWorkflowOptions _options;
#pragma warning disable IDE0032 // Lazy-init via ??=; not convertible to auto-property
private InstallRootManager? _installRootManager;
#pragma warning restore IDE0032

public InstallWalkthrough(
IDotnetInstallManager dotnetInstaller,
ChannelVersionResolver channelVersionResolver,
InstallWorkflow.InstallWorkflowOptions options)
{
_dotnetInstaller = dotnetInstaller;
_channelVersionResolver = channelVersionResolver;
_options = options;
}

Expand Down Expand Up @@ -104,21 +101,6 @@ public string ResolveChannel(
return channelFromGlobalJson;
}

if (_options.Interactive)
{
// Feature bands (like 9.0.1xx) are SDK-specific, don't show them for runtimes
bool includeFeatureBands = _options.Component == InstallComponent.SDK;
SpectreAnsiConsole.WriteLine("Available supported channels: " + string.Join(' ', _channelVersionResolver.GetSupportedChannels(includeFeatureBands)));

// Use appropriate version example for SDK vs Runtime
string versionExample = _options.Component == InstallComponent.SDK ? "9.0.304" : "9.0.12";
SpectreAnsiConsole.WriteLine($"You can also specify a specific version (for example {versionExample}).");

return SpectreAnsiConsole.Prompt(
new TextPrompt<string>($"Which channel of the {_options.ComponentDescription} do you want to install?")
.DefaultValue(defaultChannel));
}

return defaultChannel;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public void Execute(InstallWorkflowOptions options)

private WorkflowContext? ResolveWorkflowContext(InstallWorkflowOptions options, out string? error)
{
var walkthrough = new InstallWalkthrough(_dotnetInstaller, _channelVersionResolver, options);
var walkthrough = new InstallWalkthrough(_dotnetInstaller, options);
var globalJson = _dotnetInstaller.GetGlobalJsonInfo(Environment.CurrentDirectory);
var currentInstallRoot = _dotnetInstaller.GetConfiguredInstallType();

Expand Down
5 changes: 2 additions & 3 deletions src/Installer/dotnetup/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,8 @@ private static RootCommand ConfigureCommandLine(RootCommand rootCommand)

rootCommand.SetAction(parseResult =>
{
// No subcommand - show help
parseResult.InvocationConfiguration.Output.WriteLine(Strings.RootCommandDescription);
return 0;
// No subcommand specified - default to sdk install
return new SdkInstallCommand(parseResult).Execute();
});

return rootCommand;
Expand Down
25 changes: 10 additions & 15 deletions test/dotnetup.Tests/ChannelVersionResolverTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,13 @@ public void GetLatestVersionForChannel_LTS_ReturnsLatestLTSVersion()
}

[Fact]
public void GetLatestVersionForChannel_STS_ReturnsLatestSTSVersion()
public void GetLatestVersionForChannel_STS_IsNoLongerSupported()
{
var manifest = new ChannelVersionResolver();
var version = manifest.GetLatestVersionForChannel(new UpdateChannel("sts"), InstallComponent.SDK);

Log.WriteLine($"STS Version found: {version}");

// Check that we got a version
Assert.NotNull(version);

// STS versions should have odd major versions (e.g., 7.0, 9.0, 11.0)
Assert.True(version.Major % 2 != 0, $"STS version {version} should have an odd major version");

// Should not be a preview version
Assert.Null(version.Prerelease);
// "sts" channel has been removed - it should not resolve to a version
var version = manifest.GetLatestVersionForChannel(new UpdateChannel("sts"), InstallComponent.SDK);
Assert.Null(version);
}

[Fact(Skip = "No preview releases may be available after GA of a major release and before preview 1 of the next")]
Expand Down Expand Up @@ -106,7 +98,6 @@ public void GetLatestVersionForChannel_Preview_ReturnsLatestPreviewVersion()
[InlineData("latest", true)]
[InlineData("preview", true)]
[InlineData("lts", true)]
[InlineData("sts", true)]
[InlineData("LTS", true)] // Case insensitive
[InlineData("9", true)]
[InlineData("9.0", true)]
Expand Down Expand Up @@ -146,9 +137,11 @@ public void GetSupportedChannels_WithFeatureBands_IncludesFeatureBandChannels()
// Should include named channels
Assert.Contains("latest", channels);
Assert.Contains("lts", channels);
Assert.Contains("sts", channels);
Assert.Contains("preview", channels);

// "sts" channel has been removed
Assert.DoesNotContain("sts", channels);

// Should include product versions like "10.0"
Assert.Contains(channels, c => c.EndsWith(".0") && !c.Contains("xx"));

Expand All @@ -165,9 +158,11 @@ public void GetSupportedChannels_WithoutFeatureBands_ExcludesFeatureBandChannels
// Should include named channels
Assert.Contains("latest", channels);
Assert.Contains("lts", channels);
Assert.Contains("sts", channels);
Assert.Contains("preview", channels);

// "sts" channel has been removed
Assert.DoesNotContain("sts", channels);

// Should include product versions like "10.0"
Assert.Contains(channels, c => c.EndsWith(".0") && !c.Contains("xx"));

Expand Down
1 change: 0 additions & 1 deletion test/dotnetup.Tests/DnupE2Etest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ public class InstallEndToEndTests
new object[] { "9.0.1xx" },
new object[] { "latest" },
new object[] { "preview" },
new object[] { "sts" },
new object[] { "lts" },
};

Expand Down
4 changes: 2 additions & 2 deletions test/dotnetup.Tests/LibraryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ public LibraryTests(ITestOutputHelper log)
[Theory]
[InlineData("9", InstallComponent.SDK)]
[InlineData("latest", InstallComponent.SDK)]
[InlineData("sts", InstallComponent.SDK)]
[InlineData("lts", InstallComponent.SDK)]
[InlineData("preview", InstallComponent.SDK)]
[InlineData("9", InstallComponent.Runtime)]
Expand Down Expand Up @@ -58,7 +57,8 @@ public void TestGetSupportedChannels()
var releaseInfoProvider = InstallerFactory.CreateReleaseInfoProvider();
var channels = releaseInfoProvider.GetSupportedChannels();

channels.Should().Contain(new[] { "latest", "lts", "sts", "preview" });
channels.Should().Contain(new[] { "latest", "lts", "preview" });
channels.Should().NotContain("sts");

// This will need to be updated every few years as versions go out of support
channels.Should().Contain(new[] { "10.0", "10.0.1xx" });
Expand Down
1 change: 0 additions & 1 deletion test/dotnetup.Tests/TelemetryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ public class VersionSanitizerTelemetryTests
[InlineData("latest", "latest")]
[InlineData("preview", "preview")]
[InlineData("lts", "lts")]
[InlineData("sts", "sts")]
public void Sanitize_ValidVersions_PassThrough(string input, string expected)
{
var result = VersionSanitizer.Sanitize(input);
Expand Down
1 change: 0 additions & 1 deletion test/dotnetup.Tests/Utilities/UpdateChannelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ public static bool IsFullySpecifiedVersion(this UpdateChannel channel)

// Special channels are not fully specified versions
if (string.Equals(channel.Name, "lts", StringComparison.OrdinalIgnoreCase) ||
string.Equals(channel.Name, "sts", StringComparison.OrdinalIgnoreCase) ||
string.Equals(channel.Name, "preview", StringComparison.OrdinalIgnoreCase) ||
string.Equals(channel.Name, "latest", StringComparison.OrdinalIgnoreCase))
{
Expand Down
2 changes: 0 additions & 2 deletions test/dotnetup.Tests/VersionSanitizerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ public class VersionSanitizerTests
[InlineData("LATEST", "latest")]
[InlineData("lts", "lts")]
[InlineData("LTS", "lts")]
[InlineData("sts", "sts")]
[InlineData("STS", "sts")]
[InlineData("preview", "preview")]
[InlineData("PREVIEW", "preview")]
public void Sanitize_ChannelKeywords_ReturnsLowercase(string input, string expected)
Expand Down
Loading