Shared options and flags between commands
I have found a simple solution! I slightly edited the snippet from https://github.com/pallets/click/issues/108 :
import click_cmd1_options = [ click.option('--cmd1-opt')]_cmd2_options = [ click.option('--cmd2-opt')]def add_options(options): def _add_options(func): for option in reversed(options): func = option(func) return func return _add_options@click.group()def group(**kwargs): pass@group.command()@add_options(_cmd1_options)def cmd1(**kwargs): print(kwargs)@group.command()@add_options(_cmd2_options)def cmd2(**kwargs): print(kwargs)@group.command()@add_options(_cmd1_options)@add_options(_cmd2_options)@click.option("--cmd3-opt")def cmd3(**kwargs): print(kwargs)if __name__ == '__main__': group()
Define a class with common parameters
class StdCommand(click.core.Command): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.params.insert(0, click.core.Option(('--default-option',), help='Every command should have one'))
Then pass the class to decorator when defining the command function
@click.command(cls=StdCommand)@click.option('--other')def main(default_option, other): ...
This code extracts all the options from it's arguments
def extract_params(*args): from click import Command if len(args) == 0: return [''] if any([ not isinstance(a, Command) for a in args ]): raise TypeError('Handles only Command instances') params = [ p.opts() for cmd_inst in args for p in cmd_inst.params ] return list(set(params))
now you can use it:
@click.command()@click.option(extract_params(cmd1, cmd2))def cmd3(): pass
This code extracts only the parameters and none of their default values, you can improve it if needed.