diff --git a/src/stratis_cli/_parser/_parser.py b/src/stratis_cli/_parser/_parser.py index 7be7294ff..68f7c2269 100644 --- a/src/stratis_cli/_parser/_parser.py +++ b/src/stratis_cli/_parser/_parser.py @@ -33,6 +33,7 @@ from ._logical import LOGICAL_SUBCMDS from ._physical import PHYSICAL_SUBCMDS from ._pool import POOL_SUBCMDS +from ._range import PrintHelpAction def print_help(parser): @@ -213,6 +214,11 @@ def gen_parser(): # version is special, it has explicit support in argparse parser.add_argument("--version", action="version", version=__version__) + # --print-all-help is special because it introspects on the parser + parser.add_argument( + "--print-all-help", action=PrintHelpAction, help=argparse.SUPPRESS, nargs=0 + ) + _add_args(parser, GEN_ARGS) subparsers = parser.add_subparsers(title="subcommands") diff --git a/src/stratis_cli/_parser/_range.py b/src/stratis_cli/_parser/_range.py index c41a5100c..b03c9c2cd 100644 --- a/src/stratis_cli/_parser/_range.py +++ b/src/stratis_cli/_parser/_range.py @@ -18,6 +18,7 @@ # isort: STDLIB import argparse import re +import sys # isort: THIRDPARTY from justbytes import B, GiB, KiB, MiB, PiB, Range, TiB @@ -98,3 +99,35 @@ class DefaultAction(argparse.Action): def __call__(self, parser, namespace, values, option_string=None): setattr(namespace, self.dest, values) setattr(namespace, self.dest + "_default", False) + + +def gen_subparsers(parser, command_line): + """ + Yield all subparser/command_lines pairs for this parser and this prefix + command line. + + :param parser: an argparse parser + :param command_line: a prefix command line + :type command_line: list of str + """ + yield (parser, command_line) + for action in ( + action + for action in parser._actions # pylint: disable=protected-access + if isinstance( + action, argparse._SubParsersAction # pylint: disable=protected-access + ) + ): + for name, subparser in sorted(action.choices.items(), key=lambda x: x[0]): + yield from gen_subparsers(subparser, command_line + [name]) + + +class PrintHelpAction(argparse.Action): + """ + Print the help text for every subcommand. + """ + + def __call__(self, parser, namespace, values, option_string=None): + for subparser, _ in gen_subparsers(parser, []): + subparser.print_help() + sys.exit(0) diff --git a/tests/whitebox/integration/test_help_text.py b/tests/whitebox/integration/test_help_text.py deleted file mode 100644 index fd58994ce..000000000 --- a/tests/whitebox/integration/test_help_text.py +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright 2025 Red Hat, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -""" -Test that printing out help text does not result in any error returns or -exceptions. -""" - -# isort: STDLIB -from argparse import _SubParsersAction - -# isort: LOCAL -from stratis_cli._parser import gen_parser - -from ._misc import RunTestCase - - -def gen_subcommands(parser, command_line): - """ - Recursively traverse the parser, yielding all possible subcommands. - """ - yield command_line - for action in ( - action - for action in parser._actions # pylint: disable=protected-access - if isinstance(action, _SubParsersAction) - ): - for name, subparser in action.choices.items(): - yield from gen_subcommands(subparser, command_line + [name]) - - -class ParserHelpTestCase(RunTestCase): - """ - Test various timeout inputs. - """ - - def test_help(self): - """ - Test all parser help. - """ - - for command_line in gen_subcommands(gen_parser(), []): - self.check_system_exit(command_line + ["--help"], 0) diff --git a/tests/whitebox/integration/test_parser.py b/tests/whitebox/integration/test_parser.py index 7076a5a49..2dc1f8a40 100644 --- a/tests/whitebox/integration/test_parser.py +++ b/tests/whitebox/integration/test_parser.py @@ -15,6 +15,10 @@ Test command-line argument parsing. """ +# isort: STDLIB +from io import StringIO +from unittest import mock + # isort: LOCAL from stratis_cli import StratisCliErrorCodes @@ -432,3 +436,16 @@ def test_stratis_list_default(self): for subcommand in [["pool"], ["filesystem"], ["blockdev"]]: for prefix in [[], ["--propagate"]]: self.assertEqual(RUNNER(prefix + subcommand), 0) + + +class TestAllHelp(RunTestCase): + """ + Verify that --print-all-help option succeeds. + """ + + def test_print_all_help(self): + """ + Test the --print-all-help option. + """ + with mock.patch("sys.stdout", new=StringIO()): + self.check_system_exit(["--print-all-help"], 0)