Added plugin support to the cli
This commit is contained in:
parent
21d595bee7
commit
9594876c1f
2 changed files with 53 additions and 0 deletions
34
docs/cli.rst
34
docs/cli.rst
|
|
@ -214,3 +214,37 @@ step.
|
|||
Whenever click now needs to operate on a Flask application it will
|
||||
call that function with the script info and ask for it to be created.
|
||||
4. All is rounded up by invoking the script.
|
||||
|
||||
CLI Plugins
|
||||
-----------
|
||||
|
||||
Flask extensions can always patch the `Flask.cli` instance with more
|
||||
commands if they want. However there is a second way to add CLI plugins
|
||||
to Flask which is through `setuptools`. If you make a Python package that
|
||||
should export a Flask command line plugin you can ship a `setup.py` file
|
||||
that declares an entrypoint that points to a click command:
|
||||
|
||||
Example `setup.py`::
|
||||
|
||||
from setuptools import setup
|
||||
|
||||
setup(
|
||||
name='flask-my-extension',
|
||||
...
|
||||
entry_points='''
|
||||
[flask.commands]
|
||||
my-command=mypackage.commands:cli
|
||||
''',
|
||||
)
|
||||
|
||||
Inside `mypackage/comamnds.py` you can then export a Click object::
|
||||
|
||||
import click
|
||||
|
||||
@click.command()
|
||||
def cli():
|
||||
"""This is an example command."""
|
||||
|
||||
Once that package is installed in the same virtualenv as Flask itself you
|
||||
can run ``flask my-command`` to invoke your command. This is useful to
|
||||
provide extra functionality that Flask itself cannot ship.
|
||||
|
|
|
|||
19
flask/cli.py
19
flask/cli.py
|
|
@ -282,7 +282,24 @@ class FlaskGroup(AppGroup):
|
|||
self.add_command(run_command)
|
||||
self.add_command(shell_command)
|
||||
|
||||
self._loaded_plugin_commands = False
|
||||
|
||||
def _load_plugin_commands(self):
|
||||
if self._loaded_plugin_commands:
|
||||
return
|
||||
try:
|
||||
import pkg_resources
|
||||
except ImportError:
|
||||
self._loaded_plugin_commands = True
|
||||
return
|
||||
|
||||
for ep in pkg_resources.iter_entry_points('flask.commands'):
|
||||
self.add_command(ep.load(), ep.name)
|
||||
self._loaded_plugin_commands = True
|
||||
|
||||
def get_command(self, ctx, name):
|
||||
self._load_plugin_commands()
|
||||
|
||||
# We load built-in commands first as these should always be the
|
||||
# same no matter what the app does. If the app does want to
|
||||
# override this it needs to make a custom instance of this group
|
||||
|
|
@ -303,6 +320,8 @@ class FlaskGroup(AppGroup):
|
|||
pass
|
||||
|
||||
def list_commands(self, ctx):
|
||||
self._load_plugin_commands()
|
||||
|
||||
# The commands available is the list of both the application (if
|
||||
# available) plus the builtin commands.
|
||||
rv = set(click.Group.list_commands(self, ctx))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue