I would like to make a module that makes it very simple to build click commands that share a lot of options. Those options would be distilled into a single object that is passed into the command. As an illustrative example:
from magic import magic_command
import click
@magic_command('Colored')
@click.option('--color')
def cmd(magic, color):
pass
The total command would then have many --magic-...
options that go into the magic
object passed into cmd
. I was able to achieve that using the following:
def magic_command(name):
def decorator(func):
@click.option('--magic-foo')
@click.option('--magic-bar')
def wrapper(magic_foo, magic_bar, **kwargs):
print(f'initializing Magic with {magic_foo} and {magic_bar}')
magic = Magic(magic_foo, magic_bar)
func(magic, **kwargs)
try:
wrapper.__click_params__.extend(func.__click_params__)
except AttributeError:
pass
return click.command(f'{name}-Magic')(wrapper)
return decorator
However, messing with the __click_params__
doesn't seem particularly clean.
The question is somewhat similar to this one, however this approach does not allow me to condense the many magic options into a magic object.
To elaborate, with this approach I would have to do
@magic_command('Colored')
@click.option('--color')
def cmd(magic_foo, magic_bar, color):
magic = Magic(magic_foo, magic_bar)
pass
But that means the custom code needs to be aware what magic options there are and how to construct the magic. I guess that can be simplified using **kwargs
but still - ideally I'd like to just have a ready magic
object passed to cmd
.