click-contrib / click-repl

Subcommand REPL for click apps
MIT License
219 stars 40 forks source link

Pass top-level args to subcommand invocation #62

Closed theazureshadow closed 1 year ago

theazureshadow commented 5 years ago

Passes the original parsed argument values as defaults to invoke the new context. Open to suggestions for a better fix, but this addresses the major issue.

Fixes #58

theazureshadow commented 5 years ago
#!/usr/bin/env python

from click import echo, group, command, option, argument, pass_context
from click_repl import repl

@group(invoke_without_command=True)
@option('--user', required=True)
@pass_context
def cli(ctx, user):
    if ctx.invoked_subcommand is None:
        echo('Top-level user: {}'.format(user))
        repl(ctx)

@cli.command()
@option('--user')
def c1(user):
    echo('Executed C1 with {}!'.format(user))

cli()

And running it looks like:

./tmp --user csullins
Top-level user: csullins
> c1
Executed C1 with None!
> c1 --user bob
Executed C1 with bob!
theazureshadow commented 5 years ago

Looks like there are two cases: one where the REPL is invoked from user code (repl(ctx)) and one where the REPL is invoked as a subcommand (register_repl(cli)). The difference is on this line:

group_ctx = old_ctx.parent or old_ctx

The current fix only covers one of those two cases. I was able to cover both by selecting the correct context to forward params, but it makes me feel like this solution is fairly fragile. Any suggestions?