Slight changes in CLI structure for performance reasons
Having the plugin commands on the first level of --help proved to be a bad idea since it basically kills every chance of lazy loading the (expensive) plugin context. Using a sub command for anything plugin related allows us to only fire up the plugin context if a plugin command is expected, saving us some precious seconds of operation in all other cases. For conformity reasons the dev sub commands were now restructured similarly.
This commit is contained in:
parent
221b497932
commit
8ed3bcb094
3 changed files with 25 additions and 29 deletions
|
|
@ -135,10 +135,10 @@ so we'll first need to install that::
|
|||
|
||||
(venv) $ pip install cookiecutter
|
||||
|
||||
Then we can use the ``octoprint dev:plugin new`` command [#f1]_ to generate a new OctoPrint plugin skeleton for us::
|
||||
Then we can use the ``octoprint dev plugin:new`` command [#f1]_ to generate a new OctoPrint plugin skeleton for us::
|
||||
|
||||
(venv) $ cd ~/devel
|
||||
(venv) $ octoprint dev:plugin new helloworld
|
||||
(venv) $ octoprint dev plugin:new helloworld
|
||||
Cloning into 'cookiecutter-octoprint-plugin'...
|
||||
remote: Counting objects: 101, done.
|
||||
remote: Total 101 (delta 0), reused 0 (delta 0), pack-reused 101
|
||||
|
|
@ -160,7 +160,7 @@ Then we can use the ``octoprint dev:plugin new`` command [#f1]_ to generate a ne
|
|||
|
||||
.. note::
|
||||
|
||||
If ``octoprint dev:plugin new`` isn't recognized as a command (and also doesn't show up in the output of
|
||||
If ``octoprint dev plugin:new`` isn't recognized as a command (and also doesn't show up in the output of
|
||||
``octoprint --help``, make sure you installed cookiecutter into the same python environment as OctoPrint.
|
||||
|
||||
This will create a project structure in the ``OctoPrint-HelloWorld`` folder we just changed to that looks like this::
|
||||
|
|
@ -230,10 +230,10 @@ Now all that's left to do is to move our ``helloworld.py`` into the ``octoprint_
|
|||
The plugin is now ready to be installed via ``python setup.py install``. However, since we are still
|
||||
working on our plugin, it makes more sense to use ``python setup.py develop`` for now -- this way the plugin becomes
|
||||
discoverable by OctoPrint, however we don't have to reinstall it after any changes we will still do. We can have the
|
||||
``octoprint dev:plugin install`` command do everything for us here, it will ensure to use the python binary belonging
|
||||
``octoprint dev plugin:install`` command do everything for us here, it will ensure to use the python binary belonging
|
||||
to your OctoPrint installation::
|
||||
|
||||
(venv) $ octoprint dev:plugin install
|
||||
(venv) $ octoprint dev plugin:install
|
||||
running develop
|
||||
running egg_info
|
||||
creating OctoPrint_HelloWorld.egg-info
|
||||
|
|
@ -1075,11 +1075,11 @@ looking for examples.
|
|||
|
||||
.. rubric:: Footnotes
|
||||
|
||||
.. [#f1] Instead of the ``octoprint dev:plugin new`` you could also have manually called cookiecutter with the
|
||||
.. [#f1] Instead of the ``octoprint dev plugin:new`` you could also have manually called cookiecutter with the
|
||||
template's repository URL shortcut: ``cookiecutter gh:OctoPrint/cookiecutter-octoprint-plugin``. The
|
||||
``devel:newplugin`` command already does this for you, makes sure cookiecutter always uses a fresh
|
||||
checkout without prompting you for it and also allows to pre-specify a bunch of settings (like the
|
||||
plugin's identifier) directly from the command line. Take a look at ``octoprint dev:plugin new --help``
|
||||
plugin's identifier) directly from the command line. Take a look at ``octoprint dev plugin:new --help``
|
||||
for the usage details.
|
||||
.. [#f2] Refer to the `LESS documentation <http://lesscss.org/#using-less>`_ on how to do that. If you are developing
|
||||
your plugin under Windows you might also want to give `WinLESS <http://winless.org/>`_ a look which will run
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ class OctoPrintDevelCommands(click.MultiCommand):
|
|||
based on availability of development dependencies.
|
||||
"""
|
||||
|
||||
prefix = "dev"
|
||||
sep = ":"
|
||||
groups = ("plugin",)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
click.MultiCommand.__init__(self, *args, **kwargs)
|
||||
|
|
@ -47,10 +47,11 @@ class OctoPrintDevelCommands(click.MultiCommand):
|
|||
yield result
|
||||
|
||||
def _get_commands(self):
|
||||
commands = dict()
|
||||
for command in self._get_commands_from_prefix_methods("group_"):
|
||||
commands[self.prefix + self.sep + command.name] = command
|
||||
return commands
|
||||
result = dict()
|
||||
for group in self.groups:
|
||||
for command in self._get_commands_from_prefix_methods("{}_".format(group)):
|
||||
result[group + self.sep + command.name] = command
|
||||
return result
|
||||
|
||||
def list_commands(self, ctx):
|
||||
result = [name for name in self._get_commands()]
|
||||
|
|
@ -61,13 +62,6 @@ class OctoPrintDevelCommands(click.MultiCommand):
|
|||
commands = self._get_commands()
|
||||
return commands.get(cmd_name, None)
|
||||
|
||||
def group_plugin(self):
|
||||
command_group = click.Group("plugin",
|
||||
help="Helpers for plugin developers")
|
||||
for command in self._get_commands_from_prefix_methods("plugin_"):
|
||||
command_group.add_command(command)
|
||||
return command_group
|
||||
|
||||
def plugin_new(self):
|
||||
try:
|
||||
import cookiecutter.main
|
||||
|
|
@ -229,6 +223,11 @@ class OctoPrintDevelCommands(click.MultiCommand):
|
|||
|
||||
return command
|
||||
|
||||
@click.group(cls=OctoPrintDevelCommands)
|
||||
@click.group()
|
||||
def dev_commands():
|
||||
pass
|
||||
|
||||
@dev_commands.group(name="dev", cls=OctoPrintDevelCommands)
|
||||
def dev():
|
||||
"""Additional commands for development tasks."""
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ class OctoPrintPluginCommands(click.MultiCommand):
|
|||
The :class:`~octoprint.plugin.core.PluginManager` instance.
|
||||
"""
|
||||
|
||||
prefix = "plugin"
|
||||
sep = ":"
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
|
@ -77,26 +76,24 @@ class OctoPrintPluginCommands(click.MultiCommand):
|
|||
|
||||
for name, hook in self.hooks.items():
|
||||
try:
|
||||
plugin_info = self.plugin_manager.get_plugin_info(name, require_enabled=False)
|
||||
command_group = click.Group(name=name, help="{} commands".format(plugin_info.name))
|
||||
|
||||
commands = hook(self, pass_octoprint_ctx)
|
||||
for command in commands:
|
||||
if not isinstance(command, click.Command):
|
||||
self._logger.warn("Plugin {} provided invalid CLI command, ignoring it: {!r}".format(name, command))
|
||||
continue
|
||||
command_group.add_command(command)
|
||||
|
||||
result[self.prefix + self.sep + name] = command_group
|
||||
result[name + self.sep + command.name] = command
|
||||
except:
|
||||
self._logger.exception("Error while retrieving cli commants for plugin {}".format(name))
|
||||
|
||||
return result
|
||||
|
||||
@click.group(cls=OctoPrintPluginCommands)
|
||||
@click.group()
|
||||
@pass_octoprint_ctx
|
||||
def plugin_commands(obj):
|
||||
"""Commands provided by plugins."""
|
||||
logging.basicConfig(level=logging.DEBUG if obj.verbosity > 0 else logging.WARN)
|
||||
|
||||
@plugin_commands.group(name="plugins", cls=OctoPrintPluginCommands)
|
||||
def plugins():
|
||||
"""Additional commands provided by plugins."""
|
||||
pass
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue