Skip to content

Commit

Permalink
RustClippyLintBear: Linter support for Rust code
Browse files Browse the repository at this point in the history
Closes #50
  • Loading branch information
rubdos committed Feb 28, 2017
1 parent 37578e1 commit e9a43e7
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 0 deletions.
63 changes: 63 additions & 0 deletions bears/rust/RustClippyLintBear.py
Original file line number Diff line number Diff line change
@@ -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']])
Empty file added bears/rust/__init__.py
Empty file.
2 changes: 2 additions & 0 deletions tests/rust/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
target
Cargo.lock
50 changes: 50 additions & 0 deletions tests/rust/RustClippyLintBearTest.py
Original file line number Diff line number Diff line change
@@ -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)
Empty file added tests/rust/__init__.py
Empty file.
5 changes: 5 additions & 0 deletions tests/rust/test_bad/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
name = "coala_test_files"
version = "0.1.0"

[dependencies]
5 changes: 5 additions & 0 deletions tests/rust/test_ok/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
name = "coala_test_files"
version = "0.1.0"

[dependencies]

0 comments on commit e9a43e7

Please sign in to comment.