Skip to content

Conversation

@MichalPavlik
Copy link
Member

Context

In some cases dotnet needs to process MSBuild cmdline switches including response files.

Changes Made

The parsing logic was pulled out from XMake to isolate it in the internal type, making it easily reusable in the .NET SDK project.

Testing

All existing tests are passing.

Notes

The goal of this PR isn’t to refactor the entire API—that’s something we can consider tackling later on.

Copilot AI review requested due to automatic review settings October 29, 2025 13:34
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot reviewed 6 out of 8 changed files in this pull request and generated 9 comments.

try
{
GatherAllSwitches(commandLine, out var switchesFromAutoResponseFile, out var switchesNotFromAutoResponseFile, out string fullCommandLine);
CommandLineParser.GatherAllSwitches(commandLine, out var switchesFromAutoResponseFile, out var switchesNotFromAutoResponseFile, out string fullCommandLine, out s_exeName);
Copy link

Copilot AI Oct 29, 2025

Choose a reason for hiding this comment

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

The new signature of GatherAllSwitches outputs exeName as the 5th parameter, but this is directly assigned to the static field s_exeName. This creates an implicit side effect where the method both returns data and modifies static state. Consider having the method return exeName as part of a result tuple or record, and let the caller assign it to s_exeName. This would make the method more testable and its behavior more explicit.

Suggested change
CommandLineParser.GatherAllSwitches(commandLine, out var switchesFromAutoResponseFile, out var switchesNotFromAutoResponseFile, out string fullCommandLine, out s_exeName);
CommandLineParser.GatherAllSwitches(commandLine, out var switchesFromAutoResponseFile, out var switchesNotFromAutoResponseFile, out string fullCommandLine, out string exeName);
s_exeName = exeName;

Copilot uses AI. Check for mistakes.
Copy link
Member Author

Choose a reason for hiding this comment

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

@rainersigwald, I kept the change minimal—s_exeName is only used once, and that’s when diagnostic verbosity is enabled and ConsoleLogger is active. I could either store the value in the parser or find another way to retrieve it without parsing the command line.

Copy link
Member

Choose a reason for hiding this comment

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

Anything new in this file, or all clean moves?

Copy link
Member Author

@MichalPavlik MichalPavlik Oct 31, 2025

Choose a reason for hiding this comment

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

Clean moves except assigning the s_exeName and getting the s_exePath value (I added a comment that the line was copied). IIRC, 3 lines of code were changed slightly.

Copy link
Member

Choose a reason for hiding this comment

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

I have concerns about the usage of static members here - MSBuild is often hosted in other environments that are not one-shot in the way that MSBuild.exe is, and if they use this API repeatedly (e.g. for preparing multiple separate builds over time), they will mutate that state.

Copy link
Member Author

Choose a reason for hiding this comment

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

The main method here is GatherAllSwitches, which resets the state. I get your concern since all internal methods are exposed, so I’ve made the parser instantiable.

Copy link
Member Author

Choose a reason for hiding this comment

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

I also removed usingSwitchesFromAutoResponseFile as this field wasn't used anywhere.

The `usingSwitchesFromAutoResponseFile` field has been removed from the `CommandLineParser` class, along with the associated logic that set its value. This includes the removal of the check for `switchesFromAutoResponseFile.HaveAnySwitchesBeenSet()` and the assignment to this field.

The `ResetGatheringSwitchesState` method has been updated to no longer reset this field, as it is no longer needed. These changes simplify the class by eliminating redundant state management related to auto-response file switches, improving maintainability.
/// <param name="switchesNotFromAutoResponseFile"></param>
/// <param name="fullCommandLine"></param>
/// <returns>Combined bag of switches.</returns>
internal void GatherAllSwitches(
Copy link
Member

Choose a reason for hiding this comment

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

The dotnet CLI callers of this aren't going to have a string, they have string[] - it would be ideal if this API exposed only arrays of args so that we didn't have to keep converting back and forth. That may bring too much churn though.

Copy link
Member Author

Choose a reason for hiding this comment

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

I’ve added a new Parse method that should be a bit more user-friendly 🙂. The parsing logic could definitely use a proper overhaul, but for now this is a quick and temporary fix.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks!

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.

Thanks for doing this :)

/// <param name="switchesNotFromAutoResponseFile"></param>
/// <param name="fullCommandLine"></param>
/// <returns>Combined bag of switches.</returns>
internal void GatherAllSwitches(
Copy link
Member

Choose a reason for hiding this comment

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

Thanks!

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.

4 participants