Skip to content

Instantly share code, notes, and snippets.

@GammaGames
Last active January 28, 2022 21:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GammaGames/b33cf6f13526fb7e55702f985058466b to your computer and use it in GitHub Desktop.
Save GammaGames/b33cf6f13526fb7e55702f985058466b to your computer and use it in GitHub Desktop.
Run click commands from a given string
import click
import shlex
from click.testing import CliRunner
help_text = ""
@click.group(invoke_without_command=True)
@click.pass_context
def cli(context):
"""Useful for showing help, since this is the default command"""
global help_text # Store it in a global variable for the "help" command
help_text = context.get_help()
if context.invoked_subcommand is None:
print(help_text)
@cli.command()
def help():
print(help_text)
@cli.command()
@click.argument("name", default="User")
def hello(name):
print(f"Hello, {name}!")
@cli.command()
@click.argument("name", default="User")
@click.argument("count", default=1)
def thanks(name, count):
for _ in range(count):
print(f"You're very welcome, {name}!")
def run_line(line):
"""Do all the magic to run commands from text and print output."""
runner = CliRunner()
print(f"INPUT: {line}\nOUTPUT:")
# Split with shlex to allow "quoted values"
args = shlex.split(line) if line != "" else [""]
# Get the function from globals, default to no subcommand
command = globals().get(args.pop(0), cli)
result = runner.invoke(command, args)
if result.exit_code == 0:
# This is ugly but w/e
print("> " + result.output.strip().replace("\n", "\n> "), end="")
print("\n")
@cli.command()
@click.argument("filename", type=click.File("r"))
def test(filename):
for line in filename.readlines():
run_line(line.strip())
if __name__ == "__main__":
cli()
hello
hello George
thanks
thanks George
thanks "Dr George PhD" 3
@GammaGames
Copy link
Author

GammaGames commented Jan 28, 2022

The output for python3 cli.py test input.txt:

INPUT: 
OUTPUT:
> Usage: cli [OPTIONS] COMMAND [ARGS]...
> 
>   Useful for showing help, since this is the default command
> 
> Options:
>   --help  Show this message and exit.
> 
> Commands:
>   hello
>   help
>   test    Run a bunch of commands stored in a text file
>   thanks

INPUT: hello
OUTPUT:
> Hello, User!

INPUT: hello George
OUTPUT:
> Hello, George!

INPUT: thanks
OUTPUT:
> You're very welcome, User!

INPUT: thanks George
OUTPUT:
> You're very welcome, George!

INPUT: thanks "Dr George PhD" 3
OUTPUT:
> You're very welcome, Dr George PhD!
> You're very welcome, Dr George PhD!
> You're very welcome, Dr George PhD!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment