diff --git a/bears/rust/RustClippyLintBear.py b/bears/rust/RustClippyLintBear.py new file mode 100644 index 0000000000..61bd06645c --- /dev/null +++ b/bears/rust/RustClippyLintBear.py @@ -0,0 +1,63 @@ +import json +import shutil +from os import linesep + +from coalib.bears.GlobalBear import GlobalBear +from coalib.misc.Shell import run_shell_command +from coalib.results.Result import Result +from coalib.results.RESULT_SEVERITY import RESULT_SEVERITY + + +class RustClippyLintBear(GlobalBear): + LANGUAGES = {'Rust'} + AUTHORS = {'The coala developers'} + AUTHORS_EMAILS = {'coala-devel@googlegroups.com'} + LICENSE = 'AGPL-3.0' + CAN_DETECT = { + 'Formatting', + 'Unused Code', + 'Syntax', + 'Unreachable Code', + 'Smell', + 'Code Simplification' + } + EXECUTABLE = 'cargo' + SEVERITY_MAP = { + # TODO: are there more? + 'warning': RESULT_SEVERITY.NORMAL, + 'error': RESULT_SEVERITY.MAJOR, + } + + @classmethod + def check_prerequisites(cls): + # TODO: - check for clippy itself + # - clippy also works via rustup nightly, so also check that. + if shutil.which('cargo') is None: + return 'cargo is not installed.' + else: + return True + + def run(self): + args = ('clippy', '--quiet', '--color', 'never', + '--', '-Z', 'unstable-options', '--error-format', 'json', + '--test') + _, stderr_output = run_shell_command( + (self.EXECUTABLE,) + args, + cwd=self.get_config_dir(), + universal_newlines=True) + for line in stderr_output.split(linesep): + if not line: + continue + yield self.new_result(json.loads(line)) + + def new_result(self, issue): + span = issue['spans'][0] + return Result.from_values( + origin=self.__class__.__name__, + message=issue['message'], + file=span['file_name'], + line=span['line_start'], + end_line=span['line_end'], + column=span['column_start'], + end_column=span['column_end'], + severity=self.SEVERITY_MAP[issue['level']]) diff --git a/bears/rust/__init__.py b/bears/rust/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/rust/.gitignore b/tests/rust/.gitignore new file mode 100644 index 0000000000..a9d37c560c --- /dev/null +++ b/tests/rust/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock diff --git a/tests/rust/RustClippyLintBearTest.py b/tests/rust/RustClippyLintBearTest.py new file mode 100644 index 0000000000..ec53bb0213 --- /dev/null +++ b/tests/rust/RustClippyLintBearTest.py @@ -0,0 +1,50 @@ +import unittest +import shutil +import os +from queue import Queue +from textwrap import dedent +from contextlib import ExitStack, contextmanager +from shutil import which +from unittest.case import skipIf + +from coala_utils.ContextManagers import prepare_file +from coalib.settings.Section import Section + +from bears.rust.RustClippyLintBear import RustClippyLintBear + + +@skipIf(which('cargo') is None, 'Cargo is not installed') +class RustClippyLintBearTest(unittest.TestCase): + + def setUp(self): + self.section = Section('name') + self.queue = Queue() + self.file_dict = {} + self.uut = RustClippyLintBear(self.file_dict, self.section, self.queue) + + def change_directory(self, directory_name): + test_path = os.path.abspath(os.path.join(os.path.dirname(__file__), + directory_name)) + os.chdir(test_path) + + def test_prerequisites(self): + _shutil_which = shutil.which + try: + shutil.which = lambda *args, **kwargs: None + self.assertEqual(RustClippyLintBear.check_prerequisites(), + 'cargo is not installed.') + + shutil.which = lambda *args, **kwargs: 'path/to/cargo' + self.assertTrue(RustClippyLintBear.check_prerequisites()) + finally: + shutil.which = _shutil_which + + def test_ok_source(self): + self.change_directory('test_ok') + results = list(self.uut.run()) + self.assertTrue(len(results) == 0) + + def test_bad_source(self): + self.change_directory('test_bad') + results = list(self.uut.run()) + self.assertTrue(len(results) >= 2) diff --git a/tests/rust/__init__.py b/tests/rust/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/rust/test_bad/Cargo.toml b/tests/rust/test_bad/Cargo.toml new file mode 100644 index 0000000000..ccaca8ccad --- /dev/null +++ b/tests/rust/test_bad/Cargo.toml @@ -0,0 +1,5 @@ +[package] +name = "coala_test_files" +version = "0.1.0" + +[dependencies] diff --git a/tests/rust/test_ok/Cargo.toml b/tests/rust/test_ok/Cargo.toml new file mode 100644 index 0000000000..ccaca8ccad --- /dev/null +++ b/tests/rust/test_ok/Cargo.toml @@ -0,0 +1,5 @@ +[package] +name = "coala_test_files" +version = "0.1.0" + +[dependencies]