diff --git a/docs/source/dev/formatters.rst b/docs/source/dev/formatters.rst new file mode 100644 index 0000000..b96c40b --- /dev/null +++ b/docs/source/dev/formatters.rst @@ -0,0 +1,16 @@ +=========================================== + Developing a Formatting Plugin for Flake8 +=========================================== + +Flake8 added the ability to develop custom formatting plugins in version +3.0.0. Let's write a plugin together: + +.. code-block:: python + + from flake8.formatting import base + + + class Example(base.BaseFormatter): + """Flake8's example formatter.""" + + pass diff --git a/docs/source/dev/registering_plugins.rst b/docs/source/dev/registering_plugins.rst new file mode 100644 index 0000000..1444af0 --- /dev/null +++ b/docs/source/dev/registering_plugins.rst @@ -0,0 +1,113 @@ +================================== + Registering a Plugin with Flake8 +================================== + +To register any kind of plugin with Flake8, you need a few things: + +#. You need a way to install the plugin (whether it is packaged on its own or + as part of something else). In this section, we will use a ``setup.py`` + written for an example plugin. + +#. A name for your plugin that will (ideally) be unique. + +#. A somewhat recent version of setuptools (newer than 0.7.0 but preferably as + recent as you can attain). + +Flake8 presently relies on a functionality provided by setuptools called +`Entry Points`_. These allow any package to register a plugin with Flake8 via +that package's ``setup.py`` file. + +Let's presume that we already have our plugin written and it's in a module +called ``flake8_example``. We might have a ``setup.py`` that looks something +like: + +.. code-block:: python + + from __future__ import with_statement + import setuptools + + requires = [ + "flake8 > 3.0.0", + ] + + flake8_entry_point = # ... + + setuptools.setup( + name="flake8_example", + license="MIT", + version="0.1.0", + description="our extension to flake8", + author="Me", + author_email="example@example.com", + url="https://gitlab.com/me/flake8_example", + packages=[ + "flake8_example", + ], + install_requires=requires, + entry_points={ + flake8_entry_point: [ + 'X = flake8_example.ExamplePlugin', + ], + }, + classifiers=[ + "Environment :: Console", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 3", + "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: Software Development :: Quality Assurance", + ], + ) + +Note specifically these lines: + +.. code-block:: python + + flake8_entry_point = # ... + + setuptools.setup( + # snip ... + entry_points={ + flake8_entry_point: [ + 'X = flake8_example.ExamplePlugin', + ], + }, + # snip ... + ) + +We tell setuptools to register our entry point "X" inside the specific +grouping of entry-points that flake8 should look in. + +Flake8 presently looks at three groups: + +- ``flake8.extension`` + +- ``flake8.format`` + +- ``flake8.report`` + +If your plugin is one that adds checks to Flake8, you will use +``flake8.extension``. If your plugin formats the output and provides that to +the user, you will use ``flake8.format``. Finally, if your plugin performs +extra report handling (filtering, etc.) it will use ``flake8.report``. + +If our ``ExamplePlugin`` is something that adds checks, our code would look +like: + +.. code-block:: python + + setuptools.setup( + # snip ... + entry_points={ + 'flake8.extension': [ + 'X = flake8_example.ExamplePlugin', + ], + }, + # snip ... + ) + + +.. _Entry Points: + https://pythonhosted.org/setuptools/pkg_resources.html#entry-points