Skip to content

Commit

Permalink
Restrucutre a plugin example and related updates in docs and test cases
Browse files Browse the repository at this point in the history
- Rename tests/plugin/ to tests/yamllint_plugin_example to make it clear
  it's an rules plugin example implementation.
- Rename the rule in example from override-comments to forbid-comments.
- Move the insturction to show how to develop plugin from
  docs/development.rst to test/yamllint_plugin_example/README.rst.
- Add packaging stuff (setup.py and setup.cfg) examples for plugins.
  • Loading branch information
ssato committed Oct 4, 2020
1 parent db749b4 commit 7aaa8e4
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 39 deletions.
40 changes: 4 additions & 36 deletions docs/development.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,39 +24,7 @@ yamllint provides a plugin mechanism using setuptools (pkg_resources) to allow
adding custom rules. So, you can extend yamllint and add rules with your own
custom yamllint rule plugins if you developed them.

Yamllint rule plugins must satisfy the followings.

#. It must be a Python package installable using pip and distributed under
GPLv3+ same as yamllint.
#. It must contains the entry point configuration in ``setup.cfg`` or something
similar packaging configuration files, to make it installed and working as a
yamllint plugin like below. (``<plugin_name>`` is that plugin name and
``<plugin_src_dir>`` is a dir where the rule modules exist.)
::

[options.entry_points]
yamllint.plugins.rules =
<plugin_name> = <plugin_src_dir>

#. It must contain custom yamllint rule modules:

- Each rule module must define a couple of global variables, ID and TYPE. ID
must not conflicts with other rules' ID.
- Each rule module must define a function named 'check' to test input data
complies with the rule.
- Each rule module may have other global variables.

- CONF to define its configuration parameters and those types.
- DEFAULT to provide default values for each configuration parameters.

#. It must define a global variable RULES_MAP to provide mappings of rule ID
and rule modules to yamllint like this.
::

RULES_MAP = {
# rule ID: rule module
a_custom_rule.ID: a_custom_rule
}

To develop yamllint rules, the default rules themselves in yamllint may become
good references.
yamllint plugins are Python packages installable using pip and distributed
under GPLv3+. To develop yamllint rules, it is recommended to copy the example
from ``tests/yamllint_plugin_example``, and follow its README file. Also, the
core rules themselves in ``yamllint/rules`` are good references.
2 changes: 1 addition & 1 deletion tests/test_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
except ImportError: # for python 2.7
mock = False

from tests.plugins import example
from tests.yamllint_plugin_example import rules as example

import yamllint.plugins

Expand Down
2 changes: 1 addition & 1 deletion tests/test_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
except ImportError: # for python 2.7
mock = False

from tests.plugins import example
from tests.yamllint_plugin_example import rules as example

import yamllint.rules

Expand Down
51 changes: 51 additions & 0 deletions tests/yamllint_plugin_example/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
yamllint plugin example
=========================

This is a yamllint plugin example as a reference, contains the following rules.

* forbid-comments to forbid comments
* random-failure to fail randomly

How to develop rule plugins
------------------------------

yamllint rule plugins must satisfy the followings.

#. It must be a Python package installable using pip and distributed under
GPLv3+ same as yamllint.

How to make a Python package is beyond the scope of this README file. Please
refer to the official guide (`Python Packaging User Guide
<https://packaging.python.org/>`_ ) and related documents.

#. It must contains the entry point configuration in ``setup.cfg`` or something
similar packaging configuration files, to make it installed and working as a
yamllint plugin like below. (``<plugin_name>`` is that plugin name and
``<plugin_src_dir>`` is a dir where the rule modules exist.)
::

[options.entry_points]
yamllint.plugins.rules =
<plugin_name> = <plugin_src_dir>

#. It must contain custom yamllint rule modules:

- Each rule module must define a couple of global variables, ID and TYPE. ID
must not conflicts with other rules' IDs.
- Each rule module must define a function named 'check' to test input data
complies with the rule.
- Each rule module may have other global variables.

- CONF to define its configuration parameters and those types.
- DEFAULT to provide default values for each configuration parameters.

#. It must define a global variable RULES to provide an iterable object, a
tuple or a list for example, of tuples of rule ID and rule modules to
yamllint like this.
::

RULES = (
# (rule module ID, rule module)
(a_custom_rule_module.ID, a_custom_rule_module),
(other_custom_rule_module.ID, other_custom_rule_module),
)
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@
"""
from __future__ import absolute_import

from . import forbid_comments
from . import forbid_comments, random_failure


RULES = (
(forbid_comments.ID, forbid_comments),
(random_failure.ID, random_failure)
)
File renamed without changes.
29 changes: 29 additions & 0 deletions tests/yamllint_plugin_example/rules/random_failure.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2020 Adrien Vergé
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import random

from yamllint.linter import LintProblem

ID = 'random-failure'
TYPE = 'token'


def check(conf, token, prev, next, nextnext, context):
if random.random() > 0.9:
yield LintProblem(token.start_mark.line + 1,
token.start_mark.column + 1,
'random failure')
11 changes: 11 additions & 0 deletions tests/yamllint_plugin_example/setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[metadata]
name = yamllint_plugin_example
version = 1.0.0

[options]
packages = find:
install_requires = yamllint

[options.entry_points]
yamllint.plugins.rules =
example = rules
2 changes: 2 additions & 0 deletions tests/yamllint_plugin_example/setup.py.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import setuptools
setuptools.setup()

0 comments on commit 7aaa8e4

Please sign in to comment.