Add error linting to ensure that rst format is not invalid
This commit is contained in:
parent
c53e54c6fc
commit
83e9c42215
|
@ -75,6 +75,18 @@ class CheckCarriageReturn(LineCheck):
|
|||
yield ('D004', 'Found literal carriage return')
|
||||
|
||||
|
||||
class CheckValidity(ContentCheck):
|
||||
REPORTS = frozenset(["D000"])
|
||||
|
||||
def report_iter(self, parsed_file):
|
||||
for error in parsed_file.errors:
|
||||
if error.line is None:
|
||||
continue
|
||||
if error.level <= 1:
|
||||
continue
|
||||
yield (error.line, 'D000', error.message)
|
||||
|
||||
|
||||
class CheckMaxLineLength(ContentCheck):
|
||||
REPORTS = frozenset(["D001"])
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
"""Check documentation for simple style requirements.
|
||||
|
||||
What is checked:
|
||||
- invalid rst format - D000
|
||||
- lines should not be longer than 79 characters - D001
|
||||
- exception: line with no whitespace except in the beginning
|
||||
- exception: lines with http or https urls
|
||||
|
@ -107,6 +108,7 @@ def extract_config(args):
|
|||
|
||||
def fetch_checks(cfg):
|
||||
base = [
|
||||
checks.CheckValidity(cfg),
|
||||
checks.CheckTrailingWhitespace(cfg),
|
||||
checks.CheckIndentationNoTab(cfg),
|
||||
checks.CheckCarriageReturn(cfg),
|
||||
|
|
|
@ -21,7 +21,9 @@ import os
|
|||
|
||||
import six
|
||||
|
||||
from docutils import core
|
||||
from docutils import frontend
|
||||
from docutils import nodes as docutils_nodes
|
||||
from docutils import parsers as docutils_parser
|
||||
from docutils import utils
|
||||
|
||||
|
@ -33,6 +35,67 @@ class ParsedFile(object):
|
|||
self._raw_content = None
|
||||
self._encoding = encoding
|
||||
self._doc = None
|
||||
self._errors = None
|
||||
self._defaults = {
|
||||
'input_encoding': self._encoding,
|
||||
'halt_level': 5,
|
||||
'report_level': 5,
|
||||
'quiet': True,
|
||||
'file_insertion_enabled': False,
|
||||
'traceback': True,
|
||||
# Development use only.
|
||||
'dump_settings': False,
|
||||
'dump_internals': False,
|
||||
'dump_transforms': False,
|
||||
}
|
||||
|
||||
@property
|
||||
def errors(self):
|
||||
if self._errors is not None:
|
||||
return self._errors
|
||||
# Borrowed from pypi package restructuredtext-lint but modified to work
|
||||
# better when there exists fatal/critical errors.
|
||||
pub = core.Publisher(None, None, None, settings=None)
|
||||
pub.set_components('standalone', 'restructuredtext', 'pseudoxml')
|
||||
defaults = dict(self._defaults)
|
||||
settings = pub.get_settings(**defaults)
|
||||
pub.set_io()
|
||||
reader = pub.reader
|
||||
document = utils.new_document(self.filename, settings)
|
||||
document.reporter.stream = None
|
||||
# Collect errors via an observer
|
||||
errors = []
|
||||
def error_collector(data):
|
||||
# Mutate the data since it was just generated
|
||||
data.line = data['line']
|
||||
data.source = data['source']
|
||||
data.level = data['level']
|
||||
data.type = data['type']
|
||||
data.message = docutils_nodes.Element.astext(data.children[0])
|
||||
data.full_message = docutils_nodes.Element.astext(data)
|
||||
# Save the error
|
||||
errors.append(data)
|
||||
document.reporter.attach_observer(error_collector)
|
||||
reader.parser.parse(self.contents, document)
|
||||
document.transformer.populate_from_components(
|
||||
(pub.source, pub.reader, pub.reader.parser, pub.writer,
|
||||
pub.destination))
|
||||
transformer = document.transformer
|
||||
while transformer.transforms:
|
||||
if not transformer.sorted:
|
||||
# Unsorted initially, and whenever a transform is added.
|
||||
transformer.transforms.sort()
|
||||
transformer.transforms.reverse()
|
||||
transformer.sorted = True
|
||||
transform = transformer.transforms.pop()
|
||||
priority, transform_class, pending, kwargs = transform
|
||||
transform = transform_class(transformer.document,
|
||||
startnode=pending)
|
||||
transform.apply(**kwargs)
|
||||
transformer.applied.append((priority, transform_class,
|
||||
pending, kwargs))
|
||||
self._errors = errors
|
||||
return errors
|
||||
|
||||
@property
|
||||
def document(self):
|
||||
|
@ -43,18 +106,7 @@ class ParsedFile(object):
|
|||
# mature).
|
||||
parser_cls = docutils_parser.get_parser_class("rst")
|
||||
parser = parser_cls()
|
||||
defaults = {
|
||||
'input_encoding': self.encoding,
|
||||
'halt_level': 5,
|
||||
'report_level': 5,
|
||||
'quiet': True,
|
||||
'file_insertion_enabled': False,
|
||||
'traceback': True,
|
||||
# Development use only.
|
||||
'dump_settings': False,
|
||||
'dump_internals': False,
|
||||
'dump_transforms': False,
|
||||
}
|
||||
defaults = dict(self._defaults)
|
||||
opt = frontend.OptionParser(components=[parser], defaults=defaults)
|
||||
doc = utils.new_document(source_path=self.filename,
|
||||
settings=opt.get_default_values())
|
||||
|
|
Loading…
Reference in New Issue