命令之间共享选项和标志

问题描述 投票:14回答:3

假设我的CLI工具有三个命令。cmd1, cmd2, cmd3

而我想 cmd3 有相同的选项和标志 cmd1cmd2. 就像某种继承。

@click.command()
@click.options("--verbose")
def cmd1():
    pass

@click.command()
@click.options("--directory")
def cmd2():
    pass

@click.command()
@click.inherit(cmd1, cmd2) # HYPOTHETICAL
def cmd3():
    pass

所以... cmd3 会有旗帜 --verbose 和选项 --directory. 能否用Click做这个?也许我只是忽略了文档中的一些内容......

EDIT.我知道我可以用Click来做这个。 我知道我可以用 click.group(). 但是,所有组的选项必须在组的命令之前指定。我希望所有的选项都在命令之后。

cli.py --verbose --directory /tmp cmd3 -&gt.如果我的CLI实用程序有三个命令:cmd1,cmd2,cmd3,我想让所有的选项都在命令之后。cli.py cmd3 --verbose --directory /tmp

python command-line-interface python-click
3个回答
20
投票

我已经找到了简单的解决方案 我稍微编辑了一下 https:/github.compalletsclickissues108 :

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()

6
投票

定义一个具有共同参数的类

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

然后在定义命令函数时将该类传递给 decorator

@click.command(cls=StdCommand)
@click.option('--other')
def main(default_option, other):
  ...

2
投票

这段代码从它的参数中提取出所有的选项。

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

现在你可以使用它了。

@click.command()
@click.option(extract_params(cmd1, cmd2))
def cmd3():
    pass

这段代码只提取了参数,没有提取默认值,如果需要的话,你可以改进它。

© www.soinside.com 2019 - 2024. All rights reserved.