From 282366e11f9cdda54dbedeb673bb894d53ec9147 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Thu, 29 Sep 2022 20:17:17 +0200 Subject: fietsupdater: better help behaviour This does two things: 1. fietsupdate update --help works (before it errored because the required argument is not given) 2. fietsupdate help works (like git help ...) --- fietsboek/updater/cli.py | 76 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 53 insertions(+), 23 deletions(-) diff --git a/fietsboek/updater/cli.py b/fietsboek/updater/cli.py index 38297d7..6a59100 100644 --- a/fietsboek/updater/cli.py +++ b/fietsboek/updater/cli.py @@ -13,6 +13,20 @@ from pyramid.paster import setup_logging from . import Updater +# We keep this as a separate option that is added to each subcommand as Click +# (unlike argparse) cannot handle "--help" without the required arguments of +# the parent (so "fietsupdate update --help" would error out) +# See also +# https://github.com/pallets/click/issues/295 +# https://github.com/pallets/click/issues/814 +config_option = click.option( + "-c", "--config", + type=click.Path(exists=True, dir_okay=False), + required=True, + help="Path to the Fietsboek configuration file", +) + + def user_confirm(): click.secho("Warning:", fg="yellow") click.echo( @@ -23,29 +37,24 @@ def user_confirm(): click.confirm("Proceed?", abort=True) -@click.group(help=__doc__) -@click.option( - "-c", "--config", - type=click.Path(exists=True, dir_okay=False), - required=True, - help="Path to the Fietsboek configuration file", +@click.group( + help=__doc__, + context_settings={'help_option_names': ['-h', '--help']}, ) -@click.pass_context -def cli(ctx, config): - ctx.ensure_object(dict) - setup_logging(config) - ctx.obj["INIFILE"] = config +def cli(): + """CLI main entry point.""" + pass @cli.command("update") +@config_option @click.option( "-f", "--force", is_flag=True, help="Skip the safety question and just run the update", ) -@click.argument("VERSION", required=False) -@click.pass_context -def update(ctx, version, force): +@click.argument("version", required=False) +def update(config, version, force): """Run the update process. Make sure to consult the documentation and ensure that you have a backup @@ -54,7 +63,7 @@ def update(ctx, version, force): VERSION specifies the version you want to update to. Leave empty to choose the latest version. """ - updater = Updater(ctx.obj["INIFILE"]) + updater = Updater(config) updater.load() if version and not updater.exists(version): click.secho("Revision not found", fg="red") @@ -76,14 +85,14 @@ def update(ctx, version, force): @cli.command("downgrade") +@config_option @click.option( "-f", "--force", is_flag=True, help="Skip the safety question and just run the downgrade", ) -@click.argument("VERSION") -@click.pass_context -def downgrade(ctx, version, force): +@click.argument("version") +def downgrade(config, version, force): """Run the downgrade process. Make sure to consult the documentation and ensure that you have a backup @@ -91,7 +100,7 @@ def downgrade(ctx, version, force): VERSION specifies the version you want to downgrade to. """ - updater = Updater(ctx.obj["INIFILE"]) + updater = Updater(config) updater.load() if version and not updater.exists(version): click.secho("Revision not found", fg="red") @@ -106,10 +115,10 @@ def downgrade(ctx, version, force): click.secho(f"Downgrade succeeded, version: {version_str}", fg="green") -@cli.command("revision") -@click.argument("REVISION_ID", required=False) -@click.pass_context -def revision(ctx, revision_id): +@cli.command("revision", hidden=True) +@config_option +@click.argument("revision_id", required=False) +def revision(config, revision_id): """Create a new revision. This automatically populates the revision dependencies and alembic @@ -133,5 +142,26 @@ def revision(ctx, revision_id): click.echo(f"Revision saved to {filename}") +@cli.command("help", hidden=True) +@click.pass_context +@click.argument("subcommand", required=False) +def help(ctx, subcommand): + """Shows the help for a given subcommand. + + This is equivalent to using the --help option. + """ + if not subcommand: + click.echo(cli.get_help(ctx.parent)) + return + cmd = cli.get_command(ctx, subcommand) + if cmd is None: + click.echo(f"Error: Command {subcommand} not found") + else: + # Create a new context so that the usage shows "fietsboek subcommand" + # instead of "fietsboek help" + with click.Context(cmd, ctx.parent, subcommand) as subcontext: + click.echo(cmd.get_help(subcontext)) + + if __name__ == "__main__": cli() -- cgit v1.2.3