Skip to content

Conversation

@nagilson
Copy link
Member

@nagilson nagilson commented Oct 24, 2025

This PR will remediate the issues discussed in #50988 to fix the prototype dnup code. It's not a complete review of all of that code, however. I have not reviewed the portion of the CLI and PATH manipulation, though that's not directly part of the library, so I think that will come later.

Splits up `ReleaseManifest` into 3 pieces:
- A. Downloading of .NET Archives
- B. Accessing the release manifest & release manifest data structures
- C. Parsing a 'channel' into a ReleaseVersion

This is a better separation of responsibility and makes each class a far more reasonable size.
What we were doing was setting the AppContext data such that the HOSTFXR_PATH pointed to the installed root location. We don't need to do that, the hostfxr interop(ped) API already points to the dotnet root location within which we want to resolve the hostfxr.
verification should happen in the downloader which will probably be deferred to the release deployment library
@nagilson nagilson changed the base branch from dnup to release/dnup October 28, 2025 22:19
Copy link
Member

@dsplaisted dsplaisted left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good improvements.

Main issue is that calls into hostfxr no longer work from a NativeAOT app.


private IEnumerable<Product> GetProductsInMajorOrMajorMinor(IEnumerable<Product> index, int major, int? minor = null)
{
var validProducts = index.Where(p => p.ProductVersion.StartsWith(minor is not null ? $"{major}.{minor}" : $"{major}."));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we do this by checking a version object instead of checking if the string starts with something? I think we'll need to parse the version first but that would seem better to me.

Comment on lines +164 to +165
/// <param name="isLts">True for LTS (Long-Term Support), false for STS (Standard-Term Support)</param>
/// <param name="mode">InstallComponent.SDK or InstallComponent.Runtime</param>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like these doc comments are out of date.

/// <summary>
/// Handles downloading and parsing .NET release manifests to find the correct installer/archive for a given installation.
/// </summary>
internal class DotnetArchiveDownloader(HttpClient httpClient) : IDisposable
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need the constructor that specifies an HttpClient? It doesn't look like we use that outside of the class, and there's no way to specify both an httpClient and a ReleaseManifest.

};

// Set user-agent to identify dnup in telemetry
client.DefaultRequestHeaders.UserAgent.ParseAdd("dnup-dotnet-installer");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be customizable via the library? We might want to differentiate between requests from dotnetup and the Aspire CLI for example.

Directory.CreateDirectory(Path.GetDirectoryName(destinationPath)!);

// Try to get content length for progress reporting
long? totalBytes = await GetContentLengthAsync(downloadUrl);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this adds an extra HTTP request. Is there a reason to do this separately rather than get the value from the header of the request which actually downloads?

Comment on lines +63 to +65
var args = DnupTestUtilities.BuildArguments(channel, testEnv.InstallPath, testEnv.ManifestPath);
(int exitCode, string output) = DnupTestUtilities.RunDnupProcess(args, captureOutput: true, workingDirectory: testEnv.TempRoot);
exitCode.Should().Be(0, $"dnup exited with code {exitCode}. Output:\n{output}");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: indentation seems wrong here.

Comment on lines +124 to +125
(int exitCode, string firstInstallOutput) = DnupTestUtilities.RunDnupProcess(args, captureOutput: true, workingDirectory: testEnv.TempRoot);
exitCode.Should().Be(0, $"First installation failed with exit code {exitCode}. Output:\n{firstInstallOutput}");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: indentation

Comment on lines +139 to +140
(exitCode, string output) = DnupTestUtilities.RunDnupProcess(args, captureOutput: true, workingDirectory: testEnv.TempRoot);
exitCode.Should().Be(0, $"Second installation failed with exit code {exitCode}. Output:\n{output}");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation.

Comment on lines +91 to +93
using var process = new Process();
string repoDotnet = Path.Combine(repoRoot, ".dotnet", DnupUtilities.GetDotnetExeName());
process.StartInfo.FileName = File.Exists(repoDotnet) ? repoDotnet : DnupUtilities.GetDotnetExeName();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: indentation

process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = captureOutput;
process.StartInfo.RedirectStandardError = captureOutput;
process.StartInfo.WorkingDirectory = workingDirectory ?? Environment.CurrentDirectory;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: indentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants