diff --git a/src/Aspire.Cli/Commands/AddCommand.cs b/src/Aspire.Cli/Commands/AddCommand.cs index ef7bb20a7bb..cd8bac92719 100644 --- a/src/Aspire.Cli/Commands/AddCommand.cs +++ b/src/Aspire.Cli/Commands/AddCommand.cs @@ -212,10 +212,12 @@ await Parallel.ForEachAsync(channels, cancellationToken, async (channel, ct) => // which prevents 'dotnet add package' from modifying the project. if (_features.IsFeatureEnabled(KnownFeatures.RunningInstanceDetectionEnabled, defaultValue: true)) { - var runningInstanceResult = await project.FindAndStopRunningInstanceAsync( - effectiveAppHostProjectFile, - ExecutionContext.HomeDirectory, - cancellationToken); + var runningInstanceResult = await InteractionService.ShowStatusAsync( + AddCommandStrings.CheckingForRunningInstances, + async () => await project.FindAndStopRunningInstanceAsync( + effectiveAppHostProjectFile, + ExecutionContext.HomeDirectory, + cancellationToken)); if (runningInstanceResult == RunningInstanceResult.InstanceStopped) { diff --git a/src/Aspire.Cli/Commands/InitCommand.cs b/src/Aspire.Cli/Commands/InitCommand.cs index 709ea77aca5..614b7fb7653 100644 --- a/src/Aspire.Cli/Commands/InitCommand.cs +++ b/src/Aspire.Cli/Commands/InitCommand.cs @@ -678,7 +678,9 @@ private static bool IsSupportedTfm(string tfm) private async Task<(NuGetPackage Package, PackageChannel Channel)> GetProjectTemplatesVersionAsync(ParseResult parseResult, CancellationToken cancellationToken) { - var allChannels = await _packagingService.GetChannelsAsync(cancellationToken); + var allChannels = await InteractionService.ShowStatusAsync( + InitCommandStrings.ResolvingTemplateVersion, + async () => await _packagingService.GetChannelsAsync(cancellationToken)); // Check if --channel option was provided (highest priority) var channelName = parseResult.GetValue(_channelOption); diff --git a/src/Aspire.Cli/Commands/NewCommand.cs b/src/Aspire.Cli/Commands/NewCommand.cs index e7296794ed2..39a3c392be0 100644 --- a/src/Aspire.Cli/Commands/NewCommand.cs +++ b/src/Aspire.Cli/Commands/NewCommand.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.CommandLine; +using System.Diagnostics.CodeAnalysis; using System.Text.RegularExpressions; using Aspire.Cli.Configuration; using Aspire.Cli.Interaction; @@ -232,50 +233,68 @@ private ITemplate[] GetTemplatesForPrompt(ParseResult parseResult) return null; } - return await _prompter.PromptForTemplateAsync(templatesForPrompt, cancellationToken); - } - - private async Task ResolveCliTemplateVersionAsync(ParseResult parseResult, CancellationToken cancellationToken) - { - var channels = await _packagingService.GetChannelsAsync(cancellationToken); + var result = await _prompter.PromptForTemplateAsync(templatesForPrompt, cancellationToken); - var configuredChannelName = parseResult.GetValue(_channelOption); - if (string.IsNullOrWhiteSpace(configuredChannelName)) + // The prompt is cleared after selection. + // Write out the selected template again for context before proceeding. + if (result != null) { - configuredChannelName = await _configurationService.GetConfigurationAsync("channel", cancellationToken); + InteractionService.DisplayPlainText($"{NewCommandStrings.SelectAProjectTemplate} {result.Description}"); } + return result; + } - var selectedChannel = string.IsNullOrWhiteSpace(configuredChannelName) - ? channels.FirstOrDefault(c => c.Type is PackageChannelType.Implicit) ?? channels.FirstOrDefault() - : channels.FirstOrDefault(c => string.Equals(c.Name, configuredChannelName, StringComparison.OrdinalIgnoreCase)); - - if (selectedChannel is null) - { - if (string.IsNullOrWhiteSpace(configuredChannelName)) - { - InteractionService.DisplayError("No package channels are available."); - } - else - { - InteractionService.DisplayError($"No channel found matching '{configuredChannelName}'. Valid options are: {string.Join(", ", channels.Select(c => c.Name))}"); - } - - return null; - } + private sealed class ResolveTemplateVersionResult + { + public string? Version { get; init; } - var packages = await selectedChannel.GetTemplatePackagesAsync(ExecutionContext.WorkingDirectory, cancellationToken); - var package = packages - .Where(p => Semver.SemVersion.TryParse(p.Version, Semver.SemVersionStyles.Strict, out _)) - .OrderByDescending(p => Semver.SemVersion.Parse(p.Version, Semver.SemVersionStyles.Strict), Semver.SemVersion.PrecedenceComparer) - .FirstOrDefault(); + [MemberNotNullWhen(true, nameof(Version))] + [MemberNotNullWhen(false, nameof(ErrorMessage))] + public bool Success => Version is not null; - if (package is null) - { - InteractionService.DisplayError($"No template versions found in channel '{selectedChannel.Name}'."); - return null; - } + public string? ErrorMessage { get; init; } + } - return package.Version; + private async Task ResolveCliTemplateVersionAsync(ParseResult parseResult, CancellationToken cancellationToken) + { + return await InteractionService.ShowStatusAsync( + NewCommandStrings.ResolvingTemplateVersion, + async () => + { + var channels = await _packagingService.GetChannelsAsync(cancellationToken); + + var configuredChannelName = parseResult.GetValue(_channelOption); + if (string.IsNullOrWhiteSpace(configuredChannelName)) + { + configuredChannelName = await _configurationService.GetConfigurationAsync("channel", cancellationToken); + } + + var selectedChannel = string.IsNullOrWhiteSpace(configuredChannelName) + ? channels.FirstOrDefault(c => c.Type is PackageChannelType.Implicit) ?? channels.FirstOrDefault() + : channels.FirstOrDefault(c => string.Equals(c.Name, configuredChannelName, StringComparison.OrdinalIgnoreCase)); + + if (selectedChannel is null) + { + var errorMessage = string.IsNullOrWhiteSpace(configuredChannelName) + ? "No package channels are available." + : $"No channel found matching '{configuredChannelName}'. Valid options are: {string.Join(", ", channels.Select(c => c.Name))}"; + + return new ResolveTemplateVersionResult { ErrorMessage = errorMessage }; + } + + var packages = await selectedChannel.GetTemplatePackagesAsync(ExecutionContext.WorkingDirectory, cancellationToken); + var package = packages + .Where(p => Semver.SemVersion.TryParse(p.Version, Semver.SemVersionStyles.Strict, out _)) + .OrderByDescending(p => Semver.SemVersion.Parse(p.Version, Semver.SemVersionStyles.Strict), Semver.SemVersion.PrecedenceComparer) + .FirstOrDefault(); + + if (package is null) + { + return new ResolveTemplateVersionResult { ErrorMessage = $"No template versions found in channel '{selectedChannel.Name}'." }; + } + + return new ResolveTemplateVersionResult { Version = package.Version }; + }); } protected override async Task ExecuteAsync(ParseResult parseResult, CancellationToken cancellationToken) @@ -298,11 +317,14 @@ protected override async Task ExecuteAsync(ParseResult parseResult, Cancell if (ShouldResolveCliTemplateVersion(template) && string.IsNullOrWhiteSpace(version)) { - version = await ResolveCliTemplateVersionAsync(parseResult, cancellationToken); - if (string.IsNullOrWhiteSpace(version)) + var resolveResult = await ResolveCliTemplateVersionAsync(parseResult, cancellationToken); + if (!resolveResult.Success) { + InteractionService.DisplayError(resolveResult.ErrorMessage); return ExitCodeConstants.InvalidCommand; } + + version = resolveResult.Version; } var inputs = new TemplateInputs diff --git a/src/Aspire.Cli/Commands/RunCommand.cs b/src/Aspire.Cli/Commands/RunCommand.cs index 50fab092700..f2e71ee748c 100644 --- a/src/Aspire.Cli/Commands/RunCommand.cs +++ b/src/Aspire.Cli/Commands/RunCommand.cs @@ -206,7 +206,9 @@ protected override async Task ExecuteAsync(ParseResult parseResult, Cancell // Even if we fail to stop we won't block the apphost starting // to make sure we don't ever break flow. It should mostly stop // just fine though. - var runningInstanceResult = await project.FindAndStopRunningInstanceAsync(effectiveAppHostFile, ExecutionContext.HomeDirectory, cancellationToken); + var runningInstanceResult = await InteractionService.ShowStatusAsync( + RunCommandStrings.CheckingForRunningInstances, + async () => await project.FindAndStopRunningInstanceAsync(effectiveAppHostFile, ExecutionContext.HomeDirectory, cancellationToken)); // If in isolated mode and a running instance was stopped, warn the user if (isolated && runningInstanceResult == RunningInstanceResult.InstanceStopped) diff --git a/src/Aspire.Cli/Commands/UpdateCommand.cs b/src/Aspire.Cli/Commands/UpdateCommand.cs index 839f6d65a40..5e9f7716959 100644 --- a/src/Aspire.Cli/Commands/UpdateCommand.cs +++ b/src/Aspire.Cli/Commands/UpdateCommand.cs @@ -152,7 +152,9 @@ protected override async Task ExecuteAsync(ParseResult parseResult, Cancell var channelName = parseResult.GetValue(_channelOption) ?? parseResult.GetValue(_qualityOption); PackageChannel channel; - var allChannels = await _packagingService.GetChannelsAsync(cancellationToken); + var allChannels = await InteractionService.ShowStatusAsync( + UpdateCommandStrings.CheckingForUpdates, + async () => await _packagingService.GetChannelsAsync(cancellationToken)); if (!string.IsNullOrEmpty(channelName)) { @@ -347,8 +349,16 @@ private async Task ExtractAndUpdateAsync(string archivePath, CancellationToken c try { // Extract archive - InteractionService.DisplayMessage(KnownEmojis.Package, "Extracting new CLI..."); - await ArchiveHelper.ExtractAsync(archivePath, tempExtractDir, cancellationToken); + await InteractionService.ShowStatusAsync( + UpdateCommandStrings.ExtractingNewCli, + async () => + { + await ArchiveHelper.ExtractAsync(archivePath, tempExtractDir, cancellationToken); + return 0; + }, + KnownEmojis.Package); + + InteractionService.DisplayMessage(KnownEmojis.Package, UpdateCommandStrings.ExtractedNewCli); // Find the aspire executable in the extracted files var newExePath = Path.Combine(tempExtractDir, exeName); diff --git a/src/Aspire.Cli/Interaction/KnownEmojis.cs b/src/Aspire.Cli/Interaction/KnownEmojis.cs index e8f4fd99c01..e6c05a37f4a 100644 --- a/src/Aspire.Cli/Interaction/KnownEmojis.cs +++ b/src/Aspire.Cli/Interaction/KnownEmojis.cs @@ -29,6 +29,7 @@ internal static class KnownEmojis public static readonly KnownEmoji FloppyDisk = new("floppy_disk"); public static readonly KnownEmoji Gear = new("gear"); public static readonly KnownEmoji Hammer = new("hammer"); + public static readonly KnownEmoji Ice = new("ice"); public static readonly KnownEmoji HammerAndWrench = new("hammer_and_wrench"); public static readonly KnownEmoji Information = new("information"); public static readonly KnownEmoji Key = new("key"); diff --git a/src/Aspire.Cli/Projects/GuestAppHostProject.cs b/src/Aspire.Cli/Projects/GuestAppHostProject.cs index 2f2cb3666b4..be59f437027 100644 --- a/src/Aspire.Cli/Projects/GuestAppHostProject.cs +++ b/src/Aspire.Cli/Projects/GuestAppHostProject.cs @@ -964,8 +964,15 @@ public async Task UpdatePackagesAsync(UpdatePackagesContex // Rebuild and regenerate SDK code with updated packages _interactionService.DisplayEmptyLine(); - _interactionService.DisplaySubtleMessage("Regenerating SDK code with updated packages..."); - await BuildAndGenerateSdkAsync(directory, cancellationToken); + await _interactionService.ShowStatusAsync( + UpdateCommandStrings.RegeneratingSdkCode, + async () => + { + await BuildAndGenerateSdkAsync(directory, cancellationToken); + return 0; + }); + + _interactionService.DisplayMessage(KnownEmojis.Package, UpdateCommandStrings.RegeneratedSdkCode); _interactionService.DisplayEmptyLine(); _interactionService.DisplaySuccess(UpdateCommandStrings.UpdateSuccessfulMessage); diff --git a/src/Aspire.Cli/Projects/ProjectUpdater.cs b/src/Aspire.Cli/Projects/ProjectUpdater.cs index 549a9018511..5b9722d2f0b 100644 --- a/src/Aspire.Cli/Projects/ProjectUpdater.cs +++ b/src/Aspire.Cli/Projects/ProjectUpdater.cs @@ -120,11 +120,18 @@ public async Task UpdateProjectAsync(FileInfo projectFile, interactionService.DisplayEmptyLine(); - foreach (var updateStep in updateSteps) - { - interactionService.DisplaySubtleMessage(string.Format(CultureInfo.InvariantCulture, UpdateCommandStrings.ExecutingUpdateStepFormat, updateStep.Description)); - await updateStep.Callback(); - } + await interactionService.ShowStatusAsync( + UpdateCommandStrings.ApplyingUpdates, + async () => + { + foreach (var updateStep in updateSteps) + { + interactionService.DisplaySubtleMessage(string.Format(CultureInfo.InvariantCulture, UpdateCommandStrings.ExecutingUpdateStepFormat, updateStep.Description)); + await updateStep.Callback(); + } + + return 0; + }); interactionService.DisplayEmptyLine(); diff --git a/src/Aspire.Cli/Resources/AddCommandStrings.Designer.cs b/src/Aspire.Cli/Resources/AddCommandStrings.Designer.cs index 9f5e8514b27..71c85806aaa 100644 --- a/src/Aspire.Cli/Resources/AddCommandStrings.Designer.cs +++ b/src/Aspire.Cli/Resources/AddCommandStrings.Designer.cs @@ -204,5 +204,13 @@ public static string UnableToStopRunningInstances return ResourceManager.GetString("UnableToStopRunningInstances", resourceCulture); } } + + public static string CheckingForRunningInstances + { + get + { + return ResourceManager.GetString("CheckingForRunningInstances", resourceCulture); + } + } } } diff --git a/src/Aspire.Cli/Resources/AddCommandStrings.resx b/src/Aspire.Cli/Resources/AddCommandStrings.resx index 84623e973d3..1c6d2d5e594 100644 --- a/src/Aspire.Cli/Resources/AddCommandStrings.resx +++ b/src/Aspire.Cli/Resources/AddCommandStrings.resx @@ -178,4 +178,7 @@ Unable to stop one or more running Aspire AppHost instances. Please stop the application and try again. + + Checking for running instances... + diff --git a/src/Aspire.Cli/Resources/InitCommandStrings.Designer.cs b/src/Aspire.Cli/Resources/InitCommandStrings.Designer.cs index 8178ece1dc7..9e80ff89783 100644 --- a/src/Aspire.Cli/Resources/InitCommandStrings.Designer.cs +++ b/src/Aspire.Cli/Resources/InitCommandStrings.Designer.cs @@ -110,5 +110,11 @@ internal static string AddingServiceDefaultsProjectToSolution { return ResourceManager.GetString("AddingServiceDefaultsProjectToSolution", resourceCulture); } } + + internal static string ResolvingTemplateVersion { + get { + return ResourceManager.GetString("ResolvingTemplateVersion", resourceCulture); + } + } } } \ No newline at end of file diff --git a/src/Aspire.Cli/Resources/InitCommandStrings.resx b/src/Aspire.Cli/Resources/InitCommandStrings.resx index 23977ff23b0..dc351b5cdea 100644 --- a/src/Aspire.Cli/Resources/InitCommandStrings.resx +++ b/src/Aspire.Cli/Resources/InitCommandStrings.resx @@ -93,4 +93,7 @@ Adding ServiceDefaults project to solution... + + Resolving template version... + \ No newline at end of file diff --git a/src/Aspire.Cli/Resources/NewCommandStrings.Designer.cs b/src/Aspire.Cli/Resources/NewCommandStrings.Designer.cs index 198156b9900..6e436d799ce 100644 --- a/src/Aspire.Cli/Resources/NewCommandStrings.Designer.cs +++ b/src/Aspire.Cli/Resources/NewCommandStrings.Designer.cs @@ -138,5 +138,11 @@ public static string PromptToUsePrereleaseTemplates { return ResourceManager.GetString("PromptToUsePrereleaseTemplates", resourceCulture); } } + + public static string ResolvingTemplateVersion { + get { + return ResourceManager.GetString("ResolvingTemplateVersion", resourceCulture); + } + } } } diff --git a/src/Aspire.Cli/Resources/NewCommandStrings.resx b/src/Aspire.Cli/Resources/NewCommandStrings.resx index b42073476c3..7f35dde64ee 100644 --- a/src/Aspire.Cli/Resources/NewCommandStrings.resx +++ b/src/Aspire.Cli/Resources/NewCommandStrings.resx @@ -148,4 +148,7 @@ The programming language for the AppHost. + + Resolving template version... + diff --git a/src/Aspire.Cli/Resources/UpdateCommandStrings.Designer.cs b/src/Aspire.Cli/Resources/UpdateCommandStrings.Designer.cs index 3ffb04ec849..2c608fb89cb 100644 --- a/src/Aspire.Cli/Resources/UpdateCommandStrings.Designer.cs +++ b/src/Aspire.Cli/Resources/UpdateCommandStrings.Designer.cs @@ -109,5 +109,11 @@ internal static string ProjectArgumentDescription { internal static string MigratedToNewSdkFormat => ResourceManager.GetString("MigratedToNewSdkFormat", resourceCulture); internal static string RemovedObsoleteAppHostPackage => ResourceManager.GetString("RemovedObsoleteAppHostPackage", resourceCulture); internal static string NoWritePermissionToInstallDirectory => ResourceManager.GetString("NoWritePermissionToInstallDirectory", resourceCulture); + internal static string CheckingForUpdates => ResourceManager.GetString("CheckingForUpdates", resourceCulture); + internal static string ApplyingUpdates => ResourceManager.GetString("ApplyingUpdates", resourceCulture); + internal static string ExtractingNewCli => ResourceManager.GetString("ExtractingNewCli", resourceCulture); + internal static string ExtractedNewCli => ResourceManager.GetString("ExtractedNewCli", resourceCulture); + internal static string RegeneratingSdkCode => ResourceManager.GetString("RegeneratingSdkCode", resourceCulture); + internal static string RegeneratedSdkCode => ResourceManager.GetString("RegeneratedSdkCode", resourceCulture); } } diff --git a/src/Aspire.Cli/Resources/UpdateCommandStrings.resx b/src/Aspire.Cli/Resources/UpdateCommandStrings.resx index f79b9c98a49..458f75175c9 100644 --- a/src/Aspire.Cli/Resources/UpdateCommandStrings.resx +++ b/src/Aspire.Cli/Resources/UpdateCommandStrings.resx @@ -144,4 +144,22 @@ Cannot write to installation directory '{0}'. Please run the update with elevated permissions (e.g., using sudo on Linux/macOS). + + Checking for updates... + + + Applying updates... + + + Extracting new CLI... + + + Extracted new CLI + + + Regenerating SDK code with updated packages... + + + Regenerated SDK code with updated packages. + diff --git a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.cs.xlf b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.cs.xlf index bb24461c342..0f8510ed398 100644 --- a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.cs.xlf +++ b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.cs.xlf @@ -7,6 +7,11 @@ Přidává se integrace hostování Aspire... + + Checking for running instances... + Checking for running instances... + + Add a hosting integration to the apphost. Přidejte do hostitele aplikací Aspire integraci hostování. diff --git a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.de.xlf b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.de.xlf index d78167fb247..14767e1b9d4 100644 --- a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.de.xlf +++ b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.de.xlf @@ -7,6 +7,11 @@ Aspire-Hosting-Integration wird hinzugefügt... + + Checking for running instances... + Checking for running instances... + + Add a hosting integration to the apphost. Fügen Sie dem Aspire AppHost eine Hosting-Integration hinzu. diff --git a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.es.xlf b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.es.xlf index e338b59f460..e4f29db42e6 100644 --- a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.es.xlf +++ b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.es.xlf @@ -7,6 +7,11 @@ Agregando integración de hospedaje de Aspire... + + Checking for running instances... + Checking for running instances... + + Add a hosting integration to the apphost. Agregue una integración de hospedaje a Aspire AppHost. diff --git a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.fr.xlf b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.fr.xlf index 5571a70a18b..85411608591 100644 --- a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.fr.xlf +++ b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.fr.xlf @@ -7,6 +7,11 @@ Ajout de l’intégration d’hébergement Aspire... + + Checking for running instances... + Checking for running instances... + + Add a hosting integration to the apphost. Ajoutez une intégration d’hébergement à l’Aspire AppHost. diff --git a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.it.xlf b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.it.xlf index c3247c18f84..4b58d0c925a 100644 --- a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.it.xlf +++ b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.it.xlf @@ -7,6 +7,11 @@ Aggiunta dell'integrazione di hosting Aspire in corso... + + Checking for running instances... + Checking for running instances... + + Add a hosting integration to the apphost. Aggiungere un'integrazione di hosting all'AppHost Aspire. diff --git a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.ja.xlf b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.ja.xlf index 90add5ffb24..4e1b1aa4004 100644 --- a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.ja.xlf +++ b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.ja.xlf @@ -7,6 +7,11 @@ Aspire ホスティング統合を追加しています... + + Checking for running instances... + Checking for running instances... + + Add a hosting integration to the apphost. Aspire AppHost にホスティング統合を追加します。 diff --git a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.ko.xlf b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.ko.xlf index 1c03456afca..1fb392ff16e 100644 --- a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.ko.xlf +++ b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.ko.xlf @@ -7,6 +7,11 @@ Aspire 호스팅 통합을 추가하는 중... + + Checking for running instances... + Checking for running instances... + + Add a hosting integration to the apphost. Aspire AppHost에 호스팅 통합을 추가하세요. diff --git a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.pl.xlf b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.pl.xlf index 54c15d16df9..80e171960a2 100644 --- a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.pl.xlf +++ b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.pl.xlf @@ -7,6 +7,11 @@ Trwa dodawanie integracji hostingu platformy Aspire... + + Checking for running instances... + Checking for running instances... + + Add a hosting integration to the apphost. Dodaj integrację hostingu do hosta AppHost platformy Aspire. diff --git a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.pt-BR.xlf b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.pt-BR.xlf index 5ef5e738086..174232e941e 100644 --- a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.pt-BR.xlf +++ b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.pt-BR.xlf @@ -7,6 +7,11 @@ Adicionando integração de hosting do Aspire... + + Checking for running instances... + Checking for running instances... + + Add a hosting integration to the apphost. Adicione uma integração de hosting ao Aspire AppHost. diff --git a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.ru.xlf b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.ru.xlf index e245c37f520..97af4404f3a 100644 --- a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.ru.xlf +++ b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.ru.xlf @@ -7,6 +7,11 @@ Добавление интеграции размещения Aspire... + + Checking for running instances... + Checking for running instances... + + Add a hosting integration to the apphost. Добавьте интеграцию размещения в Aspire AppHost. diff --git a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.tr.xlf b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.tr.xlf index 3b2e6350c61..0dfe380f9b3 100644 --- a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.tr.xlf +++ b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.tr.xlf @@ -7,6 +7,11 @@ Aspire barındırma tümleştirmesi ekleniyor... + + Checking for running instances... + Checking for running instances... + + Add a hosting integration to the apphost. Aspire AppHost'a bir barındırma tümleştirmesi ekleyin. diff --git a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.zh-Hans.xlf b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.zh-Hans.xlf index 563019e9b67..f55a676a7c6 100644 --- a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.zh-Hans.xlf +++ b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.zh-Hans.xlf @@ -7,6 +7,11 @@ 正在添加 Aspire 托管集成... + + Checking for running instances... + Checking for running instances... + + Add a hosting integration to the apphost. 将托管集成添加到 Aspire AppHost。 diff --git a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.zh-Hant.xlf b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.zh-Hant.xlf index 1a196dee737..e2c1b243074 100644 --- a/src/Aspire.Cli/Resources/xlf/AddCommandStrings.zh-Hant.xlf +++ b/src/Aspire.Cli/Resources/xlf/AddCommandStrings.zh-Hant.xlf @@ -7,6 +7,11 @@ 正在新增 Aspire 主機整合... + + Checking for running instances... + Checking for running instances... + + Add a hosting integration to the apphost. 將主機整合新增到 Aspire AppHost。 diff --git a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.cs.xlf b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.cs.xlf index 04e77e8310d..77985587fa2 100644 --- a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.cs.xlf +++ b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.cs.xlf @@ -47,6 +47,11 @@ Nenašel se žádný soubor řešení. Vytváří se AppHost s jedním souborem... + + Resolving template version... + Resolving template version... + + Solution detected: {0} Zjištěné řešení: {0} diff --git a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.de.xlf b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.de.xlf index 0e9c4e74db6..fd2a2dcb6cc 100644 --- a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.de.xlf +++ b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.de.xlf @@ -47,6 +47,11 @@ Keine Lösungsdatei gefunden. AppHost mit einzelner Datei wird erstellt … + + Resolving template version... + Resolving template version... + + Solution detected: {0} Lösung erkannt: {0} diff --git a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.es.xlf b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.es.xlf index c15d61fc51d..1903b29a032 100644 --- a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.es.xlf +++ b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.es.xlf @@ -47,6 +47,11 @@ No se encontró ningún archivo de solución. Creando AppHost de un solo archivo... + + Resolving template version... + Resolving template version... + + Solution detected: {0} Solución detectada: {0} diff --git a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.fr.xlf b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.fr.xlf index ac5b6eb918a..6c44497d7b6 100644 --- a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.fr.xlf +++ b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.fr.xlf @@ -47,6 +47,11 @@ Fichier de solution introuvable. Création d’un AppHost à fichier unique... + + Resolving template version... + Resolving template version... + + Solution detected: {0} Solution détectée : {0} diff --git a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.it.xlf b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.it.xlf index 520e4717f2f..92ffe6e9570 100644 --- a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.it.xlf +++ b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.it.xlf @@ -47,6 +47,11 @@ Nessun file di soluzione trovato. Creazione di AppHost a file singolo in corso... + + Resolving template version... + Resolving template version... + + Solution detected: {0} Soluzione rilevata: {0} diff --git a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.ja.xlf b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.ja.xlf index 416fc2ee7d8..3acbcc62965 100644 --- a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.ja.xlf +++ b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.ja.xlf @@ -47,6 +47,11 @@ ソリューション ファイルが見つかりません。単一ファイルの AppHost を作成しています... + + Resolving template version... + Resolving template version... + + Solution detected: {0} ソリューションが検出されました: {0} diff --git a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.ko.xlf b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.ko.xlf index bc29fe515c2..0c729e510ec 100644 --- a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.ko.xlf +++ b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.ko.xlf @@ -47,6 +47,11 @@ 솔루션 파일을 찾을 수 없습니다. 단일 파일 AppHost를 만드는 중... + + Resolving template version... + Resolving template version... + + Solution detected: {0} 솔루션 검색됨: {0} diff --git a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.pl.xlf b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.pl.xlf index dbf04baf696..bc20d2a4897 100644 --- a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.pl.xlf +++ b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.pl.xlf @@ -47,6 +47,11 @@ Nie znaleziono pliku rozwiązania. Trwa tworzenie hosta aplikacji (AppHost) z jednym plikiem... + + Resolving template version... + Resolving template version... + + Solution detected: {0} Wykryto rozwiązanie: {0} diff --git a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.pt-BR.xlf b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.pt-BR.xlf index d96c76b70b9..6a1855c9316 100644 --- a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.pt-BR.xlf +++ b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.pt-BR.xlf @@ -47,6 +47,11 @@ Não há arquivos de solução abertos. Criando o AppHost de arquivo único... + + Resolving template version... + Resolving template version... + + Solution detected: {0} Solução detectada: {0} diff --git a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.ru.xlf b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.ru.xlf index 1d518575e08..dc12fdf76cf 100644 --- a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.ru.xlf +++ b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.ru.xlf @@ -47,6 +47,11 @@ Файл решения не найден. Создание однофайлового AppHost... + + Resolving template version... + Resolving template version... + + Solution detected: {0} Обнаружено решение: {0} diff --git a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.tr.xlf b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.tr.xlf index 05571936352..97a32f836c1 100644 --- a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.tr.xlf +++ b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.tr.xlf @@ -47,6 +47,11 @@ Çözüm dosyası bulunamadı. Tek dosyalı AppHost oluşturuluyor... + + Resolving template version... + Resolving template version... + + Solution detected: {0} Çözüm algılandı: {0} diff --git a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.zh-Hans.xlf b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.zh-Hans.xlf index b3721872253..f3257b8e8b7 100644 --- a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.zh-Hans.xlf +++ b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.zh-Hans.xlf @@ -47,6 +47,11 @@ 找不到解决方案文件。正在创建单文件 AppHost... + + Resolving template version... + Resolving template version... + + Solution detected: {0} 检测到解决方案: {0} diff --git a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.zh-Hant.xlf b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.zh-Hant.xlf index 2396e175973..ad62f82e797 100644 --- a/src/Aspire.Cli/Resources/xlf/InitCommandStrings.zh-Hant.xlf +++ b/src/Aspire.Cli/Resources/xlf/InitCommandStrings.zh-Hant.xlf @@ -47,6 +47,11 @@ 找不到解決方案檔案。正在建立單一檔案 AppHost... + + Resolving template version... + Resolving template version... + + Solution detected: {0} 偵測到的解決方案: {0} diff --git a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.cs.xlf b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.cs.xlf index c20b8aba626..c99ed7ed0ca 100644 --- a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.cs.xlf +++ b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.cs.xlf @@ -47,6 +47,11 @@ Výstupní cesta pro projekt + + Resolving template version... + Resolving template version... + + Select a template: Vyberte šablonu: diff --git a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.de.xlf b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.de.xlf index 13dc8ba2eb8..47db6e1d2ca 100644 --- a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.de.xlf +++ b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.de.xlf @@ -47,6 +47,11 @@ Der Ausgabepfad für das Projekt. + + Resolving template version... + Resolving template version... + + Select a template: Wählen Sie eine Vorlage aus: diff --git a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.es.xlf b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.es.xlf index 8b92d9151a4..b4183d6a32c 100644 --- a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.es.xlf +++ b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.es.xlf @@ -47,6 +47,11 @@ La ruta de salida del proyecto. + + Resolving template version... + Resolving template version... + + Select a template: Seleccione una plantilla: diff --git a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.fr.xlf b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.fr.xlf index 8615786e812..2b12a209263 100644 --- a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.fr.xlf +++ b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.fr.xlf @@ -47,6 +47,11 @@ Le chemin de sortie du projet. + + Resolving template version... + Resolving template version... + + Select a template: Sélectionnez un modèle : diff --git a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.it.xlf b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.it.xlf index e055850c46f..184fa6fcc38 100644 --- a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.it.xlf +++ b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.it.xlf @@ -47,6 +47,11 @@ Percorso di output per il progetto. + + Resolving template version... + Resolving template version... + + Select a template: Selezionare un modello: diff --git a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.ja.xlf b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.ja.xlf index eece148caff..92891d5986a 100644 --- a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.ja.xlf +++ b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.ja.xlf @@ -47,6 +47,11 @@ プロジェクトの出力パス。 + + Resolving template version... + Resolving template version... + + Select a template: テンプレートの選択: diff --git a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.ko.xlf b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.ko.xlf index 025216abe12..e893cc3fde6 100644 --- a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.ko.xlf +++ b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.ko.xlf @@ -47,6 +47,11 @@ 프로젝트의 출력 경로입니다. + + Resolving template version... + Resolving template version... + + Select a template: 템플릿 선택: diff --git a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.pl.xlf b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.pl.xlf index 9d7882f27a4..ee3c6691908 100644 --- a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.pl.xlf +++ b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.pl.xlf @@ -47,6 +47,11 @@ Ścieżka wyjściowa projektu. + + Resolving template version... + Resolving template version... + + Select a template: Wybierz szablon: diff --git a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.pt-BR.xlf b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.pt-BR.xlf index 9b042608297..459623b6bdf 100644 --- a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.pt-BR.xlf +++ b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.pt-BR.xlf @@ -47,6 +47,11 @@ O caminho de saída para o projeto. + + Resolving template version... + Resolving template version... + + Select a template: Selecione um modelo: diff --git a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.ru.xlf b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.ru.xlf index f4aac64b11f..0853531ca96 100644 --- a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.ru.xlf +++ b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.ru.xlf @@ -47,6 +47,11 @@ Выходной путь для проекта. + + Resolving template version... + Resolving template version... + + Select a template: Выберите шаблон: diff --git a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.tr.xlf b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.tr.xlf index b2ab0aa19eb..33af320fecb 100644 --- a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.tr.xlf +++ b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.tr.xlf @@ -47,6 +47,11 @@ Projenin çıkış yolu. + + Resolving template version... + Resolving template version... + + Select a template: Bir şablon seçin: diff --git a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.zh-Hans.xlf b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.zh-Hans.xlf index 2b5b6567f1e..64b628a08f3 100644 --- a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.zh-Hans.xlf +++ b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.zh-Hans.xlf @@ -47,6 +47,11 @@ 项目的输出路径。 + + Resolving template version... + Resolving template version... + + Select a template: 选择模板: diff --git a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.zh-Hant.xlf b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.zh-Hant.xlf index 18e9b06f0ba..12e0ce2dafe 100644 --- a/src/Aspire.Cli/Resources/xlf/NewCommandStrings.zh-Hant.xlf +++ b/src/Aspire.Cli/Resources/xlf/NewCommandStrings.zh-Hant.xlf @@ -47,6 +47,11 @@ 專案的輸出路徑。 + + Resolving template version... + Resolving template version... + + Select a template: 選取範本: diff --git a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.cs.xlf b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.cs.xlf index b0011508192..9e918b2a747 100644 --- a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.cs.xlf +++ b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.cs.xlf @@ -32,6 +32,11 @@ Chcete tyto změny použít v souboru NuGet.config? + + Applying updates... + Applying updates... + + Central package management is currently not supported by 'aspire update'. Centrální správa balíčků není v současné době přes aspire update podporována. @@ -47,6 +52,11 @@ Kanál, na který se má aktualizovat (stabilní, příprava, denní) + + Checking for updates... + Checking for updates... + + Could not find PackageVersion element for '{0}' in {1} Nepovedlo se najít element PackageVersion pro: {0} v: {1} @@ -77,6 +87,16 @@ Spouští se: {0} + + Extracted new CLI + Extracted new CLI + + + + Extracting new CLI... + Extracting new CLI... + + Failed to discover NuGet.config files. Nepodařilo se zjistit soubory NuGet.config. @@ -177,6 +197,16 @@ Úroveň kvality, na kterou se má aktualizovat (stabilní, příprava, denní) + + Regenerated SDK code with updated packages. + Regenerated SDK code with updated packages. + + + + Regenerating SDK code with updated packages... + Regenerating SDK code with updated packages... + + Removed: {0} Odebráno: {0} diff --git a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.de.xlf b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.de.xlf index b02244f1c36..1565748d480 100644 --- a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.de.xlf +++ b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.de.xlf @@ -32,6 +32,11 @@ Diese Änderungen in NuGet.config übernehmen? + + Applying updates... + Applying updates... + + Central package management is currently not supported by 'aspire update'. Die zentrale Paketverwaltung wird von „aspire update“ zurzeit nicht unterstützt. @@ -47,6 +52,11 @@ Kanal, auf den aktualisiert werden soll (stable, staging, daily) + + Checking for updates... + Checking for updates... + + Could not find PackageVersion element for '{0}' in {1} Das PackageVersion-Element für „{0}“ wurde in {1} nicht gefunden. @@ -77,6 +87,16 @@ Wird ausgeführt: {0} + + Extracted new CLI + Extracted new CLI + + + + Extracting new CLI... + Extracting new CLI... + + Failed to discover NuGet.config files. Beim Auffinden der NuGet.config-Dateien ist ein Fehler aufgetreten. @@ -177,6 +197,16 @@ Qualitätsstufe, auf die aktualisiert werden soll (stable, staging, daily) + + Regenerated SDK code with updated packages. + Regenerated SDK code with updated packages. + + + + Regenerating SDK code with updated packages... + Regenerating SDK code with updated packages... + + Removed: {0} Entfernt: {0} diff --git a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.es.xlf b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.es.xlf index 0ef985b205e..c2a11711aa0 100644 --- a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.es.xlf +++ b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.es.xlf @@ -32,6 +32,11 @@ ¿Aplicar estos cambios en NuGet.config? + + Applying updates... + Applying updates... + + Central package management is currently not supported by 'aspire update'. La administración central de paquetes no es compatible actualmente con "aspire update". @@ -47,6 +52,11 @@ Canal al que se va a actualizar (estable, de ensayo, diario) + + Checking for updates... + Checking for updates... + + Could not find PackageVersion element for '{0}' in {1} No se pudo encontrar el elemento PackageVersion para '{0}' en {1} @@ -77,6 +87,16 @@ Ejecutando: {0} + + Extracted new CLI + Extracted new CLI + + + + Extracting new CLI... + Extracting new CLI... + + Failed to discover NuGet.config files. Error al detectar los archivos NuGet.config. @@ -177,6 +197,16 @@ Nivel de calidad al que se va a actualizar (estable, de ensayo, diario) + + Regenerated SDK code with updated packages. + Regenerated SDK code with updated packages. + + + + Regenerating SDK code with updated packages... + Regenerating SDK code with updated packages... + + Removed: {0} Quitado: {0} diff --git a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.fr.xlf b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.fr.xlf index 781c85f444e..6db234e838a 100644 --- a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.fr.xlf +++ b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.fr.xlf @@ -32,6 +32,11 @@ Voulez-vous appliquer ces modifications à NuGet.config ? + + Applying updates... + Applying updates... + + Central package management is currently not supported by 'aspire update'. Actuellement, la gestion centralisée des packages n’est pas prise en charge par « aspire update ». @@ -47,6 +52,11 @@ Canal vers lequel effectuer une mise à jour (stable, gestion intermédiaire, quotidien) + + Checking for updates... + Checking for updates... + + Could not find PackageVersion element for '{0}' in {1} Élément PackageVersion introuvable pour « {0} » dans {1} @@ -77,6 +87,16 @@ Exécution : {0} + + Extracted new CLI + Extracted new CLI + + + + Extracting new CLI... + Extracting new CLI... + + Failed to discover NuGet.config files. Échec de la découverte des fichiers NuGet.config. @@ -177,6 +197,16 @@ Niveau de qualité vers lequel effectuer une mise à jour (stable, gestion intermédiaire, quotidien) + + Regenerated SDK code with updated packages. + Regenerated SDK code with updated packages. + + + + Regenerating SDK code with updated packages... + Regenerating SDK code with updated packages... + + Removed: {0} Supprimé : {0} diff --git a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.it.xlf b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.it.xlf index 08b452195a6..1c8dc06b660 100644 --- a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.it.xlf +++ b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.it.xlf @@ -32,6 +32,11 @@ Applicare le modifiche a NuGet.config? + + Applying updates... + Applying updates... + + Central package management is currently not supported by 'aspire update'. La gestione centralizzata dei pacchetti non è attualmente supportata da "aspire update". @@ -47,6 +52,11 @@ Canale da aggiornare a (stabile, staging, giornaliero) + + Checking for updates... + Checking for updates... + + Could not find PackageVersion element for '{0}' in {1} Non è possibile trovare l'elemento PackageVersion per '{0}' in {1} @@ -77,6 +87,16 @@ Esecuzione in corso: {0} + + Extracted new CLI + Extracted new CLI + + + + Extracting new CLI... + Extracting new CLI... + + Failed to discover NuGet.config files. Non è possibile individuare i file NuGet.config. @@ -177,6 +197,16 @@ Livello di qualità da aggiornare a (stabile, staging, giornaliero) + + Regenerated SDK code with updated packages. + Regenerated SDK code with updated packages. + + + + Regenerating SDK code with updated packages... + Regenerating SDK code with updated packages... + + Removed: {0} Rimosso: {0} diff --git a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.ja.xlf b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.ja.xlf index 14600c37930..d3ce03430c7 100644 --- a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.ja.xlf +++ b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.ja.xlf @@ -32,6 +32,11 @@ これらの変更を NuGet.config に適用しますか? + + Applying updates... + Applying updates... + + Central package management is currently not supported by 'aspire update'. 現在、中央パッケージ管理では、'aspire update' によるサポートがありません。 @@ -47,6 +52,11 @@ 更新先のチャネル (安定、ステージング、毎日) + + Checking for updates... + Checking for updates... + + Could not find PackageVersion element for '{0}' in {1} {1} 内に '{0}' の PackageVersion 要素が見つかりませんでした @@ -77,6 +87,16 @@ 次を実行しています: {0} + + Extracted new CLI + Extracted new CLI + + + + Extracting new CLI... + Extracting new CLI... + + Failed to discover NuGet.config files. NuGet.config ファイルを検出できませんでした。 @@ -177,6 +197,16 @@ 更新先の品質レベル (安定、ステージング、毎日) + + Regenerated SDK code with updated packages. + Regenerated SDK code with updated packages. + + + + Regenerating SDK code with updated packages... + Regenerating SDK code with updated packages... + + Removed: {0} 削除済み: {0} diff --git a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.ko.xlf b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.ko.xlf index 8c5a2327796..19eaa99a2d2 100644 --- a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.ko.xlf +++ b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.ko.xlf @@ -32,6 +32,11 @@ NuGet.config에 이러한 변경 내용을 적용하시겠습니까? + + Applying updates... + Applying updates... + + Central package management is currently not supported by 'aspire update'. 중앙 패키지 관리는 현재 'aspire update'에서 지원되지 않습니다. @@ -47,6 +52,11 @@ 업데이트할 채널(안정, 스테이징, 데일리) + + Checking for updates... + Checking for updates... + + Could not find PackageVersion element for '{0}' in {1} {1}에서 '{0}'에 대한 PackageVersion 요소를 찾을 수 없습니다. @@ -77,6 +87,16 @@ 실행 중: {0} + + Extracted new CLI + Extracted new CLI + + + + Extracting new CLI... + Extracting new CLI... + + Failed to discover NuGet.config files. NuGet.config 파일을 검색하지 못했습니다. @@ -177,6 +197,16 @@ 업데이트할 품질 수준(안정, 스테이징, 데일리) + + Regenerated SDK code with updated packages. + Regenerated SDK code with updated packages. + + + + Regenerating SDK code with updated packages... + Regenerating SDK code with updated packages... + + Removed: {0} 제거됨: {0} diff --git a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.pl.xlf b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.pl.xlf index 03fa52b5606..c370eaf8f74 100644 --- a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.pl.xlf +++ b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.pl.xlf @@ -32,6 +32,11 @@ Czy zastosować te zmiany do pliku NuGet.config? + + Applying updates... + Applying updates... + + Central package management is currently not supported by 'aspire update'. Centralne zarządzanie pakietami nie jest obecnie obsługiwane przez „aktualizację Aspire”. @@ -47,6 +52,11 @@ Kanał, do którego należy zaktualizować (stabilny, przejściowy, dzienny) + + Checking for updates... + Checking for updates... + + Could not find PackageVersion element for '{0}' in {1} Nie można odnaleźć elementu PackageVersion dla „{0}” w {1} @@ -77,6 +87,16 @@ Wykonywanie: {0} + + Extracted new CLI + Extracted new CLI + + + + Extracting new CLI... + Extracting new CLI... + + Failed to discover NuGet.config files. Nie można odnaleźć plików NuGet.config. @@ -177,6 +197,16 @@ Poziom jakości, do którego należy zaktualizować (stabilny, przejściowy, dzienny) + + Regenerated SDK code with updated packages. + Regenerated SDK code with updated packages. + + + + Regenerating SDK code with updated packages... + Regenerating SDK code with updated packages... + + Removed: {0} Usunięto: {0} diff --git a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.pt-BR.xlf b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.pt-BR.xlf index f3c587be496..9a298067e2f 100644 --- a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.pt-BR.xlf +++ b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.pt-BR.xlf @@ -32,6 +32,11 @@ Aplicar essas alterações ao NuGet.config? + + Applying updates... + Applying updates... + + Central package management is currently not supported by 'aspire update'. No momento, o gerenciamento central de pacotes por “atualização de atualização” não ´possui suporte. @@ -47,6 +52,11 @@ Canal para o qual atualizar (estável, preparo, diariamente) + + Checking for updates... + Checking for updates... + + Could not find PackageVersion element for '{0}' in {1} Não foi possível localizar o elemento PackageVersion para "{0}" em {1} @@ -77,6 +87,16 @@ Executando: {0} + + Extracted new CLI + Extracted new CLI + + + + Extracting new CLI... + Extracting new CLI... + + Failed to discover NuGet.config files. Falha ao descobrir os arquivos NuGet.config. @@ -177,6 +197,16 @@ Nível de qualidade para o qual atualizar (estável, preparo, diariamente) + + Regenerated SDK code with updated packages. + Regenerated SDK code with updated packages. + + + + Regenerating SDK code with updated packages... + Regenerating SDK code with updated packages... + + Removed: {0} Removido: {0} diff --git a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.ru.xlf b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.ru.xlf index b81c4b90b1d..4c9b2bd5e48 100644 --- a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.ru.xlf +++ b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.ru.xlf @@ -32,6 +32,11 @@ Применить эти изменения к NuGet.config? + + Applying updates... + Applying updates... + + Central package management is currently not supported by 'aspire update'. Централизованное управление пакетами в настоящее время не поддерживается функцией "обновление Aspire". @@ -47,6 +52,11 @@ Канал для обновления (стабильный, промежуточный, ежедневный) + + Checking for updates... + Checking for updates... + + Could not find PackageVersion element for '{0}' in {1} Не удалось найти элемент PackageVersion для "{0}" в {1} @@ -77,6 +87,16 @@ Выполнение: {0} + + Extracted new CLI + Extracted new CLI + + + + Extracting new CLI... + Extracting new CLI... + + Failed to discover NuGet.config files. Не удалось обнаружить файлы NuGet.config. @@ -177,6 +197,16 @@ Уровень качества для обновления (стабильный, промежуточный, ежедневный) + + Regenerated SDK code with updated packages. + Regenerated SDK code with updated packages. + + + + Regenerating SDK code with updated packages... + Regenerating SDK code with updated packages... + + Removed: {0} Удалено: {0} diff --git a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.tr.xlf b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.tr.xlf index ee8f553e842..c05dc1cf87c 100644 --- a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.tr.xlf +++ b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.tr.xlf @@ -32,6 +32,11 @@ Bu değişiklikler NuGet.config dosyasına uygulansın mı? + + Applying updates... + Applying updates... + + Central package management is currently not supported by 'aspire update'. Merkezi paket yönetimi şu anda 'aspire update' tarafından desteklenmiyor. @@ -47,6 +52,11 @@ Güncelleştirme yapılacak kanal (kararlı, hazırlama, günlük) + + Checking for updates... + Checking for updates... + + Could not find PackageVersion element for '{0}' in {1} {1} içinde '{0}' için PackageVersion öğesi bulunamadı @@ -77,6 +87,16 @@ Yürütülüyor: {0} + + Extracted new CLI + Extracted new CLI + + + + Extracting new CLI... + Extracting new CLI... + + Failed to discover NuGet.config files. NuGet.config dosyalarını bulunamadı. @@ -177,6 +197,16 @@ Güncelleştirilecek kalite seviyesi (kararlı, hazırlama, günlük) + + Regenerated SDK code with updated packages. + Regenerated SDK code with updated packages. + + + + Regenerating SDK code with updated packages... + Regenerating SDK code with updated packages... + + Removed: {0} Kaldırıldı: {0} diff --git a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.zh-Hans.xlf b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.zh-Hans.xlf index ae01d9f7b71..ca57f107045 100644 --- a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.zh-Hans.xlf +++ b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.zh-Hans.xlf @@ -32,6 +32,11 @@ 是否将这些更改应用到 NuGet.config? + + Applying updates... + Applying updates... + + Central package management is currently not supported by 'aspire update'. "aspire update" 当前不支持中央包管理。 @@ -47,6 +52,11 @@ 要更新到的频道(稳定、暂存、每日) + + Checking for updates... + Checking for updates... + + Could not find PackageVersion element for '{0}' in {1} 在 {1} 中找不到 ‘{0}’ 的 PackageVersion 元素 @@ -77,6 +87,16 @@ 正在执行: {0} + + Extracted new CLI + Extracted new CLI + + + + Extracting new CLI... + Extracting new CLI... + + Failed to discover NuGet.config files. 未能发现 NuGet.config 文件。 @@ -177,6 +197,16 @@ 要更新到的质量级别(稳定、暂存、每日) + + Regenerated SDK code with updated packages. + Regenerated SDK code with updated packages. + + + + Regenerating SDK code with updated packages... + Regenerating SDK code with updated packages... + + Removed: {0} 已移除: {0} diff --git a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.zh-Hant.xlf b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.zh-Hant.xlf index 28782266096..47aedafc849 100644 --- a/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.zh-Hant.xlf +++ b/src/Aspire.Cli/Resources/xlf/UpdateCommandStrings.zh-Hant.xlf @@ -32,6 +32,11 @@ 是否將這些變更套用至 NuGet.config? + + Applying updates... + Applying updates... + + Central package management is currently not supported by 'aspire update'. 中央套件管理目前不受 'aspire update' 支援。 @@ -47,6 +52,11 @@ 要更新的通道 (穩定、暫存、每日) + + Checking for updates... + Checking for updates... + + Could not find PackageVersion element for '{0}' in {1} 在{1}中找不到 '{0}' 的 PackageVersion 元素 @@ -77,6 +87,16 @@ 正在執行: {0} + + Extracted new CLI + Extracted new CLI + + + + Extracting new CLI... + Extracting new CLI... + + Failed to discover NuGet.config files. 無法探索 NuGet.config 檔案。 @@ -177,6 +197,16 @@ 要更新的品質等級 (穩定、暫存、每日) + + Regenerated SDK code with updated packages. + Regenerated SDK code with updated packages. + + + + Regenerating SDK code with updated packages... + Regenerating SDK code with updated packages... + + Removed: {0} 已移除: {0} diff --git a/src/Aspire.Cli/Templating/CliTemplateFactory.EmptyTemplate.cs b/src/Aspire.Cli/Templating/CliTemplateFactory.EmptyTemplate.cs index e711728f124..af4446f21ac 100644 --- a/src/Aspire.Cli/Templating/CliTemplateFactory.EmptyTemplate.cs +++ b/src/Aspire.Cli/Templating/CliTemplateFactory.EmptyTemplate.cs @@ -41,15 +41,13 @@ private async Task ApplyEmptyAppHostTemplateAsync(CallbackTempla var defaultOutputPath = $"./{projectName}"; outputPath = await _prompter.PromptForOutputPath(defaultOutputPath, cancellationToken); } - if (!Path.IsPathRooted(outputPath)) - { - outputPath = Path.Combine(_executionContext.WorkingDirectory.FullName, outputPath); - } + outputPath = Path.GetFullPath(outputPath, _executionContext.WorkingDirectory.FullName); _logger.LogDebug("Applying empty AppHost template. LanguageId: {LanguageId}, Language: {LanguageDisplayName}, ProjectName: {ProjectName}, OutputPath: {OutputPath}.", languageId, language.DisplayName, projectName, outputPath); var useLocalhostTld = await ResolveUseLocalhostTldAsync(parseResult, cancellationToken); + TemplateResult templateResult; try { if (!Directory.Exists(outputPath)) @@ -57,22 +55,40 @@ private async Task ApplyEmptyAppHostTemplateAsync(CallbackTempla Directory.CreateDirectory(outputPath); } - if (language.LanguageId.Value.Equals(Projects.KnownLanguageId.CSharp, StringComparison.OrdinalIgnoreCase)) + var isCsharp = language.LanguageId.Value.Equals(Projects.KnownLanguageId.CSharp, StringComparison.OrdinalIgnoreCase); + if (isCsharp) { - _logger.LogDebug("Using embedded C# empty AppHost template for '{OutputPath}'.", outputPath); - await WriteCSharpEmptyAppHostAsync(inputs.Version, outputPath, projectName, useLocalhostTld, cancellationToken); + // Do this first so there is no prompt while status is displayed for creating project. await _templateNuGetConfigService.PromptToCreateOrUpdateNuGetConfigAsync(inputs.Channel, outputPath, cancellationToken); } - else - { - _logger.LogDebug("Using scaffolding service for language '{LanguageDisplayName}' in '{OutputPath}'.", language.DisplayName, outputPath); - var context = new ScaffoldContext(language, new DirectoryInfo(outputPath), projectName); - await _scaffoldingService.ScaffoldAsync(context, cancellationToken); - if (useLocalhostTld) + templateResult = await _interactionService.ShowStatusAsync( + TemplatingStrings.CreatingNewProject, + async () => { - await ApplyLocalhostTldToScaffoldedRunProfileAsync(outputPath, projectName, cancellationToken); - } + if (isCsharp) + { + _logger.LogDebug("Using embedded C# empty AppHost template for '{OutputPath}'.", outputPath); + await WriteCSharpEmptyAppHostAsync(inputs.Version, outputPath, projectName, useLocalhostTld, cancellationToken); + } + else + { + _logger.LogDebug("Using scaffolding service for language '{LanguageDisplayName}' in '{OutputPath}'.", language.DisplayName, outputPath); + var context = new ScaffoldContext(language, new DirectoryInfo(outputPath), projectName); + await _scaffoldingService.ScaffoldAsync(context, cancellationToken); + + if (useLocalhostTld) + { + await ApplyLocalhostTldToScaffoldedRunProfileAsync(outputPath, projectName, cancellationToken); + } + } + + return new TemplateResult(ExitCodeConstants.Success, outputPath); + }, emoji: KnownEmojis.Rocket); + + if (templateResult.ExitCode != ExitCodeConstants.Success) + { + return templateResult; } } catch (Exception ex) when (ex is IOException or UnauthorizedAccessException) @@ -84,7 +100,7 @@ private async Task ApplyEmptyAppHostTemplateAsync(CallbackTempla _interactionService.DisplaySuccess($"Created {language.DisplayName.EscapeMarkup()} project at {outputPath.EscapeMarkup()}"); _interactionService.DisplayMessage(KnownEmojis.Information, "Run 'aspire run' to start your AppHost."); - return new TemplateResult(ExitCodeConstants.Success, outputPath); + return templateResult; } private async Task ResolveUseLocalhostTldAsync(System.CommandLine.ParseResult parseResult, CancellationToken cancellationToken) diff --git a/src/Aspire.Cli/Templating/CliTemplateFactory.TypeScriptStarterTemplate.cs b/src/Aspire.Cli/Templating/CliTemplateFactory.TypeScriptStarterTemplate.cs index 2fcaa9b17e4..e62136447b2 100644 --- a/src/Aspire.Cli/Templating/CliTemplateFactory.TypeScriptStarterTemplate.cs +++ b/src/Aspire.Cli/Templating/CliTemplateFactory.TypeScriptStarterTemplate.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using Aspire.Cli.Interaction; +using Aspire.Cli.Resources; using Microsoft.Extensions.Logging; using Spectre.Console; @@ -31,15 +32,13 @@ private async Task ApplyTypeScriptStarterTemplateAsync(CallbackT var defaultOutputPath = $"./{projectName}"; outputPath = await _prompter.PromptForOutputPath(defaultOutputPath, cancellationToken); } - if (!Path.IsPathRooted(outputPath)) - { - outputPath = Path.Combine(_executionContext.WorkingDirectory.FullName, outputPath); - } + outputPath = Path.GetFullPath(outputPath, _executionContext.WorkingDirectory.FullName); _logger.LogDebug("Applying TypeScript starter template. ProjectName: {ProjectName}, OutputPath: {OutputPath}, AspireVersion: {AspireVersion}.", projectName, outputPath, aspireVersion); var useLocalhostTld = await ResolveUseLocalhostTldAsync(parseResult, cancellationToken); + TemplateResult templateResult; try { if (!Directory.Exists(outputPath)) @@ -47,14 +46,42 @@ private async Task ApplyTypeScriptStarterTemplateAsync(CallbackT Directory.CreateDirectory(outputPath); } - var projectNameLower = projectName.ToLowerInvariant(); + templateResult = await _interactionService.ShowStatusAsync( + TemplatingStrings.CreatingNewProject, + async () => + { + var projectNameLower = projectName.ToLowerInvariant(); + + // Generate random ports (matching .NET template port ranges) + var ports = GenerateRandomPorts(); + var hostName = useLocalhostTld ? $"{projectNameLower}.dev.localhost" : "localhost"; + string ApplyAllTokens(string content) => ApplyTokens(content, projectName, projectNameLower, aspireVersion, ports, hostName); + _logger.LogDebug("Copying embedded TypeScript starter template files to '{OutputPath}'.", outputPath); + await CopyTemplateTreeToDiskAsync("ts-starter", outputPath, ApplyAllTokens, cancellationToken); + + var npmPath = PathLookupHelper.FindFullPathFromPath("npm") ?? PathLookupHelper.FindFullPathFromPath("npm.cmd"); + if (npmPath is null) + { + _interactionService.DisplayError("npm is not installed or not found in PATH. Please install Node.js and try again."); + return new TemplateResult(ExitCodeConstants.InvalidCommand); + } - // Generate random ports (matching .NET template port ranges) - var ports = GenerateRandomPorts(); - var hostName = useLocalhostTld ? $"{projectNameLower}.dev.localhost" : "localhost"; - string ApplyAllTokens(string content) => ApplyTokens(content, projectName, projectNameLower, aspireVersion, ports, hostName); - _logger.LogDebug("Copying embedded TypeScript starter template files to '{OutputPath}'.", outputPath); - await CopyTemplateTreeToDiskAsync("ts-starter", outputPath, ApplyAllTokens, cancellationToken); + // Run npm install in the output directory (non-fatal — package may not be published yet) + _logger.LogDebug("Running npm install for TypeScript starter in '{OutputPath}'.", outputPath); + var npmInstallResult = await RunProcessAsync(npmPath, "install", outputPath, cancellationToken); + if (npmInstallResult.ExitCode != 0) + { + _interactionService.DisplaySubtleMessage("npm install had warnings or errors. You may need to run 'npm install' manually after dependencies are available."); + DisplayProcessOutput(npmInstallResult, treatStandardErrorAsError: false); + } + + return new TemplateResult(ExitCodeConstants.Success, outputPath); + }, emoji: KnownEmojis.Rocket); + + if (templateResult.ExitCode != ExitCodeConstants.Success) + { + return templateResult; + } } catch (Exception ex) when (ex is IOException or UnauthorizedAccessException) { @@ -62,25 +89,9 @@ private async Task ApplyTypeScriptStarterTemplateAsync(CallbackT return new TemplateResult(ExitCodeConstants.FailedToCreateNewProject); } - var npmPath = PathLookupHelper.FindFullPathFromPath("npm") ?? PathLookupHelper.FindFullPathFromPath("npm.cmd"); - if (npmPath is null) - { - _interactionService.DisplayError("npm is not installed or not found in PATH. Please install Node.js and try again."); - return new TemplateResult(ExitCodeConstants.InvalidCommand); - } - - // Run npm install in the output directory (non-fatal — package may not be published yet) - _logger.LogDebug("Running npm install for TypeScript starter in '{OutputPath}'.", outputPath); - var npmInstallResult = await RunProcessAsync(npmPath, "install", outputPath, cancellationToken); - if (npmInstallResult.ExitCode != 0) - { - _interactionService.DisplaySubtleMessage("npm install had warnings or errors. You may need to run 'npm install' manually after dependencies are available."); - DisplayProcessOutput(npmInstallResult, treatStandardErrorAsError: false); - } - _interactionService.DisplaySuccess($"Created TypeScript starter project at {outputPath.EscapeMarkup()}"); _interactionService.DisplayMessage(KnownEmojis.Information, "Run 'aspire run' to start your AppHost."); - return new TemplateResult(ExitCodeConstants.Success, outputPath); + return templateResult; } } diff --git a/src/Aspire.Cli/Templating/DotNetTemplateFactory.cs b/src/Aspire.Cli/Templating/DotNetTemplateFactory.cs index c81def9d9d7..8f88caf1e52 100644 --- a/src/Aspire.Cli/Templating/DotNetTemplateFactory.cs +++ b/src/Aspire.Cli/Templating/DotNetTemplateFactory.cs @@ -456,7 +456,7 @@ private async Task ApplyTemplateAsync(CallbackTemplate template, var templateInstallCollector = new OutputCollector(); var templateInstallResult = await interactionService.ShowStatusAsync<(int ExitCode, string? TemplateVersion)>( - $":ice: {TemplatingStrings.GettingTemplates}", + TemplatingStrings.GettingTemplates, async () => { var options = new DotNetCliRunnerInvocationOptions() @@ -480,7 +480,7 @@ private async Task ApplyTemplateAsync(CallbackTemplate template, options: options, cancellationToken: cancellationToken); return result; - }); + }, emoji: KnownEmojis.Ice); if (templateInstallResult.ExitCode != 0) { diff --git a/tests/Aspire.Cli.Tests/Commands/NewCommandTests.cs b/tests/Aspire.Cli.Tests/Commands/NewCommandTests.cs index 9685e5a68f6..c2038e913b5 100644 --- a/tests/Aspire.Cli.Tests/Commands/NewCommandTests.cs +++ b/tests/Aspire.Cli.Tests/Commands/NewCommandTests.cs @@ -1107,6 +1107,70 @@ public async Task NewCommandWithEmptyTemplateAndExplicitTypeScriptLanguageUsesSc Assert.True(scaffoldingInvoked); } + [Fact] + public async Task NewCommandWithEmptyTemplateNormalizesDefaultOutputPath() + { + using var workspace = TemporaryWorkspace.Create(outputHelper); + string? capturedTargetDirectory = null; + + var services = CliTestHelper.CreateServiceCollection(workspace, outputHelper, options => + { + options.NewCommandPrompterFactory = (sp) => + { + var interactionService = sp.GetRequiredService(); + var prompter = new TestNewCommandPrompter(interactionService); + + // Accept the default "./TestApp" path from the prompt + prompter.PromptForOutputPathCallback = (path) => path; + + return prompter; + }; + + options.DotNetCliRunnerFactory = (sp) => + { + var runner = new TestDotNetCliRunner(); + runner.SearchPackagesAsyncCallback = (dir, query, prerelease, take, skip, nugetSource, useCache, options, cancellationToken) => + { + var package = new NuGetPackage() + { + Id = "Aspire.ProjectTemplates", + Source = "nuget", + Version = "9.2.0" + }; + + return (0, new NuGetPackage[] { package }); + }; + + return runner; + }; + }); + + services.AddSingleton(new TestScaffoldingService + { + ScaffoldAsyncCallback = (context, cancellationToken) => + { + capturedTargetDirectory = context.TargetDirectory.FullName; + return Task.CompletedTask; + } + }); + + var provider = services.BuildServiceProvider(); + var command = provider.GetRequiredService(); + // Do not pass --output so the default "./TestApp" path is used via the prompter + var result = command.Parse("new --language typescript aspire-empty --name TestApp --localhost-tld false"); + + var exitCode = await result.InvokeAsync().DefaultTimeout(); + Assert.Equal(0, exitCode); + Assert.NotNull(capturedTargetDirectory); + + // The output path should be properly normalized without "./" segments + Assert.DoesNotContain("./", capturedTargetDirectory); + Assert.DoesNotContain(".\\", capturedTargetDirectory); + + var expectedPath = Path.Combine(workspace.WorkspaceRoot.FullName, "TestApp"); + Assert.Equal(expectedPath, capturedTargetDirectory); + } + [Fact] public async Task NewCommandWithEmptyTemplateAndTypeScriptPromptsForLocalhostTldAndUsesSelection() {