diff options
author | Armin Ronacher <armin.ronacher@active-4.com> | 2015-09-15 16:46:29 -0700 |
---|---|---|
committer | Armin Ronacher <armin.ronacher@active-4.com> | 2015-09-15 16:46:29 -0700 |
commit | 5620b05385c3bdaeac0f0347fd2373ae1479624c (patch) | |
tree | 7ae58099e571fe21cddfc0a8eaecd3aeea214074 | |
parent | c4c9eb23243174cd1ffc9fd0162caf31e93b49ee (diff) | |
download | click-5620b05385c3bdaeac0f0347fd2373ae1479624c.tar.gz |
We're not rejecting multi commands below chained multi commands. This fixes #415
-rw-r--r-- | CHANGES | 3 | ||||
-rw-r--r-- | click/core.py | 22 | ||||
-rw-r--r-- | docs/commands.rst | 3 |
3 files changed, 27 insertions, 1 deletions
@@ -10,6 +10,9 @@ Version 6.0 - Optimized the progressbar rendering to not render when it did not actually change. +- Actively reject multi commands within chained multi commands. This + cannot be supported with the current setup of how the invocation for + subcommands works. Version 5.1 ----------- diff --git a/click/core.py b/click/core.py index b3b51c4..e4aaca9 100644 --- a/click/core.py +++ b/click/core.py @@ -37,6 +37,25 @@ def _bashcomplete(cmd, prog_name, complete_var=None): sys.exit(1) +def _check_multicommand(base_command, cmd_name, cmd, register=False): + if not base_command.chain or not isinstance(cmd, MultiCommand): + return + if register: + hint = 'It is not possible to add multi commands as children to ' \ + 'another multi command that is in chain mode' + else: + hint = 'Found a multi command as subcommand to a multi command ' \ + 'that is in chain mode. This is not supported' + raise RuntimeError('%s. Command "%s" is set to chain and "%s" was ' + 'added as subcommand but it in itself is a ' + 'multi command. ("%s" is a %s within a chained ' + '%s named "%s")' % ( + hint, base_command.name, cmd_name, + cmd_name, cmd.__class__.__name__, + base_command.__class__.__name__, + base_command.name)) + + def batch(iterable, batch_size): return list(zip(*repeat(iter(iterable), batch_size))) @@ -1111,6 +1130,7 @@ class Group(MultiCommand): name = name or cmd.name if name is None: raise TypeError('Command has no name.') + _check_multicommand(self, name, cmd, register=True) self.commands[name] = cmd def command(self, *args, **kwargs): @@ -1163,6 +1183,8 @@ class CommandCollection(MultiCommand): def get_command(self, ctx, cmd_name): for source in self.sources: rv = source.get_command(ctx, cmd_name) + if self.chain: + _check_multicommand(self, cmd_name, rv) if rv is not None: return rv diff --git a/docs/commands.rst b/docs/commands.rst index 642f873..157d004 100644 --- a/docs/commands.rst +++ b/docs/commands.rst @@ -310,7 +310,8 @@ Now you can invoke it like this: invoke(cli, prog_name='setup.py', args=['sdist', 'bdist_wheel']) When using multi command chaining you can only have one command (the last) -use ``nargs=-1`` on an argument. Other than that there are no +use ``nargs=-1`` on an argument. It is also not possible to nest multi +commands below chained multicommands. Other than that there are no restrictions on how they work. They can accept options and arguments as normal. |