command-line-api icon indicating copy to clipboard operation
command-line-api copied to clipboard

Support grouping options in help

Open hach-que opened this issue 2 years ago • 3 comments
trafficstars

Currently the options output for my program looks like this:

Description:
  Build an Unreal Engine project or plugin.

Usage:
  uet build [options]

Options:
  -e, --engine <engine>                                        The engine to use for the build. []
  -p, --path <path>                                            The directory path that contains a .uproject file, a .uplugin file, or a BuildConfig.json file. If this parameter isn't provided, defaults to the current working directory. [default: C:\Work\internal
                                                               (BuildConfig.json)]
  -d, --distribution <distribution>                            The distribution to build if targeting a BuildConfig.json file. []
  --shipping                                                   If set, builds for Shipping instead of Development. Only valid when not using a BuildConfig.json file to build.
  -x, --executor <gitlab|local>                                The executor to use. [default: local]
  --executor-output-file <executor-output-file>                If the executor runs the build externally (e.g. a build server), this is the path to the emitted file that should be passed as the job or build description into the build server.
  --windows-shared-storage-path <windows-shared-storage-path>  If the build is running across multiple machines (depending on the executor), this is the network share for Windows machines to access.
  --windows-sdks-path <windows-sdks-path>                      If set, UET will automatically manage and install platform SDKs, and store them in the provided path on Windows machines. This should be a local path; the SDKs will be installed on each machine as they're
                                                               needed.
  --mac-shared-storage-path <mac-shared-storage-path>          If the build is running across multiple machines (depending on the executor), this is the local path on macOS pre-mounted to the network share.
  --mac-sdks-path <mac-sdks-path>                              If set, UET will automatically manage and install platform SDKs, and store them in the provided path on macOS machines. This should be a local path; the SDKs will be installed on each machine as they're
                                                               needed.
  --test                                                       If set, executes the tests after building.
  --deploy                                                     If set, executes the deployment after building (and testing if --test is set).
  --strict-includes                                            If set, disables unity and PCH builds. This forces all files to have the correct #include directives, at the cost of increased build time.
  -?, -h, --help                                               Show help and usage information

I would like to be able to customize the help output by assigning options and arguments to "groups", so that I can get help output like this instead:

Description:
  Build an Unreal Engine project or plugin.

Usage:
  uet build [options]

Options:
  -e, --engine <engine>                                        The engine to use for the build. []
  -p, --path <path>                                            The directory path that contains a .uproject file, a .uplugin file, or a BuildConfig.json file. If this parameter isn't provided, defaults to the current working directory. [default: C:\Work\internal
                                                               (BuildConfig.json)]
  --test                                                       If set, executes the tests after building.
  --deploy                                                     If set, executes the deployment after building (and testing if --test is set).
  --strict-includes                                            If set, disables unity and PCH builds. This forces all files to have the correct #include directives, at the cost of increased build time.
  -?, -h, --help                                               Show help and usage information.

Options when targeting a BuildConfig.json file:
  -d, --distribution <distribution>                            The distribution to build if targeting a BuildConfig.json file. []

Options when targeting a .uplugin or .uproject file:
  --shipping                                                   If set, builds for Shipping instead of Development

Options when building on CI/CD:
  -x, --executor <gitlab|local>                                The executor to use. [default: local]
  --executor-output-file <executor-output-file>                If the executor runs the build externally (e.g. a build server), this is the path to the emitted file that should be passed as the job or build description into the build server.
  --windows-shared-storage-path <windows-shared-storage-path>  If the build is running across multiple machines (depending on the executor), this is the network share for Windows machines to access.
  --windows-sdks-path <windows-sdks-path>                      If set, UET will automatically manage and install platform SDKs, and store them in the provided path on Windows machines. This should be a local path; the SDKs will be installed on each machine as they're
                                                               needed.
  --mac-shared-storage-path <mac-shared-storage-path>          If the build is running across multiple machines (depending on the executor), this is the local path on macOS pre-mounted to the network share.
  --mac-sdks-path <mac-sdks-path>                              If set, UET will automatically manage and install platform SDKs, and store them in the provided path on macOS machines. This should be a local path; the SDKs will be installed on each machine as they're
                                                               needed.

I tried to customize the options output through HelpBuilder, but ran into the problem mentioned in #2215 where it uses a bunch of internals that are not accessible:

image

hach-que avatar Jun 09 '23 03:06 hach-que

You can copy over the ParentNode class and then use:

ParentNode? parent = new ParentNode(current.Parents.FirstOrDefault());

The IsGlobal in the latest build isn't there anymore, using this now:

                     if (option is { Recursive: true, Hidden: false })
                                    {
                                        if (option is not HelpOption || !addedHelpOption)
                                        {
                                            optionRows.Add(this.GetTwoColumnRow(option, ctx));
                                        }
                                    }

I just copied over the WriteHeading functionality to use it.

For WasSectionSkipped I'm still working out a way to handle it, current thoughts are having my own List of skipped sections that I add to since I can't use the WasSectionSkipped in the help context.

seanadams9 avatar Jun 09 '23 15:06 seanadams9

I ended up forking System.CommandLine and added an ArgumentGroupName to options. It can be downloaded here: https://www.nuget.org/packages/Redpoint.ThirdParty.System.CommandLine

hach-que avatar Jul 13 '23 05:07 hach-que