| File: Commands\ResourceCommandHelpParser.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; namespace Aspire.Cli.Commands; internal sealed record ResourceCommandHelpRequest(string ResourceName, string CommandName, FileInfo? AppHostProjectFile); internal static class ResourceCommandHelpParser { public static ResourceCommandHelpRequest? Parse( ParseResult parseResult, Argument<string> resourceArgument, Argument<string> commandArgument, OptionWithLegacy<FileInfo?> appHostOption) { // Command-specific help is only available when both the resource and command were parsed: // aspire resource web wait-for-browser --help // aspire resource web wait-for-browser --apphost ./AppHost.csproj --help // aspire resource web wait-for-browser --project ./AppHost.csproj --help // // Generic help is intentionally ignored here and falls back to System.CommandLine: // aspire resource --help // aspire resource web --help var resourceName = GetArgumentValue(parseResult, resourceArgument); var commandName = GetArgumentValue(parseResult, commandArgument); var appHostOptionValue = GetOptionTokenValue(parseResult, appHostOption.InnerOption) ?? GetOptionTokenValue(parseResult, appHostOption.LegacyOption); // Only intercept help when the resource and command tokens are real positional arguments. Resource-only help, // option tokens, and option values that System.CommandLine bound into the command argument should fall back to // the default/resource-scoped help paths instead of being treated as command-specific help. // Examples: // aspire resource web --help // aspire resource web --apphost ./AppHost.csproj --help // aspire resource web -- --message hi --help if (string.IsNullOrEmpty(resourceName) || IsOptionLikeToken(resourceName) || string.IsNullOrEmpty(commandName) || IsOptionLikeToken(commandName) || string.Equals(commandName, appHostOptionValue, StringComparison.Ordinal)) { return null; } return new ResourceCommandHelpRequest( resourceName, commandName, appHostOptionValue is null ? null : new FileInfo(appHostOptionValue)); } private static string? GetArgumentValue(ParseResult parseResult, Argument<string> argument) { var result = parseResult.GetResult(argument); return result?.Tokens.Count > 0 ? result.Tokens[0].Value : null; } private static string? GetOptionTokenValue(ParseResult parseResult, Option<FileInfo?> option) { var result = parseResult.GetResult(option); return result?.Tokens.Count > 0 ? result.Tokens[0].Value : null; } private static bool IsOptionLikeToken(string value) { return value.StartsWith("-", StringComparison.Ordinal); } }