Skip to content

Conversation

jjonescz
Copy link
Member

Resolves #50501.

@jjonescz jjonescz added the Area-run-file Items related to the "dotnet run <file>" effort label Aug 28, 2025
@jjonescz jjonescz marked this pull request as ready for review August 28, 2025 17:43
@jjonescz jjonescz requested a review from a team as a code owner August 28, 2025 17:43
@jjonescz jjonescz requested a review from a team August 28, 2025 17:44
private static Option<string[]?> MSBuildMultiOption(string name)
=> new ForwardedOption<string[]?>($"--{name}", $"-{name}", $"/{name}")
{
Hidden = true,
Copy link
Member

Choose a reason for hiding this comment

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

@zivkan all of these getX options are marked hidden here - they won't show in help output as a result.

Copy link
Member

Choose a reason for hiding this comment

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

Oh. But don't all "unknown" parameters get forwarded to MSBuild anyway? What's the benefit of having build, clean, pack, etc all define these hidden options? Why not every option listed in dotnet msbuild -h? What makes these 4 special, other than it's the focus of this PR?

Copy link
Member

Choose a reason for hiding this comment

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

We've been explicitly modeling specific parameters that impact the way MSbuild behaves so that we can detect and mimic that behavior for the file-based apps usage model, which doesn't actually invoke the MSBuild CLI. We also have an issue to model, intercept, and interpret the -bl arg for similar reasons. In general, if the dotnet CLI needs to do some processing of an argument that MSbuild accepts, we need to model, parse, and interpret it based on our needs - which may involve just forwarding it back to MSBuild, but may also mean modifying it in some way, or using it internally, etc.

Copy link
Member

Choose a reason for hiding this comment

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

It also helps us inside the CLI codebase
a) ensure that we keep certain invariants around key MSbuild properties intact - like making sure that --restoreProperty values are always a superset of --property values, or that a Target isn't set to be built twice in a single invocation
b) helps us correctly parse and handle complex interactions around implicit Restore vs explicit, separate restore for TFM and RID-specific SDK scenarios that MSBuild proper has no opinion on
c) makes it easier for us to do parsing-based testing, because we can assert on a model instead of random raw strings
d) ensures that we can enforce correct-by-construction calls to the lower-level MSbuild forwarding commands for the key CLI commands - we force all MSbuild forwarding commands to use the MSBuildArgs struct so that we can encourage centralized parsing and handling of these structures, and the forwarding app just has to map from the structure to a string[] of args to give to the MSbuild process
e) more reasons that I'm forgetting

in short, it's been a huge boon for the CLI codebase's handling of MSbuild semantics

var verbosity = MSBuildArgs.Verbosity ?? VerbosityOptions.quiet;
var consoleLogger = TerminalLogger.CreateTerminalOrConsoleLogger([$"--verbosity:{verbosity}", .. MSBuildArgs.OtherMSBuildArgs]);
var consoleLogger = minimizeStdOut
? new SimpleErrorLogger()
Copy link
Member

Choose a reason for hiding this comment

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

the rest of this looks good, but I don't actually know what the behavior of the SimpleErrorLogger is. What does this look like in the case of errors?

Copy link
Member Author

@jjonescz jjonescz Aug 29, 2025

Choose a reason for hiding this comment

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

It writes each error on a single line something like this:
image

It's the exact same logger MSBuild uses in this situation btw

Copy link
Member

@baronfel baronfel left a comment

Choose a reason for hiding this comment

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

Approved pending one question about the error behavior with the simple logger

@jjonescz
Copy link
Member Author

jjonescz commented Sep 3, 2025

@RikkiGibson @333fred for reviews, thanks

{
Log.WriteLine($"File '{file}':");
Log.WriteLine(text);
File.Delete(Path.Join(testInstance.Path, file));
Copy link
Member

Choose a reason for hiding this comment

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

Is this delete needed to clean up the test? Containing directory is not being deleted?

Copy link
Member Author

@jjonescz jjonescz Sep 8, 2025

Choose a reason for hiding this comment

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

This is used twice during the test, so the containing directory is kept (and so is the Program.cs file). Only the intermediate files that might be generated by -getResultOutputFile are deleted so we verify they are equivalently emitted again (to check equivalence between file-based and project-based programs).

@jjonescz jjonescz merged commit 5832911 into dotnet:release/10.0.1xx Sep 9, 2025
27 checks passed
@jjonescz jjonescz deleted the sprint-msbuild-get branch September 9, 2025 08:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-run-file Items related to the "dotnet run <file>" effort
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants