Make template discovery async in aspire new command#14870
Make template discovery async in aspire new command#14870mitchdenny merged 2 commits intorelease/13.2from
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 14870Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 14870" |
There was a problem hiding this comment.
Pull request overview
This PR updates the aspire new command so template discovery happens asynchronously at execution time (instead of synchronously during CLI construction), avoiding startup-time blocking and .NET SDK checks when aspire new isn’t invoked.
Changes:
- Replaces template subcommands with a
template-namepositional argument and loads templates inNewCommand.ExecuteAsync. - Consolidates shared template-related options into
TemplateOptionsand registers them onNewCommand. - Removes the now-unneeded
TemplateCommandtype and updates tests/resources for the new CLI shape.
Reviewed changes
Copilot reviewed 21 out of 22 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Aspire.Cli.Tests/Commands/SdkInstallerTests.cs | Updates expectations/comments to reflect template-name argument behavior. |
| tests/Aspire.Cli.Tests/Commands/NewCommandTests.cs | Updates tests to assert no subcommands and presence of template-name argument. |
| src/Aspire.Cli/Templating/TemplateOptions.cs | Introduces shared Option definitions for template-specific flags/options. |
| src/Aspire.Cli/Templating/DotNetTemplateFactory.cs | Switches to shared options from TemplateOptions. |
| src/Aspire.Cli/Templating/CliTemplateFactory.cs | Switches to shared options from TemplateOptions. |
| src/Aspire.Cli/Resources/xlf/NewCommandStrings.*.xlf | Adds localized resource entry for the new template-name argument description. |
| src/Aspire.Cli/Resources/NewCommandStrings.resx | Adds TemplateNameArgumentDescription string resource. |
| src/Aspire.Cli/Resources/NewCommandStrings.Designer.cs | Adds strongly-typed accessor for TemplateNameArgumentDescription. |
| src/Aspire.Cli/Commands/TemplateCommand.cs | Removes template-subcommand implementation. |
| src/Aspire.Cli/Commands/NewCommand.cs | Moves template discovery to async execution; adds template-name argument and shared options. |
Files not reviewed (1)
- src/Aspire.Cli/Resources/NewCommandStrings.Designer.cs: Language not supported
Separate template definition (sync) from template availability (async) so that NewCommand can register template subcommands without blocking on async I/O in the constructor. - Add sync GetTemplates() to ITemplateFactory/ITemplateProvider that returns template definitions without performing runtime checks - Keep GetTemplatesAsync() for execution-time availability filtering (e.g. .NET SDK availability check) - NewCommand constructor uses GetTemplates() for subcommand registration - NewCommand.ExecuteAsync uses GetTemplatesAsync() to resolve which templates are actually available at runtime - Template subcommands and per-template help output are preserved Fixes #14805 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
b5f52d9 to
92223da
Compare
🎬 CLI E2E Test RecordingsThe following terminal recordings are available for commit
📹 Recordings uploaded automatically from CI run #22653991422 |
|
@davidfowl This is one area where |
| Description = TemplatingStrings.EnterXUnitVersion_Description | ||
| }; | ||
|
|
||
| public IEnumerable<ITemplate> GetTemplates() |
There was a problem hiding this comment.
These template show up as subcommands even when they are not applicable?
There was a problem hiding this comment.
Fixed in 2177294 — GetTemplates() now checks IsDotNetOnPath() first. If dotnet isn't found on the system PATH or in the private SDK installation, it returns empty and the .NET templates won't be registered as subcommands.
PR Testing ResultsI tested this PR build ( What works well
Concern: all templates registered as subcommands even when unavailableThe core tradeoff of this PR is that A user could see |
Add IsDotNetOnPath() sync check to DotNetTemplateFactory.GetTemplates() so .NET templates are only registered as subcommands when dotnet is found on PATH or via the private SDK installation. This addresses the UX concern where 'aspire new --help' advertised .NET templates even on systems without the .NET SDK installed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Updated in 2177294 — Tested locally on Linux:
The full async SDK version check in |
* Make template discovery async in aspire new command Separate template definition (sync) from template availability (async) so that NewCommand can register template subcommands without blocking on async I/O in the constructor. - Add sync GetTemplates() to ITemplateFactory/ITemplateProvider that returns template definitions without performing runtime checks - Keep GetTemplatesAsync() for execution-time availability filtering (e.g. .NET SDK availability check) - NewCommand constructor uses GetTemplates() for subcommand registration - NewCommand.ExecuteAsync uses GetTemplatesAsync() to resolve which templates are actually available at runtime - Template subcommands and per-template help output are preserved Fixes #14805 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Filter .NET templates from subcommands when dotnet is not available Add IsDotNetOnPath() sync check to DotNetTemplateFactory.GetTemplates() so .NET templates are only registered as subcommands when dotnet is found on PATH or via the private SDK installation. This addresses the UX concern where 'aspire new --help' advertised .NET templates even on systems without the .NET SDK installed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Mitch Denny <mitch@mitchdeny.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Description
Make template discovery in
aspire newasynchronous instead of blocking at CLI startup.Problem:
NewCommand's constructor calledtemplateProvider.GetTemplatesAsync(CancellationToken.None).GetAwaiter().GetResult()which synchronously blocked on async template discovery (including a .NET SDK availability check) every time the command was instantiated.Solution: Separate template definition (sync) from template availability (async):
GetTemplates()method toITemplateFactory/ITemplateProviderthat returns template definitions without performing any I/O or async workNewCommandconstructor usesGetTemplates()for subcommand registration — no blockingNewCommand.ExecuteAsyncuses the existingGetTemplatesAsync()to resolve which templates are actually available at runtime (e.g. .NET SDK check)Validation: All 1,395 Aspire.Cli.Tests pass (0 failures, 2 skipped).
Fixes #14805
Checklist