From 7aaa8e476130574e47740da0618eecbf364a6ac1 Mon Sep 17 00:00:00 2001 From: Satoru SATOH Date: Sun, 4 Oct 2020 13:00:04 +0900 Subject: [PATCH] Restrucutre a plugin example and related updates in docs and test cases - 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. --- docs/development.rst | 40 ++------------- tests/test_plugins.py | 2 +- tests/test_rules.py | 2 +- tests/yamllint_plugin_example/README.rst | 51 +++++++++++++++++++ .../__init__.py | 0 .../rules}/__init__.py | 3 +- .../rules}/forbid_comments.py | 0 .../rules/random_failure.py | 29 +++++++++++ tests/yamllint_plugin_example/setup.cfg | 11 ++++ .../yamllint_plugin_example/setup.py.example | 2 + 10 files changed, 101 insertions(+), 39 deletions(-) create mode 100644 tests/yamllint_plugin_example/README.rst rename tests/{plugins => yamllint_plugin_example}/__init__.py (100%) rename tests/{plugins/example => yamllint_plugin_example/rules}/__init__.py (90%) rename tests/{plugins/example => yamllint_plugin_example/rules}/forbid_comments.py (100%) create mode 100644 tests/yamllint_plugin_example/rules/random_failure.py create mode 100644 tests/yamllint_plugin_example/setup.cfg create mode 100644 tests/yamllint_plugin_example/setup.py.example diff --git a/docs/development.rst b/docs/development.rst index 3060b34b7..7ddda1431 100644 --- a/docs/development.rst +++ b/docs/development.rst @@ -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. (```` is that plugin name and - ```` is a dir where the rule modules exist.) - :: - - [options.entry_points] - yamllint.plugins.rules = - = - -#. 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. diff --git a/tests/test_plugins.py b/tests/test_plugins.py index 1ee33148f..2680b0ce7 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -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 diff --git a/tests/test_rules.py b/tests/test_rules.py index b81ee86a2..7d15c73a9 100644 --- a/tests/test_rules.py +++ b/tests/test_rules.py @@ -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 diff --git a/tests/yamllint_plugin_example/README.rst b/tests/yamllint_plugin_example/README.rst new file mode 100644 index 000000000..3e6075fba --- /dev/null +++ b/tests/yamllint_plugin_example/README.rst @@ -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 + `_ ) 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. (```` is that plugin name and + ```` is a dir where the rule modules exist.) + :: + + [options.entry_points] + yamllint.plugins.rules = + = + +#. 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), + ) diff --git a/tests/plugins/__init__.py b/tests/yamllint_plugin_example/__init__.py similarity index 100% rename from tests/plugins/__init__.py rename to tests/yamllint_plugin_example/__init__.py diff --git a/tests/plugins/example/__init__.py b/tests/yamllint_plugin_example/rules/__init__.py similarity index 90% rename from tests/plugins/example/__init__.py rename to tests/yamllint_plugin_example/rules/__init__.py index 2d06f7d7c..426544b0e 100644 --- a/tests/plugins/example/__init__.py +++ b/tests/yamllint_plugin_example/rules/__init__.py @@ -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) ) diff --git a/tests/plugins/example/forbid_comments.py b/tests/yamllint_plugin_example/rules/forbid_comments.py similarity index 100% rename from tests/plugins/example/forbid_comments.py rename to tests/yamllint_plugin_example/rules/forbid_comments.py diff --git a/tests/yamllint_plugin_example/rules/random_failure.py b/tests/yamllint_plugin_example/rules/random_failure.py new file mode 100644 index 000000000..4032a80af --- /dev/null +++ b/tests/yamllint_plugin_example/rules/random_failure.py @@ -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 . + +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') diff --git a/tests/yamllint_plugin_example/setup.cfg b/tests/yamllint_plugin_example/setup.cfg new file mode 100644 index 000000000..1ad9e72c4 --- /dev/null +++ b/tests/yamllint_plugin_example/setup.cfg @@ -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 diff --git a/tests/yamllint_plugin_example/setup.py.example b/tests/yamllint_plugin_example/setup.py.example new file mode 100644 index 000000000..a4f49f920 --- /dev/null +++ b/tests/yamllint_plugin_example/setup.py.example @@ -0,0 +1,2 @@ +import setuptools +setuptools.setup()