use app context aware cli, fixes #65

This commit is contained in:
Matthew Scragg 2015-07-22 12:01:49 -05:00
parent 8a7ef6bc90
commit bd41eaac4e
4 changed files with 51 additions and 7 deletions

View file

@ -226,6 +226,51 @@ assets.register('main.css',
'css/style.css')
@click.group()
from functools import update_wrapper
def with_appcontext(f):
"""Wraps a callback so that it's guaranteed to be executed with the
script's application context. If callbacks are registered directly
to the ``app.cli`` object then they are wrapped with this function
by default unless it's disabled.
"""
@click.pass_context
def decorator(__ctx, *args, **kwargs):
with create_app().app_context():
return __ctx.invoke(f, *args, **kwargs)
return update_wrapper(decorator, f)
class AppGroup(click.Group):
"""This works similar to a regular click :class:`~click.Group` but it
changes the behavior of the :meth:`command` decorator so that it
automatically wraps the functions in :func:`with_appcontext`.
Not to be confused with :class:`FlaskGroup`.
"""
def command(self, *args, **kwargs):
"""This works exactly like the method of the same name on a regular
:class:`click.Group` but it wraps callbacks in :func:`with_appcontext`
unless it's disabled by passing ``with_appcontext=False``.
"""
wrap_for_ctx = kwargs.pop('with_appcontext', True)
def decorator(f):
if wrap_for_ctx:
f = with_appcontext(f)
return click.Group.command(self, *args, **kwargs)(f)
return decorator
def group(self, *args, **kwargs):
"""This works exactly like the method of the same name on a regular
:class:`click.Group` but it defaults the group class to
:class:`AppGroup`.
"""
kwargs.setdefault('cls', AppGroup)
return click.Group.group(self, *args, **kwargs)
flask_cli = AppGroup()
@flask_cli.group()
def cli():
pass

View file

@ -1,4 +1,4 @@
from realms import config, create_app, db, __version__, cli
from realms import config, create_app, db, __version__, flask_cli as cli
from realms.lib.util import random_string, in_virtualenv, green, yellow, red
from subprocess import call, Popen
from multiprocessing import cpu_count
@ -13,7 +13,6 @@ import subprocess
# called to discover commands in modules
app = create_app()
def get_user():
for name in ('SUDO_USER', 'LOGNAME', 'USER', 'LNAME', 'USERNAME'):
user = os.environ.get(name)

View file

@ -2,9 +2,9 @@ import click
from realms.lib.util import random_string
from realms.modules.auth.models import User
from realms.lib.util import green, red, yellow
from realms import flask_cli
@click.group(short_help="Auth Module")
@flask_cli.group(short_help="Auth Module")
def cli():
pass

View file

@ -1,10 +1,10 @@
import click
from realms import create_app, search
from realms import create_app, search, flask_cli
from realms.modules.wiki.models import Wiki
from realms.lib.util import filename_to_cname
@click.group(short_help="Search Module")
@flask_cli.group(short_help="Search Module")
def cli():
pass