diff --git a/docs/experimental/index.rst b/docs/experimental/index.rst index c84fefb1e..1c019c396 100644 --- a/docs/experimental/index.rst +++ b/docs/experimental/index.rst @@ -16,4 +16,19 @@ it's properly merged) . Use at your own risk. This documentation is a work in progress. Use at your own risk. -*No experimental features at this time* +Add commands using external libraries +------------------------------------- + +You can also add Scrapy commands from an external library by adding `scrapy.commands` section into entry_points in the `setup.py`. + +The following example adds `my_command` command:: + + from setuptools import setup, find_packages + + setup(name='scrapy-mymodule', + entry_points={ + 'scrapy.commands': [ + 'my_command=my_scrapy_module.commands:MyCommand', + ], + }, + ) diff --git a/scrapy/cmdline.py b/scrapy/cmdline.py index aebdb51f6..db7f0c122 100644 --- a/scrapy/cmdline.py +++ b/scrapy/cmdline.py @@ -2,6 +2,7 @@ import sys import optparse import cProfile import inspect +import pkg_resources import scrapy from scrapy.crawler import CrawlerProcess @@ -30,8 +31,19 @@ def _get_commands_from_module(module, inproject): d[cmdname] = cmd() return d +def _get_commands_from_entry_points(inproject, group='scrapy.commands'): + cmds = {} + for entry_point in pkg_resources.iter_entry_points(group): + obj = entry_point.load() + if inspect.isclass(obj): + cmds[entry_point.name] = obj() + else: + raise Exception("Invalid entry point %s" % entry_point.name) + return cmds + def _get_commands_dict(settings, inproject): cmds = _get_commands_from_module('scrapy.commands', inproject) + cmds.update(_get_commands_from_entry_points(inproject)) cmds_module = settings['COMMANDS_MODULE'] if cmds_module: cmds.update(_get_commands_from_module(cmds_module, inproject))