-
Notifications
You must be signed in to change notification settings - Fork 280
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
enhancement: add rules plugin support #315
base: master
Are you sure you want to change the base?
Conversation
Here is a working YAML Lint plugin example tested with it: https://github.com/ssato/yamllint-plugin-example |
Interesting! Supporting plugins raise new issues (like security), for info please look this similar pull request from 2016: #19. Could you give more details about your use-case? What kind of rules would you like to plug in? Wouldn't they be better inside yamllint, upstream? |
Unlike #19, my plugin code does not use hidden dir to put custom rules nor modify sys.path, and plugins must be installed as usual python modules, AFAIK. So I don't think it brings huge security risks. Also, there might be security risk if users change $PYTHONPATH but it should be another story, I guess.
There are cases that users want their own unique rules never come into yamllint, I think. For example, a rule forbids that some words are not allowed as mapping objects' keys. |
@ssato I agree that the python module idea is good 👍 Supporting plugins in yamllint would also require adding documentation and tests. Also, I would prefer dropping the override parameter, and don't allow to re-define an existing rule, to make things clear and less error-prone for users. What do you think? |
I changed my mind and fully agree with you to drop that part. And about doc and tests, I'll try a little more. |
afa0496
to
3074488
Compare
A couple of updates:
|
9cf8903
to
10467a4
Compare
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.
Thanks @ssato. I have a few remarks, please see in the code.
I squashed and pushed them as two commits because adding plugin test case feels a bit harder and should take some more time. I cannot think of clean solution for this issue now.
Once merged into yamllint, the plugin feature will be used and will need some work to maintain, and some support on the GitHub issues page. Therefore this feature will be accepted if the code is perfect and comes with tests (and in my opinion one commit is enough since it's all the same functionnality).
yamllint/plugins.py
Outdated
rules_mod = entry.load() | ||
yield rules_mod.RULES_MAP | ||
except AttributeError: | ||
pass # TBD |
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.
What do you mean with TBD
?
What do you think about removing load_plugin_rules_itr()
and loading plugins into update_rules_map()
, without try
/except
? If importing a plugin fails → no silent error. The problem is clearly visible in the stacktrace and the user knows why the custom plugin doesn't work, and how to fix it (uninstall the plugin or fix it).
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.
TBD means to be determined to fix what to do if plugin is broken or has some problems to work.
I have some ideas about it, e.g. output warning messages about broken plugins, but I'm not sure twhat is the best to do for such cases you think so that I commented as it is.
I think that maybe there are cases that the quality of plugin code is not enough compared to yamllint itself you keep maintained and it would be better to keep yamllint works even if such plugins are installed.
yamllint/rules/__init__.py
Outdated
@@ -14,6 +14,8 @@ | |||
# 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 yamllint.plugins | |||
|
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.
This space is not needed I think, yamllint.*
import should be grouped.
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.
Please let me clarify that your thought. Do you think that it should be something like:
from yamllint import (
plugins,
rules.braces,
...
)
or anything else?
I fully agree with you about that the empty line 18 is not needed and pushed that change already (commit ad1f292) but I'm not sure to group those (plugin and rules.*) imports is good thing from your maintainer's point of view (I think of the cases that addition and/or removal of standard rules).
yamllint/rules/__init__.py
Outdated
@@ -63,8 +65,11 @@ | |||
} | |||
|
|||
|
|||
def get(id): | |||
if id not in _RULES: | |||
def get(id, rules=None): |
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.
If nobody uses the optional parameter rules=None
, I'm for removing it.
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.
I'm not sure but it might be better to keep it as is or allow passing some arguments to make easier for unit tests, I think.
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.
To make tests easier and leave a room to control the rules' mappings to search for, those are necessary, I think.Please take a look at the commit 01554f2 also.
yamllint/rules/__init__.py
Outdated
if rules is None: | ||
rules = yamllint.plugins.update_rules_map(_RULES) |
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.
I see 2 issues:
- It appears that this call modifies the
_RULES
object. - This
get()
function is called many times by the linter, it would be better not to callyamllint.plugins.update_rules_map()
every time.
What do you think of:
_EXTERNAL_RULES = None
def get(id):
global _RULES, _EXTERNAL_RULES
if _EXTERNAL_RULES is None:
_EXTERNAL_RULES = yamllint.plugins.load_plugin_rules()
if id in _RULES:
return _RULES[id]
elif id in _EXTERNAL_RULES:
return _EXTERNAL_RULES[id]
else:
raise ValueError('no such rule: "%s"' % id)
?
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.
Absolutely right! I like the code looks best and don't have any objections about it.
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.
One thing I forgot to mention.
How about to add arguments {rules=None, external_rules=None} (both will fallback to_RULES, _EXTERNAL_RULES if no arguments were given) to 'get' function to make it easy to test?
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.
Could you please take a look at the commit 01554f2 ? I think it got better.
ad1f292
to
af8d060
Compare
As far as I'm aware of, the following issues have to be fixed and/or improved before merge.
Could you please point out if I forgot to list? And other relatively minor things may be followings, I think.
|
3503eb0
to
cb7ae13
Compare
I reverted this change because it does not look improving its performance a lot as far as I tested. Sorry for the confusion.
|
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.
Hello @ssato,
Decide what to do for cases if something goes wrong with loaded plugin:
I'm OK with your proposal (a warning).
Decide what to do for cases if something goes wrong with loaded plugin:
Using a LRU cache for this is probably overkill and complexifies the code. What about my original suggestion: just build an _EXTERNAL_RULES
in parallel of _RULES
? EDIT: I see in you finally reverted back to it.
How about to add arguments {rules=None, external_rules=None}
If they are not used in real code (not tests), they shouldn't be. Modifying code just for tests is usually a bad practice.
If you need to test different values of _RULES
and _EXTERNAL_RULES
, you can patch them using a mock?
The real plugin test cases using pkg_resources actually. I think that another plugin repo might be needed for this.
It would be complicated; in my opinion your example in tests
is good 👍
Perhaps, it might be better to change the package group name to "yamllint.plugins.rules" or something.
Good idea! yamllint.plugins.rules
sound good.
tests/plugins/example/__init__.py
Outdated
# | ||
# SPDX-License-Identifier: GPL-3.0-or-later | ||
# | ||
"""YAML Lint plugin entry point |
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.
The tool is named "yamllint", not "YAML Lint".
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.
Thanks for your correction! Applied the fix and pushed it: 8253b1c
tests/plugins/example/__init__.py
Outdated
# | ||
# Copyright (C) 2020 Satoru SATOH | ||
# | ||
# SPDX-License-Identifier: GPL-3.0-or-later |
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.
Can you please stay consistent with other license headers, even in the plugin example code?
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.
Same as above.
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.
Hello @adrienverge,
Thanks a lot for your feedbacks!
I think that I applied all changes you advised and could you please look at them in the following comments?
If you're OK with them, I'll squash all into a few commits or a commit for further review.
Decide what to do for cases if something goes wrong with loaded plugin:
I'm OK with your proposal (a warning).
Thanks! Then, I keep as it is.
Decide what to do for cases if something goes wrong with loaded plugin:
Using a LRU cache for this is probably overkill and complexifies the code. What about my original suggestion: just build an
_EXTERNAL_RULES
in parallel of_RULES
? EDIT: I see in you finally reverted back to it.How about to add arguments {rules=None, external_rules=None}
If they are not used in real code (not tests), they shouldn't be. Modifying code just for tests is usually a bad practice.
If you need to test different values of_RULES
and_EXTERNAL_RULES
, you can patch them using a mock?The real plugin test cases using pkg_resources actually. I think that another plugin repo might be needed for this.
It would be complicated; in my opinion your example in
tests
is good +1
Absolutely right. I was not sure mock works for such cases but it looks so.
I changed as you advised and modified its test code in 507d824 and 44a3559.
Could you please take a look at these changes?
Perhaps, it might be better to change the package group name to "yamllint.plugins.rules" or something.
Good idea!
yamllint.plugins.rules
sound good.
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.
Thanks @ssato, here are some new comments. I need to take time to test the code and review it in detail.
.travis.yml
Outdated
@@ -13,6 +13,7 @@ env: | |||
- REMOVE_LOCALES=true | |||
install: | |||
- pip install pyyaml coveralls flake8 flake8-import-order doc8 | |||
- if [[ $TRAVIS_PYTHON_VERSION != 3* ]]; then pip install mock; fi |
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.
Python 2 support and all related code will be dropped soon. So can we avoid this line, and don't execute your new tests if Python < 3? Maybe with something like @unittest.skipIf(sys.version_info < (3, 0)...
or equivalent?
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.
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.
👍
docs/development.rst
Outdated
|
||
Yamllint rule plugins must satisfy the followings. | ||
|
||
#. It must be a python package installable using pip and distributed under |
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.
python → Python
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.
Thanks! I applied changes in 8864b19.
docs/development.rst
Outdated
#. 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.) |
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.
#. 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.) | |
#. 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.) |
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.
Same as the previous one.
@@ -0,0 +1,51 @@ | |||
# | |||
# Copyright (C) 2020 Satoru SATOH | |||
# SPDX-License-Identifier: GPL-3.0-or-later |
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.
Can you please stay consistent with other license headers, even in the plugin example code?
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.
Thanks! I forgot to fix that. Fixed in b49e67f.
yamllint/plugins.py
Outdated
def validate_rule_module(rule_mod): | ||
"""Test if given rule module is valid. | ||
""" | ||
return getattr(rule_mod, "ID", False | ||
) and callable(getattr(rule_mod, "check", False)) |
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.
Do you think it would be a good idea to check if TYPE
, CONF
and DEFAULT
are also present?
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.
Some rules don't have CONF and DEFAULT like yamllint/rules/comments_indentation.py.
So how about to check if both ID and TYPE are present? I pushed such change in ec9b177 just in case.
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.
Sure, you're totally right.
44a3559
to
897594a
Compare
@adrienverge Are there any issues left behind or I forgot? If it's OK, I'll squash all of them into a few commits to prepare you can easily merge them. |
I don't know about issues, I still need to take time to test and review. But you can squash 👍 |
6ae0956
to
9f9e282
Compare
Thanks! I squashed them into 3 commits. |
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.
Hello @ssato, thanks for the work! Here is a first review.
The first thing I have to say is that it's not obvious how to make a plugin, or how to enable it. Hence, I propose some modifications.
-
Simplify
docs/development.rst
a lot:Develop rule plugins -------------------- 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 plugins are Python packages installable using pip and distributed under GPLv3+. To develop yamllint rules, it is recommended to copy the example from ``tests/plugins/yamllint_plugin_example``, and follow its README file. Also, the core rules themselves in ``yamllint/rules`` are good references.
-
Write most of the rules how-to inside
tests/plugins/yamllint_plugin_example/README.rst
. -
Name the example
yamllint_plugin_example
(not justexample
) and make it a real distributable example. This way, any user would easily know where to start.For this, it should contain:
- A
README.rst
file, that explains what you did previously, and how to install the plugin usingpip install
, etc. setup.py
:import setuptools setuptools.setup()
setup.cfg
:[metadata] name = yamllint_plugin_example version = 1.0.0 [options] packages = find: install_requires = yamllint [options.entry_points] yamllint.plugins.rules = example = yamllint_plugin_example
- For completeness, I propose to add a file
tests/plugins/yamllint_plugin_example/yamllint_plugin_example/random_failure.py
:# -*- 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')
- A
-
Idea: rename
override-comments
toforbid-comments
? -
Inside the plugin, change
RULES_MAP = {
toRULES = {
, for simplicity.
What do you think?
Thanks for the comments! @adrienverge. Before going into details, I think that it should be better to have a standalone git repo separate from yamllint's repo as a rules plugin reference implementation fully tested, git-{clone,fork}-able, and provides the followings.
So, I made changes as you said basically but those might be a temporal solution.
I agree, and changed docs/development.rst as you said and add tests/yamllint_plugin_example/README.rst to provide detailed information.
I just renamed from tests/plugin to tests/yamllint_plugin_example and from tests/plugin/example/ to tests/yamllint_plugin_rules to run tests easier, add setup.py.example because the file named setup.py causes tests error, setup.cfg and README.rst I mentioned before.
Thanks! I like it and added.
I agree and renamed it.
I agree. I changed RULES_MAP to RULES and simplified it because it's not necessary to be a dict. |
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.
Thanks @ssato, it's starting to look good!
Please see my remarks below, I fixed some of them + other things in commit c43a149 that I pushed directly on your branch (feel free to squash if you want).
-
I think that it should be better to have a standalone git repo separate from yamllint's repo as a rules plugin reference implementation fully tested, git-{clone,fork}-able, and provides the followings.
I get your point, but in my opinion it's needed to have the plugin example in the same repo, for some of the same reasons that you describe: being able to test both:
- the plugins,
- the yamllint code that uses plugins.By the way you renamed
setup.py
tosetup.py.example
because "it caused tests error": what errors do you encounter? On my computer, using the normal filenamesetup.py
works fine, andpython -m unittest discover
passes.Most importantly, this feature lacks tests. In
test_plugins.py
we need tests that simulate a yamllint with plugins (for example the ones intests/yamllint_plugin_example/rules
), and run the linter on fake files, and makes sure everything is reported as expected.
This way, future bugs or regressions on the plugin code will be noticed.
For this purpose, maybe it would help to add a 3rd fake rule (very simple, again)? An idea: ruleno-forty-two
, that would error when the number42
is found as ayaml.ValueToken
? It would be easy to unit-test. -
Again: making code more complex (adding arguments to
load_plugin_rules_itr(entry_points=None, group=PACKAGE_GROUP)
) just to be able to test it is a bad practice. We should use mocks instead.
I fixed this in my commit.
Good luck! Next time, it would be awesome if the code was perfect, so we can merge it!
"""Check if comments are found. | ||
""" |
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.
I think these docstrings everywhere aren't needed, they say exactly what the file/function already says. To me it brings more confusion. These examples should instead be short and simple.
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.
Thanks! I rebased it to follow changes in master branch, commit and pushed 0588797 for this.
tests/test_plugins.py
Outdated
self.assertFalse(fun(rule_mod)) | ||
|
||
@unittest.skipIf(not mock, "unittest.mock is not available") | ||
@mock.patch('pkg_resources.iter_entry_points') |
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.
Tests fail on Python 2.7 because of this change I just pushed (because mock == False
on Python 2).
To solve it, I see at least 2 options:
- Reintroduce your code in
.travis.yml
(from enhancement: add rules plugin support #315 (comment)). - Use another way to call mock, for example:
def test_load_plugin_rules_itr(self): with mock.patch('pkg_resources.iter_entry_points') as iter_entry_points: iter_entry_points.return_value = []
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.
I chosen 2 because Python 2.7 support might be stopped not too far ahead.
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.
OK! As you prefer.
Indeed all Python 2 related code will be dropped in 3 months.
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.
Thanks, I pushed ca6274e for this.
Sorry to add another code needs review but I pushed 48462f5 for this issue that it lacks of plugin tests. |
Hello @ssato, I think the main code (in However I was talking about testing the yamllint code that uses plugins. Testing that the
|
Hello @adrienverge,
Thanks a lot!
I'm not sure what you want exactly but added each plugin test cases in tests/yamllint_plugin_example/tests/ and some integration test cases run linter with disabled plugins, will be generated dynamically as same as tests/test_spec_examples.py does in tests/test_plugins.py. |
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.
Hello @ssato,
I'm talking about removing tests from tests/yamllint_plugin_example/tests/
(or leaving just very basic ones, just to encourage developers to write tests for their plugins) and moving all these tests to tests/test_plugins.py
. What is most useful is to check that yamllint correctly loads these rules, and correctly uses them.
Please don't change tests/test_spec_examples.py
because it's not meant for that.
if not self.rule_id: | ||
return |
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.
if not self.rule_id: | |
return | |
assert self.rule_id |
if self.rule_id
is not set, it's probably a problem and should be reported?
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.
Thanks! Absolutely, right. Fixed in 007b9cf.
from .plugins_common import ( | ||
mock, PluginTestCase | ||
) |
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.
Can you make this fit one line to match the project style?
(same at other places in this commit)
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.
Fixed in f100ced.
mock = False | ||
|
||
import yamllint.rules | ||
from .common import RuleTestCase |
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.
I don't like the idea of copying test/common.py
to tests/yamllint_plugin_example/tests/common.py
, with the exact same content. We would have to maintain two identic files, which is cumbersome for multiple reasons.
I propose to remove tests/yamllint_plugin_example/tests/common.py
, and use:
from .common import RuleTestCase | |
from ...common import RuleTestCase |
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.
I did so because I want that plugin developers can devel their plugins by copying tests/yamllint_plugin_example with least modifications but I understand that and removed the copy.
from ..rules import RULES | ||
|
||
|
||
PLUGIN_RULES = dict(RULES) |
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.
Why this line? Why not just using RULES
on line 39?
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.
Thanks! Also absolutely, right. Fixed in 09e6530.
tests/test_plugins.py
Outdated
import yamllint.rules | ||
|
||
|
||
PLUGIN_RULES = dict(example.RULES) |
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.
(same as previous comment)
Why this line? Why not just using example.RULES
on lines 104-117?
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.
Same as the above.
I think that change should not change its original behavior. And I did so to achieve the following. I can't think of any good ideas other than that now.
|
b81be25
to
79626a3
Compare
I did like you said. Could you please check the commit c377e63?
I see and reverted the change in the commit ab2eb97. |
Hello @ssato, thanks again for your work. |
Add plugin support using setuptools (pkg_resources) plugin mechanism to yamllint to allow users to add their own custom lint rule plugins. Also add some plugin support test cases, an example plugin as a reference, and doc section about how to develop rules' plugins. Signed-off-by: Satoru SATOH <satoru.satoh@gmail.com> Co-authored-by: Adrien Vergé
Very sorry to left it and gave no response to you for a long time. A lot happened in my personal life and could not work on this. Anyway, I self-reviewed this again and have confident it works well and resolved all of the issues you kindly pointed out AFAIK. |
Hi there! |
Hello @perseoGI, no, it's not possible to extend yamllint to create custom rules. Although I thank Satoru for trying with this pull request in 2020, I now think such addition is a bad idea. Plugin support would require an immutable API and much work to maintain. It's preferable to upstream rules that make sense (those about the form of YAML, not the content) inside the yamllint project itself. |
@adrienverge understood, thank you for your response! |
Add plugin support using setuptools (pkg_resources) plugin mechanism to
YAML Lint to allow users to add their own custom lint rule plugins.
Signed-off-by: Satoru SATOH satoru.satoh@gmail.com