| File: Commands\ApiSearchCommand.cs | Web Access |
| Project: src\src\Aspire.Cli\Aspire.Cli.csproj (aspire) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.CommandLine; using System.Globalization; using System.Text.Json; using Aspire.Cli.Documentation.ApiDocs; using Aspire.Cli.Interaction; using Aspire.Cli.Resources; using Aspire.Cli.Utils; using Spectre.Console; namespace Aspire.Cli.Commands; /// <summary> /// Command to search Aspire API reference documentation. /// </summary> internal sealed class ApiSearchCommand : BaseCommand { private readonly IApiDocsIndexService _apiDocsIndexService; private static readonly Argument<string> s_queryArgument = new("query") { Description = ApiCommandStrings.QueryArgumentDescription }; private static readonly Option<string?> s_languageOption = new Option<string?>("--language") { Description = ApiCommandStrings.LanguageOptionDescription }; private static readonly Option<OutputFormat> s_formatOption = new("--format") { Description = ApiCommandStrings.FormatOptionDescription }; private static readonly Option<int?> s_limitOption = new("--limit", "-n") { Description = ApiCommandStrings.LimitOptionDescription }; /// <summary> /// Initializes a new instance of the <see cref="ApiSearchCommand"/> class. /// </summary> /// <param name="apiDocsIndexService">The API docs index service.</param> /// <param name="services">Common command services.</param> public ApiSearchCommand( IApiDocsIndexService apiDocsIndexService, CommonCommandServices services) : base("search", ApiCommandStrings.SearchDescription, services) { _apiDocsIndexService = apiDocsIndexService; Arguments.Add(s_queryArgument); Options.Add(s_languageOption); Options.Add(s_formatOption); Options.Add(s_limitOption); } protected override async Task<CommandResult> ExecuteAsync(ParseResult parseResult, CancellationToken cancellationToken) { using var activity = Telemetry.StartDiagnosticActivity(Name); var query = parseResult.GetValue(s_queryArgument)!; var language = parseResult.GetValue(s_languageOption); var format = parseResult.GetValue(s_formatOption); var limit = Math.Clamp(parseResult.GetValue(s_limitOption) ?? 5, 1, 10); var items = await InteractionService.ShowStatusAsync( ApiCommandStrings.LoadingApiDocumentation, async () => await _apiDocsIndexService.SearchAsync(query, language, limit, cancellationToken)); if (items.Count is 0) { InteractionService.DisplayError(string.Format(CultureInfo.CurrentCulture, ApiCommandStrings.NoResultsFound, query)); return CommandResult.Success(); } if (format is OutputFormat.Json) { var json = JsonSerializer.Serialize([.. items], JsonSourceGenerationContext.RelaxedEscaping.ApiSearchResultArray); InteractionService.DisplayRawText(json, ConsoleOutput.Standard); return CommandResult.Success(); } InteractionService.DisplaySuccess(string.Format(CultureInfo.CurrentCulture, ApiCommandStrings.FoundSearchResults, items.Count, query)); var table = new Table(); table.AddBoldColumn(ApiCommandStrings.HeaderName); table.AddBoldColumn(ApiCommandStrings.HeaderId); table.AddBoldColumn(ApiCommandStrings.HeaderLanguage); table.AddBoldColumn(ApiCommandStrings.HeaderKind); table.AddBoldColumn(ApiCommandStrings.HeaderScore); foreach (var item in items) { table.AddRow( Markup.Escape(item.Name), Markup.Escape(item.Id), Markup.Escape(item.Language), Markup.Escape(item.Kind), item.Score.ToString("F2", CultureInfo.InvariantCulture)); } InteractionService.DisplayRenderable(table); return CommandResult.Success(); } }