-
-
Notifications
You must be signed in to change notification settings - Fork 566
Spring cleaning #788
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Spring cleaning #788
Changes from 11 commits
b8e1c29
c7dd288
b9d44e5
7f4aeea
bda2966
c64e636
591532e
50d6230
0e05f36
e2f97fc
a80fe9f
fb13e94
fc9fba2
f179e5f
76b8205
48cae31
ebd5835
f9825d1
dc62bd6
c44c7d4
3b6bd01
7cdf048
3822793
5b63777
a620048
470149a
b8eee01
1eecd5f
f3412d6
6f96ca2
1dffe50
8d8cd81
4d3193a
dffae55
db57931
bc950dd
d4cdf11
5a6743b
cdb6680
acdbd48
82a32bb
7d139e5
4969c57
7327c89
61498c2
bdb0d17
2d1f2a2
5a5b3dc
9662011
e3bba6b
5058cc9
a6c3ff6
d136a4f
98cbcd9
84c5884
753fe55
b5944ca
40d2583
558000c
1f995b3
2683477
e59afae
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,74 +5,90 @@ tox plugins | |
|
|
||
| .. versionadded:: 2.0 | ||
|
|
||
| With tox-2.0 a few aspects of tox running can be experimentally modified | ||
| by writing hook functions. The list of of available hook function is | ||
| to grow over time on a per-need basis. | ||
| A growing number of `pluggy`_ hooks make tox extendable by writing plugins. | ||
|
|
||
|
|
||
| writing a setuptools entrypoints plugin | ||
| Writing a setuptools entrypoints plugin | ||
| --------------------------------------- | ||
|
|
||
| If you have a ``tox_MYPLUGIN.py`` module you could use the following | ||
| rough ``setup.py`` to make it into a package which you can upload to the | ||
| Python packaging index: | ||
| You can create a new tox plugin with all bells and whistles via a `Cookiecutter`_ template (see `cookiecutter-tox-plugin <https://github.com/tox-dev/cookiecutter-tox-plugin>`_) - this will create a complete pypi-releasable, documented project with license, documentation and CI. | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| # content of setup.py | ||
| from setuptools import setup | ||
| .. code-block:: console | ||
|
|
||
| if __name__ == "__main__": | ||
| setup( | ||
| name='tox-MYPLUGIN', | ||
| description='tox plugin decsription', | ||
| license="MIT license", | ||
| version='0.1', | ||
| py_modules=['tox_MYPLUGIN'], | ||
| entry_points={'tox': ['MYPLUGIN = tox_MYPLUGIN']}, | ||
| install_requires=['tox>=2.0'], | ||
| ) | ||
| $ pip install -U cookiecutter | ||
| $ cookiecutter gh:tox-dev/cookiecutter-tox-plugin | ||
|
|
||
| If installed, the ``entry_points`` part will make tox see and integrate | ||
| your plugin during startup. | ||
|
|
||
| You can install the plugin for development ("in-place") via: | ||
| Tutorial: a minimal tox plugin | ||
| ------------------------------ | ||
|
|
||
| .. code-block:: shell | ||
| To create a working plugin you need at least a python project with a tox entry point and a python | ||
| module implementing one or more of the pluggy based hooks tox specifies (using the | ||
| ``@tox.hookimpl`` decorator as marker). | ||
|
|
||
| pip install -e . | ||
| Let us consider you want to extent tox behaviour by displaying fireworks at the end of a | ||
| successful tox run (we won't go into the details of how to display fireworks though). | ||
|
|
||
| and later publish it via something like: | ||
| minimal structure: | ||
|
|
||
| .. code-block:: shell | ||
| .. code-block:: console | ||
|
|
||
| python setup.py sdist register upload | ||
| $ mkdir tox-fireworks | ||
| $ cd tox-fireworks | ||
| $ touch tox_fireworks.py | ||
| $ touch setup.py | ||
|
|
||
|
|
||
| Writing hook implementations | ||
| ---------------------------- | ||
|
|
||
| A plugin module defines one or more hook implementation functions | ||
| by decorating them with tox's ``hookimpl`` marker: | ||
| contents of ``tox_fireworks.py``: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| from tox import hookimpl | ||
| import pluggy | ||
|
|
||
| hookimpl = pluggy.HookimplMarker("tox") | ||
|
|
||
| @hookimpl | ||
| def tox_addoption(parser): | ||
| # add your own command line options | ||
|
|
||
| """Add command line option to display fireworks on request.""" | ||
|
|
||
| @hookimpl | ||
| def tox_configure(config): | ||
| # post process tox configuration after cmdline/ini file have | ||
| # been parsed | ||
| """Post process config after parsing.""" | ||
|
|
||
| @hookimpl | ||
| def tox_runenvreport(config): | ||
| """Display fireworks if all was fine and requested.""" | ||
|
|
||
| If you put this into a module and make it pypi-installable with the ``tox`` | ||
| entry point you'll get your code executed as part of a tox run. | ||
|
|
||
| contents of ``setup.py``: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| from setuptools import setup | ||
|
|
||
| setup(name='tox-fireworks', py_modules=['tox_fireworks'], | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. would be more comfortable if this would follow the structure of what we generate with the cookiecutter, but at least add tox-dev/cookiecutter-tox-plugin#4
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The idea here is to explain the minimal implementation to show how things basically work. In the cookiecutter introduced the package structure, because I think it is a better structure. I was already thinking that this could also be made configurable in the cookiecutter (adding a choice, if you want to create a single module plugin or a a package based one). |
||
| entry_points={'tox': ['fireworks = tox_fireworks']}) | ||
|
|
||
| Using the **tox-** prefix in ``tox-fireworks`` is necessary for it to be an official plugin and | ||
| makes finding it easy with e.g. ``pip search 'tox-'`` once it is released on PyPi. | ||
|
|
||
| To make your new plugin discoverable by tox, you need to install it. During development you should | ||
| install it with ``-e`` or ``--editable``, so that changes to the code are immediately active: | ||
|
|
||
| .. code-block:: console | ||
|
|
||
| pip install -e </path/to/tox-fireworks> | ||
|
|
||
| If you think the rest of the world could profit using your plugin you can publish it to PyPi. | ||
| Add some more meta data to ``setup.py`` (see the cookiecutter for a complete example) and publish | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
link the cookiectutter template to the github repo
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done. |
||
| it like: | ||
|
|
||
| .. code-block:: console | ||
|
|
||
| $ cd </path/to/tox-fireworks> | ||
| $ python setup.py sdist bdist_wheel upload | ||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there's a typo in this commit message, can be left as it is if you do a squash merge, otherwise I suggest a reword 😄
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Imprve definitely needs improving :) |
||
| For more information about packaging Python projects see the | ||
| `Python Packaging User Guide <https://packaging.python.org/>`_. | ||
|
|
||
| tox hook specifications and related API | ||
| --------------------------------------- | ||
|
|
@@ -94,3 +110,7 @@ tox hook specifications and related API | |
|
|
||
| .. autoclass:: tox.session.Session() | ||
| :members: | ||
|
|
||
|
|
||
| .. _`Cookiecutter`: https://cookiecutter.readthedocs.io | ||
| .. _`pluggy`: https://pluggy.readthedocs.io | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -43,7 +43,7 @@ def main(): | |
| author='holger krekel', | ||
| author_email='holger@merlinux.eu', | ||
| packages=['tox'], | ||
| entry_points={'console_scripts': ['tox=tox.session:run_main', | ||
| entry_points={'console_scripts': ['tox=tox:cmdline', | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand this rename; the cmdline actually shows up as not a valid dictionary entry, hence why I renamed it to run_main instead, to be more explicit
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you mean by valid dictionary entry? Idea here is to remove an unnecessary proxy name. Why should we have a run_main at all, when it is imported and used as
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. e.g. in the English dictionary the word cmdline does not exist I would consider this bad naming in the past, having the proxy names help correct it internally imho, although if you really insist we can keep it as such |
||
| 'tox-quickstart=tox._quickstart:main']}, | ||
| python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', | ||
| setup_requires=['setuptools_scm'], | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should have a link here to a page that lists all available hooks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless I misunderstand what you mean: they are already documented at the end of the same page.