diff --git a/DevProxy/Commands/DevProxyCommand.cs b/DevProxy/Commands/DevProxyCommand.cs index 6ce7ff9f..2fcbea5e 100644 --- a/DevProxy/Commands/DevProxyCommand.cs +++ b/DevProxy/Commands/DevProxyCommand.cs @@ -30,7 +30,7 @@ sealed class DevProxyCommand : RootCommand internal static readonly Option ConfigFileOption = new(ConfigFileOptionName, "-c") { HelpName = "config-file", - Description = "The path to the configuration file" + Description = "Path to config file. If not specified, Dev Proxy searches for devproxyrc.jsonc or devproxyrc.json in the current directory, then in a .devproxy/ directory, then under the ~appFolder location. Supports ~appFolder token." }; internal const string NoFirstRunOptionName = "--no-first-run"; internal const string NoWatchOptionName = "--no-watch"; @@ -574,13 +574,18 @@ private void ConfigureCommand() ]); HelpExamples.Install(this); + CustomizeHelp(); + + SetAction(InvokeAsync); + } + + private void CustomizeHelp() + { var helpOption = Options.OfType().FirstOrDefault(); - if (helpOption?.Action is HelpAction helpAction) + if (helpOption?.Action is SynchronousCommandLineAction currentAction) { - helpOption.Action = new ExitCodeHelpAction(helpAction); + helpOption.Action = new DevProxyHelpAction(currentAction); } - - SetAction(InvokeAsync); } private void ConfigureFromOptions(ParseResult parseResult) diff --git a/DevProxy/Commands/DevProxyHelpAction.cs b/DevProxy/Commands/DevProxyHelpAction.cs new file mode 100644 index 00000000..9f331705 --- /dev/null +++ b/DevProxy/Commands/DevProxyHelpAction.cs @@ -0,0 +1,42 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.CommandLine; +using System.CommandLine.Help; +using System.CommandLine.Invocation; + +namespace DevProxy.Commands; + +sealed class DevProxyHelpAction(SynchronousCommandLineAction originalAction) : SynchronousCommandLineAction +{ + public override int Invoke(ParseResult parseResult) + { + originalAction.Invoke(parseResult); + + if (parseResult.CommandResult.Command is not RootCommand) + { + return 0; + } + + var output = parseResult.Configuration.Output; + + output.WriteLine(); + output.WriteLine(" Additional commands may be available depending on configured plugins."); + output.WriteLine(" Use -c to load a specific configuration."); + output.WriteLine(); + output.WriteLine("Output:"); + output.WriteLine(" Primary output goes to stdout. Errors and diagnostics go to stderr."); + output.WriteLine(" Use --output json for structured output."); + output.WriteLine(); + output.WriteLine("Configuration precedence:"); + output.WriteLine(" CLI flags > config file > defaults"); + output.WriteLine(); + output.WriteLine("Exit codes:"); + output.WriteLine(" 0 Success"); + output.WriteLine(" 1 Runtime error"); + output.WriteLine(" 2 Invalid input or usage"); + + return 0; + } +}