Skip to content Skip to sidebar Skip to footer

Shared Options And Flags Between Commands

Say my CLI utility has three commands: cmd1, cmd2, cmd3 And I want cmd3 to have same options and flags as cmd1 and cmd2. Like some sort of inheritance. @click.command() @click.opti

Solution 1:

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')
]


defadd_options(options):
    def_add_options(func):
        for option inreversed(options):
            func = option(func)
        return func
    return _add_options


@click.group()defgroup(**kwargs):
    pass@group.command()@add_options(_cmd1_options)defcmd1(**kwargs):
    print(kwargs)


@group.command()@add_options(_cmd2_options)defcmd2(**kwargs):
    print(kwargs)


@group.command()@add_options(_cmd1_options)@add_options(_cmd2_options)@click.option("--cmd3-opt")defcmd3(**kwargs):
    print(kwargs)


if __name__ == '__main__':
    group()

Solution 2:

Define a class with common parameters

classStdCommand(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):
  ...

Solution 3:

This code extracts all the options from it's arguments

defextract_params(*args):
    from click import Command
    iflen(args) == 0:
        return ['']
    ifany([ notisinstance(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 ]
    returnlist(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.

Solution 4:

You could also have another decorator for shared options. I found this solution here

defcommon_params(func):
    @click.option('--foo')    @click.option('--bar')    @functools.wraps(func)defwrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapper


@click.command()@common_params@click.option('--baz')defcli(foo, bar, baz):
    print(foo, bar, baz)

Post a Comment for "Shared Options And Flags Between Commands"