10000 fix: add ability to add help to custom_actions · mschoettle/python-gitlab@9acd2d2 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9acd2d2

Browse files
JohnVillalovosnejch
authored andcommitted
fix: add ability to add help to custom_actions
Now when registering a custom_action can add help text if desired. Also delete the VerticalHelpFormatter as no longer needed. When the help value is set to `None` or some other value, the actions will get printed vertically. Before when the help value was not set the actions would all get put onto one line.
1 parent 18aa1fc commit 9acd2d2

File tree

3 files changed

+12
-34
lines changed

3 files changed

+12
-34
lines changed

gitlab/cli.py

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import pathlib
66
import re
77
import sys
8-
import textwrap
98
from types import ModuleType
109
from typing import (
1110
Any,
@@ -37,11 +36,12 @@ class CustomAction:
3736
optional: Tuple[str, ...]
3837
in_object: bool
3938
requires_id: bool # if the `_id_attr` value should be a required argument
39+
help: Optional[str] # help text for the custom action
4040

4141

4242
# custom_actions = {
4343
# cls: {
44-
# action: (mandatory_args, optional_args, in_obj),
44+
# action: CustomAction,
4545
# },
4646
# }
4747
custom_actions: Dict[str, Dict[str, CustomAction]] = {}
@@ -54,40 +54,14 @@ class CustomAction:
5454
__F = TypeVar("__F", bound=Callable[..., Any])
5555

5656

57-
class VerticalHelpFormatter(argparse.HelpFormatter):
58-
def format_help(self) -> str:
59-
result = super().format_help()
60-
output = ""
61-
indent = self._indent_increment * " "
62-
for line in result.splitlines(keepends=True):
63-
# All of our resources are on one line and wrapped inside braces.
64-
# For example: {application,resource1,resource2}
65-
# except if there are fewer resources - then the line and help text
66-
# are collapsed on the same line.
67-
# For example: {list} Action to execute on the GitLab resource.
68-
# We then put each resource on its own line to make it easier to read.
69-
if line.strip().startswith("{"):
70-
choice_string, help_string = line.split("}", 1)
71-
choice_list = choice_string.strip(" {").split(",")
72-
help_string = help_string.strip()
73-
74-
if help_string:
75-
help_indent = len(max(choice_list, key=len)) * " "
76-
choice_list.append(f"{help_indent} {help_string}")
77-
78-
choices = "\n".join(choice_list)
79-
line = f"{textwrap.indent(choices, indent)}\n"
80-
output += line
81-
return output
82-
83-
8457
def register_custom_action(
8558
*,
8659
cls_names: Union[str, Tuple[str, ...]],
8760
required: Tuple[str, ...] = (),
8861
optional: Tuple[str, ...] = (),
8962
custom_action: Optional[str] = None,
9063
requires_id: bool = True, # if the `_id_attr` value should be a required argument
64+
help: Optional[str] = None, # help text for the action
9165
) -> Callable[[__F], __F]:
9266
def wrap(f: __F) -> __F:
9367
@functools.wraps(f)
@@ -115,6 +89,7 @@ def wrapped_f(*args: Any, **kwargs: Any) -> Any:
11589
optional=optional,
11690
in_object=in_obj,
11791
requires_id=requires_id,
92+
help=help,
11893
)
11994

12095
return cast(__F, wrapped_f)

gitlab/v4/cli.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -300,11 +300,14 @@ def _populate_sub_parser_by_class(
300300
if cls.__name__ in cli.custom_actions:
301301
name = cls.__name__
302302
for action_name in cli.custom_actions[name]:
303+
custom_action = cli.custom_actions[name][action_name]
303304
# NOTE(jlvillal): If we put a function for the `default` value of
304305
# the `get` it will always get called, which will break things.
305306
action_parser = action_parsers.get(action_name)
306307
if action_parser is None:
307-
sub_parser_action = sub_parser.add_parser(action_name)
308+
sub_parser_action = sub_parser.add_parser(
309+
action_name, help=custom_action.help
310+
)
308311
else:
309312
sub_parser_action = action_parser
310313
# Get the attributes for URL/path construction
@@ -315,7 +318,6 @@ def _populate_sub_parser_by_class(
315318
)
316319
sub_parser_action.add_argument("--sudo", required=False)
317320

318-
custom_action = cli.custom_actions[name][action_name]
319321
# We need to get the object somehow
320322
if not issubclass(cls, gitlab.mixins.GetWithoutIdMixin):
321323
if cls._id_attr is not None and custom_action.requires_id:
@@ -386,7 +388,6 @@ def extend_parser(parser: argparse.ArgumentParser) -> argparse.ArgumentParser:
386388
mgr_cls = getattr(gitlab.v4.objects, mgr_cls_name)
387389
object_group = subparsers.add_parser(
388390
arg_name,
389-
formatter_class=cli.VerticalHelpFormatter,
390391
help=f"API endpoint: {mgr_cls._path}",
391392
)
392393

tests/functional/cli/test_cli.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,15 @@ def test_config_error_with_help_prints_help(script_runner):
3636

3737
def test_resource_help_prints_actions_vertically(script_runner):
3838
ret = script_runner.run(["gitlab", "project", "--help"])
39-
assert """action:\n list\n get""" in ret.stdout
39+
assert " list List the GitLab resources\n" in ret.stdout
40+
assert " get Get a GitLab resource\n" in ret.stdout
4041
assert ret.returncode == 0
4142

4243

4344
def test_resource_help_prints_actions_vertically_only_one_action(script_runner):
4445
ret = script_runner.run(["gitlab", "event", "--help"])
45-
assert """action:\n list\n""" in ret.stdout
46+
assert " {list} Action to execute on the GitLab resource.\n"
47+
assert " list List the GitLab resources\n" in ret.stdout
4648
assert ret.returncode == 0
4749

4850

0 commit comments

Comments
 (0)
0