Add Blueprint level cli command registration
Implements #1357. Adds ability to register click cli commands onto blueprint.
This commit is contained in:
parent
855d59b68b
commit
ec1ccd7530
6 changed files with 136 additions and 8 deletions
10
flask/app.py
10
flask/app.py
|
|
@ -600,13 +600,9 @@ class Flask(_PackageBoundObject):
|
|||
view_func=self.send_static_file,
|
||||
)
|
||||
|
||||
#: The click command line context for this application. Commands
|
||||
#: registered here show up in the :command:`flask` command once the
|
||||
#: application has been discovered. The default commands are
|
||||
#: provided by Flask itself and can be overridden.
|
||||
#:
|
||||
#: This is an instance of a :class:`click.Group` object.
|
||||
self.cli = cli.AppGroup(self.name)
|
||||
# Set the name of the Click group in case someone wants to add
|
||||
# the app's commands to another CLI tool.
|
||||
self.cli.name = self.name
|
||||
|
||||
@locked_cached_property
|
||||
def name(self):
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ from functools import update_wrapper
|
|||
|
||||
from .helpers import _PackageBoundObject, _endpoint_from_view_func
|
||||
|
||||
# a singleton sentinel value for parameter defaults
|
||||
_sentinel = object()
|
||||
|
||||
|
||||
class BlueprintSetupState(object):
|
||||
"""Temporary holder object for registering a blueprint with the
|
||||
|
|
@ -90,6 +93,11 @@ class Blueprint(_PackageBoundObject):
|
|||
or other things on the main application. See :ref:`blueprints` for more
|
||||
information.
|
||||
|
||||
.. versionchanged:: 1.1.0
|
||||
Blueprints have a ``cli`` group to register nested CLI commands.
|
||||
The ``cli_group`` parameter controls the name of the group under
|
||||
the ``flask`` command.
|
||||
|
||||
.. versionadded:: 0.7
|
||||
"""
|
||||
|
||||
|
|
@ -129,6 +137,7 @@ class Blueprint(_PackageBoundObject):
|
|||
subdomain=None,
|
||||
url_defaults=None,
|
||||
root_path=None,
|
||||
cli_group=_sentinel,
|
||||
):
|
||||
_PackageBoundObject.__init__(
|
||||
self, import_name, template_folder, root_path=root_path
|
||||
|
|
@ -142,6 +151,7 @@ class Blueprint(_PackageBoundObject):
|
|||
if url_defaults is None:
|
||||
url_defaults = {}
|
||||
self.url_values_defaults = url_defaults
|
||||
self.cli_group = cli_group
|
||||
|
||||
def record(self, func):
|
||||
"""Registers a function that is called when the blueprint is
|
||||
|
|
@ -206,6 +216,17 @@ class Blueprint(_PackageBoundObject):
|
|||
for deferred in self.deferred_functions:
|
||||
deferred(state)
|
||||
|
||||
cli_resolved_group = options.get("cli_group", self.cli_group)
|
||||
|
||||
if cli_resolved_group is None:
|
||||
app.cli.commands.update(self.cli.commands)
|
||||
elif cli_resolved_group is _sentinel:
|
||||
self.cli.name = self.name
|
||||
app.cli.add_command(self.cli)
|
||||
else:
|
||||
self.cli.name = cli_resolved_group
|
||||
app.cli.add_command(self.cli)
|
||||
|
||||
def route(self, rule, **options):
|
||||
"""Like :meth:`Flask.route` but for a blueprint. The endpoint for the
|
||||
:func:`url_for` function is prefixed with the name of the blueprint.
|
||||
|
|
|
|||
|
|
@ -942,6 +942,15 @@ class _PackageBoundObject(object):
|
|||
self._static_folder = None
|
||||
self._static_url_path = None
|
||||
|
||||
# circular import
|
||||
from .cli import AppGroup
|
||||
|
||||
#: The Click command group for registration of CLI commands
|
||||
#: on the application and associated blueprints. These commands
|
||||
#: are accessible via the :command:`flask` command once the
|
||||
#: application has been discovered and blueprints registered.
|
||||
self.cli = AppGroup()
|
||||
|
||||
def _get_static_folder(self):
|
||||
if self._static_folder is not None:
|
||||
return os.path.join(self.root_path, self._static_folder)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue