diff --git a/osc_lib/tests/utils/test_tags.py b/osc_lib/tests/utils/test_tags.py index 9446b34..5bdbc13 100644 --- a/osc_lib/tests/utils/test_tags.py +++ b/osc_lib/tests/utils/test_tags.py @@ -19,6 +19,11 @@ from osc_lib.tests import utils as test_utils from osc_lib.utils import tags +def help_enhancer(_h): + """A simple helper to validate the ``enhance_help`` kwarg.""" + return ''.join(reversed(_h)) + + class TestTags(test_utils.TestCase): def test_add_tag_filtering_option_to_parser(self): @@ -169,3 +174,134 @@ class TestTags(test_utils.TestCase): tags.update_tags_for_unset(mock_client, mock_obj, mock_parsed_args) mock_client.set_tags.assert_called_once_with( mock_obj, ['tag1']) + + +class TestTagHelps(test_utils.TestCase): + + def _test_tag_method_help(self, meth, exp_normal, exp_enhanced): + """Vet the help text of the options added by the tag filtering helpers. + + :param meth: One of the ``add_tag_*`` methods. + :param exp_normal: Expected help output without ``enhance_help``. + :param exp_enhanced: Expected output with ``enhance_help`` set to + ``help_enhancer`` + """ + parser = argparse.ArgumentParser() + meth(parser, 'test') + self.assertEqual(exp_normal, parser.format_help()) + + parser = argparse.ArgumentParser() + meth(parser, 'test', enhance_help=help_enhancer) + self.assertEqual(exp_enhanced, parser.format_help()) + + def test_add_tag_filtering_option_to_parser(self): + self._test_tag_method_help( + tags.add_tag_filtering_option_to_parser, + """\ +usage: run.py [-h] [--tags [,,...]] [--any-tags [,,...]] + [--not-tags [,,...]] + [--not-any-tags [,,...]] + +optional arguments: + -h, --help show this help message and exit + --tags [,,...] + List test which have all given tag(s) (Comma-separated + list of tags) + --any-tags [,,...] + List test which have any given tag(s) (Comma-separated + list of tags) + --not-tags [,,...] + Exclude test which have all given tag(s) (Comma- + separated list of tags) + --not-any-tags [,,...] + Exclude test which have any given tag(s) (Comma- + separated list of tags) +""", + """\ +usage: run.py [-h] [--tags [,,...]] [--any-tags [,,...]] + [--not-tags [,,...]] + [--not-any-tags [,,...]] + +optional arguments: + -h, --help show this help message and exit + --tags [,,...] + )sgat fo tsil detarapes-ammoC( )s(gat nevig lla evah + hcihw tset tsiL + --any-tags [,,...] + )sgat fo tsil detarapes-ammoC( )s(gat nevig yna evah + hcihw tset tsiL + --not-tags [,,...] + )sgat fo tsil detarapes-ammoC( )s(gat nevig lla evah + hcihw tset edulcxE + --not-any-tags [,,...] + )sgat fo tsil detarapes-ammoC( )s(gat nevig yna evah + hcihw tset edulcxE +""") + + def test_add_tag_option_to_parser_for_create(self): + self._test_tag_method_help( + tags.add_tag_option_to_parser_for_create, + """\ +usage: run.py [-h] [--tag | --no-tag] + +optional arguments: + -h, --help show this help message and exit + --tag Tag to be added to the test (repeat option to set multiple + tags) + --no-tag No tags associated with the test +""", + """\ +usage: run.py [-h] [--tag | --no-tag] + +optional arguments: + -h, --help show this help message and exit + --tag )sgat elpitlum tes ot noitpo taeper( tset eht ot dedda eb ot + gaT + --no-tag tset eht htiw detaicossa sgat oN +""") + + def test_add_tag_option_to_parser_for_set(self): + self._test_tag_method_help( + tags.add_tag_option_to_parser_for_set, + """\ +usage: run.py [-h] [--tag ] [--no-tag] + +optional arguments: + -h, --help show this help message and exit + --tag Tag to be added to the test (repeat option to set multiple + tags) + --no-tag Clear tags associated with the test. Specify both --tag and + --no-tag to overwrite current tags +""", + """\ +usage: run.py [-h] [--tag ] [--no-tag] + +optional arguments: + -h, --help show this help message and exit + --tag )sgat elpitlum tes ot noitpo taeper( tset eht ot dedda eb ot + gaT + --no-tag sgat tnerruc etirwrevo ot gat-on-- dna gat-- htob yficepS .tset + eht htiw detaicossa sgat raelC +""") + + def test_add_tag_option_to_parser_for_unset(self): + self._test_tag_method_help( + tags.add_tag_option_to_parser_for_unset, + """\ +usage: run.py [-h] [--tag | --all-tag] + +optional arguments: + -h, --help show this help message and exit + --tag Tag to be removed from the test (repeat option to remove + multiple tags) + --all-tag Clear all tags associated with the test +""", + """\ +usage: run.py [-h] [--tag | --all-tag] + +optional arguments: + -h, --help show this help message and exit + --tag )sgat elpitlum evomer ot noitpo taeper( tset eht morf devomer + eb ot gaT + --all-tag tset eht htiw detaicossa sgat lla raelC +""") diff --git a/osc_lib/utils/tags.py b/osc_lib/utils/tags.py index ce382b4..eb67945 100644 --- a/osc_lib/utils/tags.py +++ b/osc_lib/utils/tags.py @@ -22,39 +22,49 @@ class _CommaListAction(argparse.Action): setattr(namespace, self.dest, values.split(',')) -def add_tag_filtering_option_to_parser(parser, resource_name): +def add_tag_filtering_option_to_parser( + parser, resource_name, enhance_help=lambda _h: _h): """Add tag filtering options to a parser. :param parser: argparse.Argument parser object. :param resource_name: Description of the object being filtered. + :param enhance_help: A callable accepting a single parameter, the + (translated) help string, and returning a (translated) help string. May + be used by a caller wishing to add qualifying text, such as "Applies to + version XYZ only", to the help strings for all options produced by this + method. """ parser.add_argument( '--tags', metavar='[,,...]', action=_CommaListAction, - help=_('List %s which have all given tag(s) ' - '(Comma-separated list of tags)') % resource_name + help=enhance_help( + _('List %s which have all given tag(s) ' + '(Comma-separated list of tags)') % resource_name) ) parser.add_argument( '--any-tags', metavar='[,,...]', action=_CommaListAction, - help=_('List %s which have any given tag(s) ' - '(Comma-separated list of tags)') % resource_name + help=enhance_help( + _('List %s which have any given tag(s) ' + '(Comma-separated list of tags)') % resource_name) ) parser.add_argument( '--not-tags', metavar='[,,...]', action=_CommaListAction, - help=_('Exclude %s which have all given tag(s) ' - '(Comma-separated list of tags)') % resource_name + help=enhance_help( + _('Exclude %s which have all given tag(s) ' + '(Comma-separated list of tags)') % resource_name) ) parser.add_argument( '--not-any-tags', metavar='[,,...]', action=_CommaListAction, - help=_('Exclude %s which have any given tag(s) ' - '(Comma-separated list of tags)') % resource_name + help=enhance_help( + _('Exclude %s which have any given tag(s) ' + '(Comma-separated list of tags)') % resource_name) ) @@ -77,11 +87,17 @@ def get_tag_filtering_args(parsed_args, args): args['not_any_tags'] = ','.join(parsed_args.not_any_tags) -def add_tag_option_to_parser_for_create(parser, resource_name): +def add_tag_option_to_parser_for_create( + parser, resource_name, enhance_help=lambda _h: _h): """Add tag options to a parser for create commands. :param parser: argparse.Argument parser object. :param resource_name: Description of the object being filtered. + :param enhance_help: A callable accepting a single parameter, the + (translated) help string, and returning a (translated) help string. May + be used by a caller wishing to add qualifying text, such as "Applies to + version XYZ only", to the help strings for all options produced by this + method. """ tag_group = parser.add_mutually_exclusive_group() tag_group.add_argument( @@ -89,43 +105,58 @@ def add_tag_option_to_parser_for_create(parser, resource_name): action='append', dest='tags', metavar='', - help=_("Tag to be added to the %s " - "(repeat option to set multiple tags)") % resource_name + help=enhance_help( + _("Tag to be added to the %s " + "(repeat option to set multiple tags)") % resource_name) ) tag_group.add_argument( '--no-tag', action='store_true', - help=_("No tags associated with the %s") % resource_name + help=enhance_help(_("No tags associated with the %s") % resource_name) ) -def add_tag_option_to_parser_for_set(parser, resource_name): +def add_tag_option_to_parser_for_set( + parser, resource_name, enhance_help=lambda _h: _h): """Add tag options to a parser for set commands. :param parser: argparse.Argument parser object. :param resource_name: Description of the object being filtered. + :param enhance_help: A callable accepting a single parameter, the + (translated) help string, and returning a (translated) help string. May + be used by a caller wishing to add qualifying text, such as "Applies to + version XYZ only", to the help strings for all options produced by this + method. """ parser.add_argument( '--tag', action='append', dest='tags', metavar='', - help=_("Tag to be added to the %s " - "(repeat option to set multiple tags)") % resource_name + help=enhance_help( + _("Tag to be added to the %s " + "(repeat option to set multiple tags)") % resource_name) ) parser.add_argument( '--no-tag', action='store_true', - help=_("Clear tags associated with the %s. Specify both " - "--tag and --no-tag to overwrite current tags") % resource_name + help=enhance_help( + _("Clear tags associated with the %s. Specify both " + "--tag and --no-tag to overwrite current tags") % resource_name) ) -def add_tag_option_to_parser_for_unset(parser, resource_name): +def add_tag_option_to_parser_for_unset( + parser, resource_name, enhance_help=lambda _h: _h): """Add tag options to a parser for set commands. :param parser: argparse.Argument parser object. :param resource_name: Description of the object being filtered. + :param enhance_help: A callable accepting a single parameter, the + (translated) help string, and returning a (translated) help string. May + be used by a caller wishing to add qualifying text, such as "Applies to + version XYZ only", to the help strings for all options produced by this + method. """ tag_group = parser.add_mutually_exclusive_group() tag_group.add_argument( @@ -133,12 +164,14 @@ def add_tag_option_to_parser_for_unset(parser, resource_name): action='append', dest='tags', metavar='', - help=_("Tag to be removed from the %s " - "(repeat option to remove multiple tags)") % resource_name) + help=enhance_help( + _("Tag to be removed from the %s " + "(repeat option to remove multiple tags)") % resource_name)) tag_group.add_argument( '--all-tag', action='store_true', - help=_("Clear all tags associated with the %s") % resource_name) + help=enhance_help( + _("Clear all tags associated with the %s") % resource_name)) def update_tags_for_set(client, obj, parsed_args):