Shared options and flags between commands Shared options and flags between commands python python

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.