Source code for flowtool.main
#!/usr/bin/env python
""" The flowtool main command.
It is implemented as a click command group.
The group members are all discovered via the setuptools
entrypoints API, that baiscally allows us to define a named
entrypoint in setup.py, that can point to an arbitrary object,
which we can then later (when the package is installed) retrieve
via it's entrypoint name.
This is especially useful, since the entrypoints can also be assigend
a group, and there is a function to get an iterator over all entrypoints
of a group. The entrypoint group name for flowtool commands is
`flowtool_commands` by convention, but adding more groups should be easy
(as long as they don't require a whole different handling).
The objects that the `flowtool_commands` entrypoints point to
should be valid click commands that will be added to the main command
group before it is executed. There is also a way to add options to the
main group via the entrypoint group `flowtool_option_extensions`. This
is currently more a proof of concept (demonstrated in flowtool-stages),
and in there for completeness sake, so that the main command group can be
configured thoroughly through entrypoints.
"""
from pkg_resources import iter_entry_points
from pkg_resources import load_entry_point, DistributionNotFound
import click
from flowtool import style
OPTION_GROUPS = ('flowtool_option_extensions',)
COMMAND_GROUPS = ('flowtool_commands',)
extension_handlers = {}
@click.group()
@click.option('-d', '--debug/--no-debug', is_flag=True, help="enable flowtool debug output.")
def flowtool_main_group(debug, **kwd):
""" flowtool - a pythonic screwdriver
This is the main command group of flowtool.
It's subcommands all come from compatible modules,
that provide click commands via the setuptools
entrypoints system.
"""
style.DEBUG_OUTPUT = debug
style.debug.cyan('Options:', kwd)
for option, value in kwd.items():
if option in extension_handlers:
style.debug.cyan('main-group-setup: %s = %s' % (option, value))
extension_handlers[option](value)
else:
style.debug.cyan('main-group-setup: unhandled option: %s = %s' % (option, value))
[docs]def add_main_group_options(names=()):
""" Add options to the main command group from the entrypoint groups `names`. """
global flowtool_main_group
for name in names:
for entry_point in iter_entry_points(name):
option, handler = entry_point.load()
flowtool_main_group = option(flowtool_main_group)
extension_handlers[entry_point.name] = handler
[docs]def add_commands(names=()):
""" Add commands to the main command group from the entrypoint groups `names`. """
for name in names:
for entry_point in iter_entry_points(name):
try:
func = entry_point.load()
flowtool_main_group.add_command(func, name=entry_point.name)
except DistributionNotFound:
style.debug.yellow('Unistalled component? - %r' % entry_point.name)
[docs]def init_main_group():
""" Main module execution flow.
Add options and commands to the main group,
then start up the whole thing.
"""
add_main_group_options(OPTION_GROUPS)
add_commands(COMMAND_GROUPS)
init_main_group()
flowtool_main_group() if __name__ == '__main__' else 'Bye!'