def perform(self): from restructuredtext_lint import lint_file # pylint:disable=import-error result = 0 for filename in self.file_in: errors = lint_file(filename, encoding=self.encoding) if len(errors) == 0: continue relpath = os.path.relpath(filename) if relpath.startswith('.'): relpath = filename print_filename = True for error in errors: ignored = False for re_ignore in self.regex_ignores: if re_ignore.match(error.message): ignored = True break if ignored: continue if print_filename: print('************* File ' + relpath) print_filename = False if error.level > 2: result += 1 message = error.message.replace('\n', ' ') print('%s: %i: %s' % (error.type[0], error.line, message)) return result
def lint(dir=SOURCE_DIR): errors = [] for root, subdirs, files in os.walk(SOURCE_DIR): for filename in files: extension = filename.rpartition('.')[2].lower() if extension == "rst": linting_errors = rst_lint.lint_file(os.path.join(root, filename)) if linting_errors: errors.extend(linting_errors) if errors: for error in errors: message = "{full_file_path}:{line_no}: {message}\n".format( full_file_path=os.path.relpath(error.source), line_no=error.line, message=error.message, ) if error.type == "WARNING": sys.stdout.write(message) else: sys.stderr.write(message) if any(error.type == "ERROR" for error in errors): sys.exit(1) else: sys.exit(0)
def test_invalid_target(self): """A document with an invalid target name raises an error This is a regression test for https://github.com/twolfson/restructuredtext-lint/issues/6 """ filepath = os.path.join(__dir__, 'test_files', 'invalid_target.rst') errors = restructuredtext_lint.lint_file(filepath) self.assertIn('Unknown target name', errors[0].message)
def test_invalid_line_mismatch(self): """A document with an overline/underline mismatch raises an error This is a regression test for https://github.com/twolfson/restructuredtext-lint/issues/7 """ filepath = os.path.join(__dir__, 'test_files', 'invalid_line_mismatch.rst') errors = restructuredtext_lint.lint_file(filepath) self.assertIn('Title overline & underline mismatch', errors[0].message)
def test_invalid_line_mismatch(self): """A document with an overline/underline mismatch raises an error This is a regression test for https://github.com/twolfson/restructuredtext-lint/issues/7 """ filepath = __dir__ + '/test_files/invalid_line_mismatch.rst' errors = restructuredtext_lint.lint_file(filepath) self.assertIn('Title overline & underline mismatch', errors[0].message)
def test_invalid_target(self): """A document with an invalid target name raises an error This is a regression test for https://github.com/twolfson/restructuredtext-lint/issues/6 """ filepath = __dir__ + '/test_files/invalid_target.rst' errors = restructuredtext_lint.lint_file(filepath) self.assertIn('Unknown target name', errors[0].message)
def check_file(self, file_name, ignore_info=True): """Lint check the specified file, printing the findings to the console. Arguments: file_name {str} -- Path and name of the file to check Keyword Arguments: ignore_info {bool} -- Determines whether INFO notices should be ignored (default: {True}) """ print('Checking {0}'.format(file_name), end='', flush=True) self.checked_count += 1 if os.path.isfile(file_name): try: err_processed = False errs = restructuredtext_lint.lint_file(file_name) if errs: for err in errs: err_process = True if err.type == 'INFO': if ignore_info: err_process = False else: m = RE_TEST_DIRECTIVE_1.match(err.message) err_process = err_process and not bool( m and m.group(1) in IGNORE_DIRECTIVES) m = RE_TEST_ROLE_1.match(err.message) err_process = err_process and not bool( m and m.group(1) in IGNORE_ROLES) if (err.type == 'ERROR' or err.type == 'SEVERE' ) and err.message.startswith('Unknown'): m = RE_TEST_DIRECTIVE_2.match(err.message) err_process = err_process and not bool( m and m.group(1) in IGNORE_DIRECTIVES) m = RE_TEST_ROLE_2.match(err.message) err_process = err_process and not bool( m and m.group(1) in IGNORE_ROLES) if err_process: err_processed = True print('\n [{0}] Line {1}: {2}'.format( err.type, err.line, err.message), end='', flush=True) if err.type == 'WARNING': self.warning_count += 1 elif err.type == 'INFO': self.info_count += 1 else: # Includes 'ERROR' and 'SEVERE' self.error_count += 1 print('' if err_processed else ' [OK]') except Exception as ex: print('\n [ERROR] Line 0: Error reading file. ({0})'.format( ex, )) self.error_count += 1 else: print('\n [ERROR] Line 0: File not found.') self.error_count += 1
def test_second_heading_short_line_number(self): """A document with a short second heading raises errors that include a line number This is a regression test for https://github.com/twolfson/restructuredtext-lint/issues/5 """ filepath = os.path.join(__dir__, 'test_files', 'second_short_heading.rst') errors = restructuredtext_lint.lint_file(filepath) self.assertEqual(errors[0].line, 6) self.assertEqual(errors[0].source, filepath)
def test_invalid_link(self): """A document with a bad link raises an error This is a regression test for https://github.com/twolfson/restructuredtext-lint/issues/12 """ filepath = os.path.join(_dir, 'test_files', 'invalid_link.rst') errors = restructuredtext_lint.lint_file(filepath) self.assertIn('Anonymous hyperlink mismatch: 1 references but 0 targets.', errors[0].message) self.assertIn('Hyperlink target "hello" is not referenced.', errors[1].message)
def test_second_heading_short_line_number(self): """A document with a short second heading raises errors that include a line number This is a regression test for https://github.com/twolfson/restructuredtext-lint/issues/5 """ filepath = os.path.join(_dir, 'test_files', 'second_short_heading.rst') errors = restructuredtext_lint.lint_file(filepath) self.assertEqual(errors[0].line, 6) self.assertEqual(errors[0].source, filepath)
def lint_files(self, files): cwd = os.getcwd() os.chdir(self.working_dir) for path in files: errors = rstlinter.lint_file(path, 'utf-8') for error in errors: msg = '{}: {}'.format(error.type, error.message) yield Problem(error.source, error.line, msg, self.name) os.chdir(cwd)
def test_invalid_link(self): """A document with a bad link raises an error This is a regression test for https://github.com/twolfson/restructuredtext-lint/issues/12 """ filepath = os.path.join(__dir__, 'test_files', 'invalid_link.rst') errors = restructuredtext_lint.lint_file(filepath) self.assertIn('Anonymous hyperlink mismatch: 1 references but 0 targets.', errors[0].message) self.assertIn('Hyperlink target "hello" is not referenced.', errors[1].message)
def lint_rst(repo, cf): msgs = restructuredtext_lint.lint_file(cf.name) for msg in msgs: if msg.line == None: line = 0 else: line = msg.line if msg.level >= 3: cf.error("%s:%d: %s: %s" % (cf.name, line, msg.type, msg.message), line) else: cf.warning( "%s:%d: %s: %s" % (cf.name, line, msg.type, msg.message), line)
def lint_rst(repo, cf): msgs = restructuredtext_lint.lint_file(cf.name) for msg in msgs: if msg.line == None: line = 0 else: line = msg.line if msg.level >= 3: cf.error("%s:%d: %s: %s" % (cf.name, line, msg.type, msg.message), line) else: cf.warning("%s:%d: %s: %s" % (cf.name, line, msg.type, msg.message), line)
def check_rst(argv=None): """ Hook entry point """ parser = argparse.ArgumentParser() parser.add_argument('filenames', nargs='*', help='RST filenames to check.') args = parser.parse_args(argv) retval = 0 for filename in args.filenames: errors = restructuredtext_lint.lint_file(filename) if errors: print('{}: Failed to RST parse ({})'.format(filename, errors)) retval = 1 return retval
def checkRstLint(document): import restructuredtext_lint # pylint: disable=I0021,import-error print("Checking %r for proper restructed text ..." % document) lint_results = restructuredtext_lint.lint_file(document, encoding="utf8") lint_error = False for lint_result in lint_results: # Not an issue. if lint_result.message.startswith("Duplicate implicit target name:"): continue print(lint_result) lint_error = True if lint_error: sys.exit("Error, no lint clean rest.") print("OK.")
def checkRstLint(document): import restructuredtext_lint # @UnresolvedImport pylint:disable=I0021,import-error print("Checking %r for proper restructed text ..." % document) lint_results = restructuredtext_lint.lint_file(document, encoding="utf8") lint_error = False for lint_result in lint_results: # Not an issue. if lint_result.message.startswith("Duplicate implicit target name:"): continue print(lint_result) lint_error = True if lint_error: sys.exit("Error, no lint clean rest.") print("OK.")
def lint(dir=SOURCE_DIR, log_level=WARNING): errors = [] for root, subdirs, files in os.walk(SOURCE_DIR): for filename in files: extension = filename.rpartition('.')[2].lower() if extension == "rst": abs_path = os.path.abspath(os.path.join(root, filename)) rel_path = os.path.relpath(abs_path, SOURCE_DIR) # Sphinx maintains a list of `docnames` that it has found which # are the relative paths to the docs from the SOURCE_DIR # without the file extension. The `sphinx.env.temp_data` # dictionary needs to have the current docname populuated while # it's being processed for the Sphinx directives to function # properly. docname = rel_path.rpartition('.')[0] sphinx.env.temp_data['docname'] = docname linting_errors = rst_lint.lint_file( os.path.join(root, filename)) if linting_errors: errors.extend(linting_errors) if errors: for error in errors: message = "{prefix}: {full_file_path}:{line_no}: {message}\n".format( prefix=error.type, full_file_path=os.path.relpath(error.source), line_no=error.line, message=error.message, ) if LEVELS[error.type] < log_level: continue elif LEVELS[error.type] < ERROR: sys.stdout.write(message) else: sys.stderr.write(message) if any((error.type == "ERROR" or error.type == "WARNING") for error in errors): sys.exit(1) else: sys.exit(0)
def lint(dir=SOURCE_DIR, log_level=WARNING): errors = [] for root, subdirs, files in os.walk(SOURCE_DIR): for filename in files: extension = filename.rpartition('.')[2].lower() if extension == "rst": abs_path = os.path.abspath(os.path.join(root, filename)) rel_path = os.path.relpath(abs_path, SOURCE_DIR) # Sphinx maintains a list of `docnames` that it has found which # are the relative paths to the docs from the SOURCE_DIR # without the file extension. The `sphinx.env.temp_data` # dictionary needs to have the current docname populuated while # it's being processed for the Sphinx directives to function # properly. docname = rel_path.rpartition('.')[0] sphinx.env.temp_data['docname'] = docname linting_errors = rst_lint.lint_file(os.path.join(root, filename)) if linting_errors: errors.extend(linting_errors) if errors: for error in errors: message = "{prefix}: {full_file_path}:{line_no}: {message}\n".format( prefix=error.type, full_file_path=os.path.relpath(error.source), line_no=error.line, message=error.message, ) if LEVELS[error.type] < log_level: continue elif LEVELS[error.type] < ERROR: sys.stdout.write(message) else: sys.stderr.write(message) if any(error.type == "ERROR" for error in errors): sys.exit(1) else: sys.exit(0)
def checkRstLint(document): print("Checking %r for proper restructed text ..." % document) lint_results = restructuredtext_lint.lint_file(document, encoding="utf8") lint_error = False for lint_result in lint_results: # Not an issue. if lint_result.message.startswith("Duplicate implicit target name:"): continue if lint_result.message.startswith('No directive entry for "youtube"'): continue if lint_result.message.startswith('Unknown directive type "youtube"'): continue print(lint_result) lint_error = True if lint_error: sys.exit("Error, no lint clean rest.") print("OK.")
# Load in our dependencies from docutils.parsers.rst.directives import register_directive from sphinx.directives.code import Highlight import restructuredtext_lint # Load our new directive register_directive('highlight', Highlight) # Lint our README errors = restructuredtext_lint.lint_file('docs/sphinx/README.rst') print errors[0].message # Error in "highlight" directive: no content permitted.
def test_encoding_utf8(self): """A document with utf-8 characters is valid.""" filepath = os.path.join(__dir__, 'test_files', 'utf8.rst') errors = restructuredtext_lint.lint_file(filepath, encoding='utf-8') self.assertEqual(errors, [])
def test_rst_syntax(filename): lint_result = rstlint.lint_file(filename) error_msg = '{0}: {1}'.format( filename, _format_rst_lint_errors(lint_result)) assert len(lint_result) == 0, error_msg
def test_restructuredtext(self): """Lint RST files.""" files = os.listdir("{0}/docs".format(self.working_directory)) for name in files: path = "{0}/docs/{1}".format(self.working_directory, name) restructuredtext_lint.lint_file(filepath=path)
# Load in our dependencies from docutils.parsers.rst.directives import register_directive from sphinx.directives.code import Highlight import restructuredtext_lint # Load our new directive register_directive('highlight', Highlight) # Lint our README errors = restructuredtext_lint.lint_file('docs/sphinx/README.rst') print errors[ 0].message # Error in "highlight" directive: no content permitted.
def test_rst_syntax(filename): lint_result = rstlint.lint_file(filename) error_msg = '{0}: {1}'.format(filename, _format_rst_lint_errors(lint_result)) assert len(lint_result) == 0, error_msg