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
Example #2
0
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)
Example #3
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)
Example #4
0
    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)
Example #5
0
    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)
Example #6
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 = __dir__ + '/test_files/invalid_target.rst'
        errors = restructuredtext_lint.lint_file(filepath)
        self.assertIn('Unknown target name', errors[0].message)
Example #7
0
    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
Example #8
0
    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)
Example #9
0
    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)
Example #10
0
    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)
Example #11
0
 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)
Example #12
0
    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)
Example #13
0
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)
Example #14
0
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)
Example #15
0
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
Example #16
0
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.")
Example #17
0
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.")
Example #18
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" or error.type == "WARNING")
           for error in errors):
        sys.exit(1)
    else:
        sys.exit(0)
Example #19
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)
Example #20
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.")
Example #21
0
# 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.
Example #22
0
 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, [])
Example #23
0
 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, [])
Example #24
0
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
Example #25
0
 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)
Example #26
0
# 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.
Example #27
0
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