Repository: python-gitlab/python-gitlab

Issue:
Bogus } in usage
## Description of the problem, including code/CLI snippet

```
✖ gitlab event -h
usage: gitlab event [-h] {list} ...

options:
  -h, --help  show this help message and exit

action:
  list}      Action to execute on the GitLab resource.
```


## Expected Behavior

There should be `list`

## Actual Behavior

There is `list}`

## Specifications

  - python-gitlab version: 3.15.0
  - API version you are using (v3/v4): None
  - Gitlab server version (or gitlab.com): None

Bogus } in usage
## Description of the problem, including code/CLI snippet

```
✖ gitlab event -h
usage: gitlab event [-h] {list} ...

options:
  -h, --help  show this help message and exit

action:
  list}      Action to execute on the GitLab resource.
```


## Expected Behavior

There should be `list`

## Actual Behavior

There is `list}`

## Specifications

  - python-gitlab version: 3.15.0
  - API version you are using (v3/v4): None
  - Gitlab server version (or gitlab.com): None



Discussion:

Resolving patch:
diff --git a/gitlab/cli.py b/gitlab/cli.py
--- a/gitlab/cli.py
+++ b/gitlab/cli.py
@@ -3,6 +3,7 @@
 import os
 import re
 import sys
+import textwrap
 from types import ModuleType
 from typing import (
     Any,
@@ -50,11 +51,21 @@ def format_help(self) -> str:
         for line in result.splitlines(keepends=True):
             # All of our resources are on one line and wrapped inside braces.
             # For example: {application,resource1,resource2}
+            # except if there are fewer resources - then the line and help text
+            # are collapsed on the same line.
+            # For example:  {list}      Action to execute on the GitLab resource.
             # We then put each resource on its own line to make it easier to read.
             if line.strip().startswith("{"):
-                choices = line.strip().strip("{}").split(",")
-                choices_str = f"\n{indent}".join(choices)
-                line = f"{indent}{choices_str}\n"
+                choice_string, help_string = line.split("}", 1)
+                choice_list = choice_string.strip(" {").split(",")
+                help_string = help_string.strip()
+
+                if help_string:
+                    help_indent = len(max(choice_list, key=len)) * " "
+                    choice_list.append(f"{help_indent} {help_string}")
+
+                choices = "\n".join(choice_list)
+                line = f"{textwrap.indent(choices, indent)}\n"
             output += line
         return output
 


Test patch:
diff --git a/tests/functional/cli/test_cli.py b/tests/functional/cli/test_cli.py
--- a/tests/functional/cli/test_cli.py
+++ b/tests/functional/cli/test_cli.py
@@ -46,6 +46,12 @@ def test_resource_help_prints_actions_vertically(script_runner):
     assert ret.returncode == 0
 
 
+def test_resource_help_prints_actions_vertically_only_one_action(script_runner):
+    ret = script_runner.run(["gitlab", "event", "--help"])
+    assert """action:\n  list\n""" in ret.stdout
+    assert ret.returncode == 0
+
+
 @pytest.mark.script_launch_mode("inprocess")
 @responses.activate
 def test_defaults_to_gitlab_com(script_runner, resp_get_project, monkeypatch):