diff --git a/changelogs/fragments/ansible-test-rstcheck-core-only.yml b/changelogs/fragments/ansible-test-rstcheck-core-only.yml new file mode 100644 index 00000000000..e3a13aeae4a --- /dev/null +++ b/changelogs/fragments/ansible-test-rstcheck-core-only.yml @@ -0,0 +1,2 @@ +minor_changes: + - ansible-test - The ``rstcheck`` sanity test is no longer used for collections, but continues to be used for ansible-core. diff --git a/test/lib/ansible_test/_data/requirements/sanity.rstcheck.txt b/test/lib/ansible_test/_data/requirements/sanity.rstcheck.txt deleted file mode 100644 index 3a5eeed1e43..00000000000 --- a/test/lib/ansible_test/_data/requirements/sanity.rstcheck.txt +++ /dev/null @@ -1 +0,0 @@ -rstcheck diff --git a/test/lib/ansible_test/_data/sanity/rstcheck/ignore-substitutions.txt b/test/lib/ansible_test/_data/sanity/rstcheck/ignore-substitutions.txt deleted file mode 100644 index 961e9bd9fd0..00000000000 --- a/test/lib/ansible_test/_data/sanity/rstcheck/ignore-substitutions.txt +++ /dev/null @@ -1,5 +0,0 @@ -version -release -today -br -_ diff --git a/test/lib/ansible_test/_internal/sanity/rstcheck.py b/test/lib/ansible_test/_internal/sanity/rstcheck.py deleted file mode 100644 index 2d8a01d544c..00000000000 --- a/test/lib/ansible_test/_internal/sanity/rstcheck.py +++ /dev/null @@ -1,95 +0,0 @@ -"""Sanity test using rstcheck.""" -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -import os - -from .. import types as t - -from ..sanity import ( - SanitySingleVersion, - SanityMessage, - SanityFailure, - SanitySuccess, - SANITY_ROOT, -) - -from ..target import ( - TestTarget, -) - -from ..util import ( - SubprocessError, - parse_to_list_of_dict, - read_lines_without_comments, - find_python, -) - -from ..util_common import ( - run_command, -) - -from ..config import ( - SanityConfig, -) - - -class RstcheckTest(SanitySingleVersion): - """Sanity test using rstcheck.""" - def filter_targets(self, targets): # type: (t.List[TestTarget]) -> t.List[TestTarget] - """Return the given list of test targets, filtered to include only those relevant for the test.""" - return [target for target in targets if os.path.splitext(target.path)[1] in ('.rst',)] - - def test(self, args, targets, python_version): - """ - :type args: SanityConfig - :type targets: SanityTargets - :type python_version: str - :rtype: TestResult - """ - ignore_file = os.path.join(SANITY_ROOT, 'rstcheck', 'ignore-substitutions.txt') - ignore_substitutions = sorted(set(read_lines_without_comments(ignore_file, remove_blank_lines=True))) - - settings = self.load_processor(args) - - paths = [target.path for target in targets.include] - - cmd = [ - find_python(python_version), - '-m', 'rstcheck', - '--report', 'warning', - '--ignore-substitutions', ','.join(ignore_substitutions), - ] + paths - - try: - stdout, stderr = run_command(args, cmd, capture=True) - status = 0 - except SubprocessError as ex: - stdout = ex.stdout - stderr = ex.stderr - status = ex.status - - if stdout: - raise SubprocessError(cmd=cmd, status=status, stderr=stderr, stdout=stdout) - - if args.explain: - return SanitySuccess(self.name) - - pattern = r'^(?P[^:]*):(?P[0-9]+): \((?PINFO|WARNING|ERROR|SEVERE)/[0-4]\) (?P.*)$' - - results = parse_to_list_of_dict(pattern, stderr) - - results = [SanityMessage( - message=r['message'], - path=r['path'], - line=int(r['line']), - column=0, - level=r['level'], - ) for r in results] - - settings.process_errors(results, paths) - - if results: - return SanityFailure(self.name, messages=results) - - return SanitySuccess(self.name) diff --git a/test/sanity/code-smell/rstcheck.json b/test/sanity/code-smell/rstcheck.json new file mode 100644 index 00000000000..870c19ffddd --- /dev/null +++ b/test/sanity/code-smell/rstcheck.json @@ -0,0 +1,6 @@ +{ + "output": "path-line-column-message", + "extensions": [ + ".rst" + ] +} diff --git a/test/sanity/code-smell/rstcheck.py b/test/sanity/code-smell/rstcheck.py new file mode 100755 index 00000000000..7866afa8913 --- /dev/null +++ b/test/sanity/code-smell/rstcheck.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python +"""Sanity test using rstcheck and sphinx.""" +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import re +import subprocess +import sys + + +def main(): + paths = sys.argv[1:] or sys.stdin.read().splitlines() + + encoding = 'utf-8' + + ignore_substitutions = ( + 'br', + ) + + cmd = [ + sys.executable, + '-m', 'rstcheck', + '--report', 'warning', + '--ignore-substitutions', ','.join(ignore_substitutions), + ] + paths + + process = subprocess.run(cmd, + stdin=subprocess.DEVNULL, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + + if process.stdout: + raise Exception(process.stdout) + + pattern = re.compile(r'^(?P[^:]*):(?P[0-9]+): \((?PINFO|WARNING|ERROR|SEVERE)/[0-4]\) (?P.*)$') + + results = parse_to_list_of_dict(pattern, process.stderr.decode(encoding)) + + for result in results: + print('%s:%s:%s: %s' % (result['path'], result['line'], 0, result['message'])) + + +def parse_to_list_of_dict(pattern, value): + matched = [] + unmatched = [] + + for line in value.splitlines(): + match = re.search(pattern, line) + + if match: + matched.append(match.groupdict()) + else: + unmatched.append(line) + + if unmatched: + raise Exception('Pattern "%s" did not match values:\n%s' % (pattern, '\n'.join(unmatched))) + + return matched + + +if __name__ == '__main__': + main() diff --git a/test/sanity/code-smell/rstcheck.requirements.txt b/test/sanity/code-smell/rstcheck.requirements.txt new file mode 100644 index 00000000000..4674b8dffe0 --- /dev/null +++ b/test/sanity/code-smell/rstcheck.requirements.txt @@ -0,0 +1,2 @@ +rstcheck +sphinx # required for full functionality