-
Notifications
You must be signed in to change notification settings - Fork 1.2k
[dotnet-cli] prompt for target framework using Spectre.Console
#51509
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Implements the first part of the spec mentioned in: https://github.com/dotnet/sdk/blob/522c88a6abfc4a011556f839d15844d07ba62cd9/documentation/specs/dotnet-run-for-maui.md?plain=1#L35-L46 Add interactive target framework selection to `dotnet run` When running a multi-targeted project without specifying `--framework`, `dotnet run` now: * Prompts interactively (using `Spectre.Console`) to select a framework with arrow keys * Shows a formatted error list in non-interactive mode with available frameworks * Handles selection early before project build/evaluation * Removes redundant multi-TFM error checking from `ThrowUnableToRunError()` * Adds a few unit tests to validate these changes. This is currently WIP, as it introduces a "pre-built" `Spectre.Console` that I will need to setup in source-build in a PRs elsewhere.
So it doesn't require `mono`
There are other tests that do this
This test fails after I made it check TF at runtime. This was not even the existing behavior, I think we can remove this test.
|
/azp run sdk-unified-build |
|
Azure Pipelines could not run because the pipeline triggers exclude this branch/path. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds interactive target framework selection to the dotnet run command for multi-targeted projects. When a multi-targeted project is run without specifying a framework, the command now prompts the user to select one in interactive mode, or displays a helpful error message with available frameworks in non-interactive mode.
- Introduces
TargetFrameworkSelectorclass to handle framework selection logic - Adds Spectre.Console package for interactive prompting
- Updates error handling to show available frameworks and example commands
- Includes comprehensive integration tests for framework selection scenarios
Reviewed Changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| test/dotnet.Tests/CommandTests/Run/GivenDotnetRunSelectsTargetFramework.cs | Adds comprehensive integration tests for target framework selection behavior |
| test/TestAssets/TestProjects/DotnetRunMultiTarget/Program.cs | Test project that outputs target framework information |
| test/TestAssets/TestProjects/DotnetRunMultiTarget/DotnetRunMultiTarget.csproj | Multi-targeted test project configuration |
| src/Cli/dotnet/dotnet.csproj | Adds Spectre.Console package reference |
| src/Cli/dotnet/Commands/xlf/*.xlf | Adds localization entries for new UI strings (state=new) |
| src/Cli/dotnet/Commands/Run/TargetFrameworkSelector.cs | New class implementing framework selection logic |
| src/Cli/dotnet/Commands/Run/RunCommand.cs | Integrates framework selection into run command execution flow |
| src/Cli/dotnet/Commands/CliCommandStrings.resx | Adds new localizable strings for framework selection UI |
| Directory.Packages.props | Adds Spectre.Console version 0.52.0 |
| using var collection = new ProjectCollection(globalProperties: globalProperties); | ||
| project = collection.LoadProject(projectFilePath); |
Copilot
AI
Oct 31, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ProjectCollection is disposed immediately after loading the project, but the project variable is used outside the using block (line 49). This could lead to issues since the project is part of the collection that's being disposed. Consider moving the property value retrieval inside the using block or restructuring to avoid using the project after its collection is disposed.
Co-authored-by: Copilot <[email protected]>
|
/azp run sdk-unified-build |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
Please also add Spectre.Console here: Lines 60 to 67 in 6a6992f
|
|
/azp run sdk-unified-build |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
@premun @dkurepa do you know what might be going on here? Build |
|
@NikolaMilosavljevic same as here: dotnet/source-build-reference-packages#1447 (comment) You will have to pin darc for the time being (either in |
|
/azp run sdk-unified-build |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run sdk-unified-build |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run sdk-unified-build |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
Since I created a branch here (and then also sent to internal): And triggered a build here: It's ongoing, but if all the source-build legs look ok, this seems safe to merge. |
|
Most of the build is green, except for a couple legs had the error: Somehow, I downgraded this in my manual test, trying again: |
|
WHOOO! One small step for the CLI.... |
|
@jonathanpeppers / @NikolaMilosavljevic if we wanted this in 10.0.2xx, are there source-build/VMR considerations that would block that? |
|
I was going to ask how that worked -- if we can add Spectre.Console to 10.0.2xx. |
|
Chatted with @MichaelSimons at standup today and he confirmed that there are no negative source-build implications from backporting. Lets's see if it applies via bot... /backport to release/10.0.2xx |
|
/backport to release/10.0.2xx |
|
Started backporting to |
|
@baronfel backporting to git am output$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patch
Applying: [dotnet-cli] prompt for target framework using `Spectre.Console`
.git/rebase-apply/patch:105: trailing whitespace.
.git/rebase-apply/patch:219: trailing whitespace.
.git/rebase-apply/patch:224: trailing whitespace.
.git/rebase-apply/patch:244: trailing whitespace.
.git/rebase-apply/patch:1008: trailing whitespace.
warning: squelched 6 whitespace errors
warning: 11 lines add whitespace errors.
Using index info to reconstruct a base tree...
M Directory.Packages.props
M src/Cli/dotnet/Commands/CliCommandStrings.resx
M src/Cli/dotnet/Commands/Run/RunCommand.cs
M src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf
M src/Cli/dotnet/Commands/xlf/CliCommandStrings.de.xlf
M src/Cli/dotnet/Commands/xlf/CliCommandStrings.es.xlf
M src/Cli/dotnet/Commands/xlf/CliCommandStrings.fr.xlf
M src/Cli/dotnet/Commands/xlf/CliCommandStrings.it.xlf
M src/Cli/dotnet/Commands/xlf/CliCommandStrings.ja.xlf
M src/Cli/dotnet/Commands/xlf/CliCommandStrings.ko.xlf
M src/Cli/dotnet/Commands/xlf/CliCommandStrings.pl.xlf
M src/Cli/dotnet/Commands/xlf/CliCommandStrings.pt-BR.xlf
M src/Cli/dotnet/Commands/xlf/CliCommandStrings.ru.xlf
M src/Cli/dotnet/Commands/xlf/CliCommandStrings.tr.xlf
M src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hans.xlf
M src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hant.xlf
M src/Cli/dotnet/dotnet.csproj
Falling back to patching base and 3-way merge...
Auto-merging Directory.Packages.props
Auto-merging src/Cli/dotnet/Commands/CliCommandStrings.resx
Auto-merging src/Cli/dotnet/Commands/Run/RunCommand.cs
Auto-merging src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf
Auto-merging src/Cli/dotnet/Commands/xlf/CliCommandStrings.de.xlf
Auto-merging src/Cli/dotnet/Commands/xlf/CliCommandStrings.es.xlf
Auto-merging src/Cli/dotnet/Commands/xlf/CliCommandStrings.fr.xlf
Auto-merging src/Cli/dotnet/Commands/xlf/CliCommandStrings.it.xlf
Auto-merging src/Cli/dotnet/Commands/xlf/CliCommandStrings.ja.xlf
Auto-merging src/Cli/dotnet/Commands/xlf/CliCommandStrings.ko.xlf
Auto-merging src/Cli/dotnet/Commands/xlf/CliCommandStrings.pl.xlf
Auto-merging src/Cli/dotnet/Commands/xlf/CliCommandStrings.pt-BR.xlf
Auto-merging src/Cli/dotnet/Commands/xlf/CliCommandStrings.ru.xlf
Auto-merging src/Cli/dotnet/Commands/xlf/CliCommandStrings.tr.xlf
Auto-merging src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hans.xlf
Auto-merging src/Cli/dotnet/Commands/xlf/CliCommandStrings.zh-Hant.xlf
Auto-merging src/Cli/dotnet/dotnet.csproj
Applying: Fix for `.sln` file passed in
Applying: Use `Interactive` property
Applying: Update GivenDotnetRunSelectsTargetFramework.cs
Applying: Remove duplicative tests
Applying: Better assertion
Applying: Skip previous TFMs on arm64, x64 passes on these
Applying: Remove ItPrefersExplicitFrameworkOptionOverProperty
Applying: Update src/Cli/dotnet/Commands/Run/RunCommand.cs
Applying: Sign `Spectre.Console.dll`
Applying: small tweaks to enable running against singular-valued targetframeworks lists
error: sha1 information is lacking or useless (src/Cli/dotnet/Commands/Run/RunCommand.cs).
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Patch failed at 0011 small tweaks to enable running against singular-valued targetframeworks lists
Error: The process '/usr/bin/git' failed with exit code 128 |
|
@jonathanpeppers the bot couldn't do the backport - mind taking a stab at it? |

Implements the first part of the spec mentioned in:
sdk/documentation/specs/dotnet-run-for-maui.md
Lines 35 to 46 in 522c88a
Add interactive target framework selection to
dotnet runWhen running a multi-targeted project without specifying
--framework,dotnet runnow:Prompts interactively (using
Spectre.Console) to select a framework with arrow keysShows a formatted error list in non-interactive mode with available frameworks
Handles selection early before project build/evaluation
Removes redundant multi-TFM error checking from
ThrowUnableToRunError()Adds a few unit tests to validate these changes.
This is currently WIP, as it introduces a "pre-built"
Spectre.Consolethat I will need to setup in source-build in a PRs elsewhere.