Python 具有单击命令别名的常规用法输出
我将此代码段用于我的自定义组(从),以允许使用前缀Python 具有单击命令别名的常规用法输出,python,click,command-line-interface,Python,Click,Command Line Interface,我将此代码段用于我的自定义组(从),以允许使用前缀 class AliasedGroup(click.Group): def get_command(self, ctx, cmd_name): rv = click.Group.get_command(self, ctx, cmd_name) if rv is not None: return rv matches = [x for x in self.list_co
class AliasedGroup(click.Group):
def get_command(self, ctx, cmd_name):
rv = click.Group.get_command(self, ctx, cmd_name)
if rv is not None:
return rv
matches = [x for x in self.list_commands(ctx)
if x.startswith(cmd_name)]
if not matches:
return None
elif len(matches) == 1:
return click.Group.get_command(self, ctx, matches[0])
ctx.fail('Too many matches: %s' % ', '.join(sorted(matches)))
但是,使用情况输出变得非常愚蠢:它显示命令的前缀,而不是完全显示它们:
用法:test_core a c[选项]
我想看看
用法:测试核心添加组合[选项]
甚至当我调用test\u core a c-h
时
我已经调查过了,但似乎没有明显的解决办法。格式化程序逻辑不知道它们的原始名称。可能可以重写MultiCommand.resolve_命令
,以处理重写版本的MultiCommand/Group.get_命令
,该命令还返回原始命令名。但这可能会破坏一些东西,也许有更简单的方法
完整代码:
import click
class AliasedGroup(click.Group):
def get_command(self, ctx, cmd_name):
rv = click.Group.get_command(self, ctx, cmd_name)
if rv is not None:
return rv
matches = [x for x in self.list_commands(ctx)
if x.startswith(cmd_name)]
if not matches:
return None
elif len(matches) == 1:
return click.Group.get_command(self, ctx, matches[0])
ctx.fail('Too many matches: %s' % ', '.join(sorted(matches)))
@click.group(cls=AliasedGroup, context_settings={'help_option_names': ['-h', '--help']})
def cli():
pass
@cli.group(cls=AliasedGroup)
def add():
pass
@add.command()
@click.option('--yarr')
def combined():
pass
cli(['a', 'c', '-h'], prog_name='test_core')
您需要跟踪使用的别名 别名保留在全局变量中,因为
click
使用了大量上下文实例
您需要实现自己的HelpFormatter。这涵盖了帮助构造的所有用途
在write\u用法中
将别名替换为完整的命令名。作为test\u core add auto-h
的命令,跟踪填充的别名,以覆盖test\u core a-h
的情况。如果在prog
中找不到别名,请不要尝试使用下一个别名(while
而不是for
)
导入单击
单击别名=[]
类别名组(单击.Group):
def get_命令(self、ctx、cmd_名称):
rv=单击.Group.get_命令(self、ctx、cmd_名称)
如果rv不是无:
返回rv
matches=[x代表self.list_命令(ctx)中的x)
如果x.startswith(cmd_name)]
如果不匹配:
一无所获
elif len(匹配项)=1:
单击别名。追加((cmd_名称,匹配[0]))
返回click.Group.get_命令(self、ctx、matches[0])
ctx.fail('匹配项太多:%s“%”,请连接(已排序(匹配项)))
类MyHelpFormatter(单击.HelpFormatter):
def write_用法(self,prog,args=“”,prefix=“用法:”):
如果单击别名:
零件=程序拆分()
partIdx=0
对于别名,单击别名中的cmd:
当partIdx
终端输出
$python test\u core.py a c-h
添加命令
用法:测试核心添加组合[选项]
选项:
--雅尔文本
-h、 --帮助显示此消息并退出。
您的完整示例程序是什么behavior@rioV8是的,我应该这么做,现在它就在那里。用法:test_core add combined[OPTIONS]
!=<代码>用法:test_core.py[OPTIONS]COMMAND1[ARGS]。。。[COMMAND2[ARGS]…]…——此外,我对命令链接不感兴趣。带有命令叶子的组层次结构是。输出到带有cli(['a','c','-h'],prog\u name='test\u core')
的调用实际上是:用法:test\u core c[OPTIONS]
--同样糟糕。@MatrixTheatrics您必须编写自己的帮助格式化程序。再见,干得好,谢谢!我自己对它做了一些修改,以便别名列表存储在当前上下文的dict obj中。我已经重载了这些类/函数,因此可以很容易地将其插入到代码中。@MatrixTheatrics在我的测试中,我为每个参数找到了一个新的上下文,或者至少为ctx.command\u path
找到了一个新值,可能是为相同的上下文