Skip to content

Commit e435fc9

Browse files
committed
fix(cli): use correct exclusive options, add unit test
1 parent a53397d commit e435fc9

File tree

2 files changed

+63
-2
lines changed

2 files changed

+63
-2
lines changed

gitlab/v4/cli.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,9 +284,9 @@ def _populate_sub_parser_by_class(
284284
f"--{x.replace('_', '-')}", required=False
285285
)
286286

287-
if mgr_cls._create_attrs.exclusive:
287+
if mgr_cls._update_attrs.exclusive:
288288
group = sub_parser_action.add_mutually_exclusive_group()
289-
for x in mgr_cls._create_attrs.exclusive:
289+
for x in mgr_cls._update_attrs.exclusive:
290290
group.add_argument(f"--{x.replace('_', '-')}")
291291

292292
if cls.__name__ in cli.custom_actions:

tests/unit/test_cli.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
import gitlab.base
1212
from gitlab import cli
1313
from gitlab.exceptions import GitlabError
14+
from gitlab.mixins import CreateMixin, UpdateMixin
15+
from gitlab.types import RequiredOptional
1416
from gitlab.v4 import cli as v4_cli
1517

1618

@@ -157,6 +159,65 @@ def test_v4_parser():
157159
assert actions["--name"].required
158160

159161

162+
def test_extend_parser():
163+
class ExceptionArgParser(argparse.ArgumentParser):
164+
def error(self, message):
165+
"Raise error instead of exiting on invalid arguments, to make testing easier"
166+
raise ValueError(message)
167+
168+
class Fake:
169+
_id_attr = None
170+
171+
class FakeManager(gitlab.base.RESTManager, CreateMixin, UpdateMixin):
172+
_obj_cls = Fake
173+
_create_attrs = RequiredOptional(
174+
required=("create",),
175+
optional=("opt_create",),
176+
exclusive=("create_a", "create_b"),
177+
)
178+
_update_attrs = RequiredOptional(
179+
required=("update",),
180+
optional=("opt_update",),
181+
exclusive=("update_a", "update_b"),
182+
)
183+
184+
parser = ExceptionArgParser()
185+
with mock.patch.dict(
186+
"gitlab.v4.objects.__dict__", {"FakeManager": FakeManager}, clear=True
187+
):
188+
v4_cli.extend_parser(parser)
189+
190+
assert parser.parse_args(["fake", "create", "--create", "1"])
191+
assert parser.parse_args(["fake", "create", "--create", "1", "--opt-create", "1"])
192+
assert parser.parse_args(["fake", "create", "--create", "1", "--create-a", "1"])
193+
assert parser.parse_args(["fake", "create", "--create", "1", "--create-b", "1"])
194+
195+
with pytest.raises(ValueError):
196+
# missing required "create"
197+
parser.parse_args(["fake", "create", "--opt_create", "1"])
198+
199+
with pytest.raises(ValueError):
200+
# both exclusive options
201+
parser.parse_args(
202+
["fake", "create", "--create", "1", "--create-a", "1", "--create-b", "1"]
203+
)
204+
205+
assert parser.parse_args(["fake", "update", "--update", "1"])
206+
assert parser.parse_args(["fake", "update", "--update", "1", "--opt-update", "1"])
207+
assert parser.parse_args(["fake", "update", "--update", "1", "--update-a", "1"])
208+
assert parser.parse_args(["fake", "update", "--update", "1", "--update-b", "1"])
209+
210+
with pytest.raises(ValueError):
211+
# missing required "update"
212+
parser.parse_args(["fake", "update", "--opt_update", "1"])
213+
214+
with pytest.raises(ValueError):
215+
# both exclusive options
216+
parser.parse_args(
217+
["fake", "update", "--update", "1", "--update-a", "1", "--update-b", "1"]
218+
)
219+
220+
160221
@pytest.mark.skipif(sys.version_info < (3, 8), reason="added in 3.8")
161222
def test_legacy_display_without_fields_warns(fake_object_no_id):
162223
printer = v4_cli.LegacyPrinter()

0 commit comments

Comments
 (0)