2016-07-10 10:18:24 +00:00
|
|
|
#!/usr/bin/env python
|
|
|
|
# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
|
|
# For details: https://github.com/PyCQA/pylint/blob/master/COPYING
|
|
|
|
|
|
|
|
"""Script used to generate the extensions file before building the actual documentation."""
|
|
|
|
|
|
|
|
import os
|
|
|
|
import re
|
|
|
|
import sys
|
|
|
|
|
|
|
|
import sphinx
|
|
|
|
|
2019-05-19 10:10:25 +00:00
|
|
|
from pylint.constants import MAIN_CHECKER_NAME
|
2016-07-10 10:18:24 +00:00
|
|
|
from pylint.lint import PyLinter
|
2019-06-10 08:37:32 +00:00
|
|
|
from pylint.utils import get_rst_title
|
2016-07-10 10:18:24 +00:00
|
|
|
|
|
|
|
# Some modules have been renamed and deprecated under their old names.
|
|
|
|
# Skip documenting these modules since:
|
|
|
|
# 1) They are deprecated, why document them moving forward?
|
|
|
|
# 2) We can't load the deprecated module and the newly renamed module at the
|
|
|
|
# same time without getting naming conflicts
|
2019-03-09 10:23:15 +00:00
|
|
|
DEPRECATED_MODULES = ["check_docs"] # ==> docparams
|
|
|
|
|
2016-07-10 10:18:24 +00:00
|
|
|
|
|
|
|
def builder_inited(app):
|
|
|
|
"""Output full documentation in ReST format for all extension modules"""
|
|
|
|
# PACKAGE/docs/exts/pylint_extensions.py --> PACKAGE/
|
|
|
|
base_path = os.path.dirname(
|
2019-03-09 10:23:15 +00:00
|
|
|
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
)
|
2016-07-10 10:18:24 +00:00
|
|
|
# PACKAGE/ --> PACKAGE/pylint/extensions
|
2019-03-09 10:23:15 +00:00
|
|
|
ext_path = os.path.join(base_path, "pylint", "extensions")
|
2016-07-10 10:18:24 +00:00
|
|
|
modules = []
|
|
|
|
doc_files = {}
|
|
|
|
for filename in os.listdir(ext_path):
|
|
|
|
name, ext = os.path.splitext(filename)
|
2019-03-09 10:23:15 +00:00
|
|
|
if name[0] == "_" or name in DEPRECATED_MODULES:
|
2016-07-10 10:18:24 +00:00
|
|
|
continue
|
2019-03-09 10:23:15 +00:00
|
|
|
if ext == ".py":
|
|
|
|
modules.append("pylint.extensions.%s" % name)
|
|
|
|
elif ext == ".rst":
|
|
|
|
doc_files["pylint.extensions." + name] = os.path.join(ext_path, filename)
|
2017-12-11 08:26:32 +00:00
|
|
|
modules.sort()
|
2016-07-10 10:18:24 +00:00
|
|
|
if not modules:
|
|
|
|
sys.exit("No Pylint extensions found?")
|
|
|
|
|
|
|
|
linter = PyLinter()
|
|
|
|
linter.load_plugin_modules(modules)
|
|
|
|
|
2019-03-09 10:23:15 +00:00
|
|
|
extensions_doc = os.path.join(
|
|
|
|
base_path, "doc", "technical_reference", "extensions.rst"
|
|
|
|
)
|
|
|
|
with open(extensions_doc, "w") as stream:
|
2019-06-10 06:52:48 +00:00
|
|
|
stream.write(
|
2019-06-10 08:37:32 +00:00
|
|
|
get_rst_title("Optional Pylint checkers in the extensions module", "=")
|
2019-06-10 06:52:48 +00:00
|
|
|
)
|
2016-07-10 10:18:24 +00:00
|
|
|
stream.write("Pylint provides the following optional plugins:\n\n")
|
|
|
|
for module in modules:
|
2018-05-22 18:37:07 +00:00
|
|
|
stream.write("- :ref:`{}`\n".format(module))
|
2016-07-10 10:18:24 +00:00
|
|
|
stream.write("\n")
|
2019-03-09 10:23:15 +00:00
|
|
|
stream.write(
|
|
|
|
"You can activate any or all of these extensions "
|
|
|
|
"by adding a ``load-plugins`` line to the ``MASTER`` "
|
|
|
|
"section of your ``.pylintrc``, for example::\n"
|
|
|
|
)
|
|
|
|
stream.write(
|
|
|
|
"\n load-plugins=pylint.extensions.docparams,"
|
|
|
|
"pylint.extensions.docstyle\n\n"
|
|
|
|
)
|
2019-06-09 21:01:01 +00:00
|
|
|
by_checker = get_plugins_info(linter, doc_files)
|
2019-06-10 07:22:49 +00:00
|
|
|
for checker, information in sorted(by_checker.items()):
|
|
|
|
linter._print_checker_doc(information, stream=stream)
|
2016-07-10 10:18:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
def get_plugins_info(linter, doc_files):
|
2019-06-09 21:01:01 +00:00
|
|
|
by_checker = {}
|
2016-07-10 10:18:24 +00:00
|
|
|
for checker in linter.get_checkers():
|
2019-05-19 10:10:25 +00:00
|
|
|
if checker.name == MAIN_CHECKER_NAME:
|
2016-07-10 10:18:24 +00:00
|
|
|
continue
|
|
|
|
module = checker.__module__
|
|
|
|
# Plugins only - skip over core checkers
|
|
|
|
if re.match("pylint.checkers", module):
|
|
|
|
continue
|
|
|
|
# Find any .rst documentation associated with this plugin
|
|
|
|
doc = ""
|
|
|
|
doc_file = doc_files.get(module)
|
|
|
|
if doc_file:
|
2020-03-19 18:20:05 +00:00
|
|
|
with open(doc_file) as f:
|
2016-07-10 10:18:24 +00:00
|
|
|
doc = f.read()
|
|
|
|
try:
|
2019-06-09 21:01:01 +00:00
|
|
|
by_checker[checker]["checker"] = checker
|
|
|
|
by_checker[checker]["options"] += checker.options_and_values()
|
|
|
|
by_checker[checker]["msgs"].update(checker.msgs)
|
|
|
|
by_checker[checker]["reports"] += checker.reports
|
|
|
|
by_checker[checker]["doc"] += doc
|
|
|
|
by_checker[checker]["module"] += module
|
2016-07-10 10:18:24 +00:00
|
|
|
except KeyError:
|
2019-06-09 21:01:01 +00:00
|
|
|
by_checker[checker] = {
|
|
|
|
"checker": checker,
|
2019-03-09 10:23:15 +00:00
|
|
|
"options": list(checker.options_and_values()),
|
|
|
|
"msgs": dict(checker.msgs),
|
|
|
|
"reports": list(checker.reports),
|
|
|
|
"doc": doc,
|
|
|
|
"module": module,
|
2016-07-10 10:18:24 +00:00
|
|
|
}
|
2019-06-09 21:01:01 +00:00
|
|
|
return by_checker
|
2016-07-10 10:18:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
def setup(app):
|
2019-03-09 10:23:15 +00:00
|
|
|
app.connect("builder-inited", builder_inited)
|
|
|
|
return {"version": sphinx.__display_version__}
|
2016-07-10 10:18:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
builder_inited(None)
|