You can add a feature flag functionality with a custom class like:
Custom Class
This class over rides the click.Group.command() method which is used to decorate command functions. It adds the ability to pass an active flag, which when False will skip adding the command to the group.
import click
class FeatureFlagCommand(click.Group):
def command(self, *args, active=True, **kwargs):
"""Behaves the same as `click.Group.command()` except added an
`active` flag which can be used to disable to command.
"""
if active:
return super(FeatureFlagCommand, self).command(*args, **kwargs)
else:
return lambda f: f
Using the Custom Class
By passing the cls parameter to the click.group() decorator, any commands added to the group via the the group.command() will be gated with the active flag.
@click.group(cls=FeatureFlagCommand)
def cli():
...
@cli.command(name='specialfeature', active=FLAG_ENABLED)
def special_feature_command()
...
How does this work?
This works because click is a well designed OO framework. It is easy to inherit from click.Group and build a new command() decorator. In the new command() decorator if the active flag is False we return the undecorated function instead of adding the function to the group.
Test Code:
@click.group(cls=FeatureFlagCommand)
def cli():
"""My Awesome Click Program"""
@cli.command(active=False)
def command1():
click.echo('Command 1')
@cli.command(active=True)
def command2():
click.echo('Command 2')
@cli.command()
def command3():
click.echo('Command 3')
if __name__ == "__main__":
commands = (
'command1',
'command2',
'command3',
'--help',
'',
)
import sys, time
time.sleep(1)
print('Click Version: {}'.format(click.__version__))
print('Python Version: {}'.format(sys.version))
for cmd in commands:
try:
time.sleep(0.1)
print('-----------')
print('> ' + cmd)
time.sleep(0.1)
cli(cmd.split())
except BaseException as exc:
if str(exc) != '0' and \
not isinstance(exc, (click.ClickException, SystemExit)):
raise
Results:
Click Version: 6.7
Python Version: 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)]
-----------
> command1
Usage: test.py [OPTIONS] COMMAND [ARGS]...
Error: No such command "command1".
-----------
> command2
Command 2
-----------
> command3
Command 3
-----------
> --help
Usage: test.py [OPTIONS] COMMAND [ARGS]...
My Awesome Click Program
Options:
--help Show this message and exit.
Commands:
command2
command3
-----------
>
Usage: test.py [OPTIONS] COMMAND [ARGS]...
My Awesome Click Program
Options:
--help Show this message and exit.
Commands:
command2
command3