diff --git a/.ci/appveyor.yml b/.ci/appveyor.yml
index c075afbe5a..51f2b187e2 100644
--- a/.ci/appveyor.yml
+++ b/.ci/appveyor.yml
@@ -4,6 +4,7 @@ environment:
# /E:ON and /V:ON options are not enabled in the batch script intepreter
# See: http://stackoverflow.com/a/13751649/163740
CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\.ci\\run_with_env.cmd"
+ RUST_TOOLCHAIN: "nightly-2017-07-20-x86_64-pc-windows-msvc"
matrix:
- PYTHON: "C:\\Python34"
@@ -20,6 +21,13 @@ cache:
- "C:\\Users\\appveyor\\AppData\\Local\\coala-bears\\coala-bears"
- "C:\\Users\\appveyor\\AppData\\Roaming\\nltk_data"
+# Workaround Appveyor bug:
+# http://help.appveyor.com/discussions/problems/7115-curl-cant-download-files-through-ssl
+init:
+ - ps: >
+ Disable-NetFirewallRule
+ -DisplayName 'Core Networking - Group Policy (LSASS-Out)'
+
branches:
except:
- /^sils\/.*/
@@ -49,6 +57,26 @@ install:
- "npm config set loglevel warn"
- "npm install"
+ - "curl -sSf -o rustup-init.exe https://win.rustup.rs/"
+ - "rustup-init.exe -y --default-toolchain=%RUST_TOOLCHAIN%"
+ # Normally, we shouldn't need the toolchain lib directory in our PATH
+ # https://github.com/rust-lang-nursery/rustup.rs/issues/876
+ # This is actually the sole reason that we really
+ # need the RUST_TOOLCHAIN variable.
+ - "set PATH=%PATH%;C:\\Users\\appveyor\\.cargo\\bin"
+ # Start ignoring YAMLLintBear
+ # because of the line length; plitting up these paths would become unreadable
+ - "set PATH=%PATH%;C:\\Users\\appveyor\\.rustup\\toolchains\\%RUST_TOOLCHAIN%\\bin"
+ - "set PATH=%PATH%;C:\\Users\\appveyor\\.rustup\\toolchains\\%RUST_TOOLCHAIN%\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib"
+ # Stop ignoring YAMLLintBear
+ - "cargo install clippy --vers 0.0.144"
+
+ # Print rust and cargo parameters for quick debugging.
+ - where rustc cargo
+ - rustc -vV
+ - cargo -vV
+ - cargo clippy -V
+
build: false # Not a C# project, build stuff at the test step instead.
test_script:
diff --git a/.ci/deps.sh b/.ci/deps.sh
index d3b544702b..df9ec5e08e 100644
--- a/.ci/deps.sh
+++ b/.ci/deps.sh
@@ -48,6 +48,24 @@ julia -e "Pkg.add(\"Lint\")"
# Lua commands
sudo luarocks install luacheck --deps-mode=none
+# Rust commands
+RUST_TOOLCHAIN=nightly-2017-07-20
+# Install Rustup
+curl -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain=$RUST_TOOLCHAIN
+# Make sure the specified nightly is the default.
+# This bypasses cache if needed, which the `sh` line above doesn't
+rustup default $RUST_TOOLCHAIN
+# Workaround https://github.com/rust-lang/cargo/issues/2078
+# and https://github.com/rust-lang/cargo/issues/2429 (explanation)
+# CircleCI gets its SSH agent activated, Travis doesn't need that.
+CLIPPY_VERSION=0.0.144
+if [ -e /home/ubuntu/.ssh/id_circleci_github ]; then
+ eval `ssh-agent`
+ ssh-add /home/ubuntu/.ssh/id_circleci_github
+fi
+cargo install clippy --vers $CLIPPY_VERSION --force
+cargo clippy -V
+
# PHPMD installation
if [ ! -e ~/phpmd/phpmd ]; then
mkdir -p ~/phpmd
diff --git a/.gitignore b/.gitignore
index 24d6ce89bf..0e44cd7b02 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,6 +23,7 @@ htmlcov
*.egg-info
.coverage.*
src
+!tests/rust/test_*/src
site
.zanata-cache
*.exe
diff --git a/.travis.yml b/.travis.yml
index 58384cf9eb..2604a6e8f1 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -68,6 +68,8 @@ cache:
- ~/dart-sdk/bin
- ~/.local/tailor/
- ~/phpmd
+ - ~/.rustup/
+ - ~/.cargo/
env:
global:
@@ -75,7 +77,7 @@ env:
- USE_PPAS="marutter/rdev staticfloat/juliareleases ondrej/golang"
- R_LIB_USER=~/R/Library
- LINTR_COMMENT_BOT=false
- - PATH="/opt/cabal/1.24/bin:$PATH:$TRAVIS_BUILD_DIR/node_modules/.bin:$TRAVIS_BUILD_DIR/vendor/bin:$HOME/dart-sdk/bin:$HOME/.cabal/bin:$HOME/infer-linux64-v0.7.0/infer/bin:$HOME/pmd-bin-5.4.1/bin:$HOME/bakalint-0.4.0:$HOME/elm-format-0.18:$HOME/.local/tailor/tailor-latest/bin:$HOME/phpmd"
+ - PATH="/opt/cabal/1.24/bin:$PATH:$TRAVIS_BUILD_DIR/node_modules/.bin:$TRAVIS_BUILD_DIR/vendor/bin:$HOME/dart-sdk/bin:$HOME/.cabal/bin:$HOME/infer-linux64-v0.7.0/infer/bin:$HOME/pmd-bin-5.4.1/bin:$HOME/bakalint-0.4.0:$HOME/elm-format-0.18:$HOME/.local/tailor/tailor-latest/bin:$HOME/phpmd:$HOME/.cargo/bin"
before_install:
- nvm install 6.10.2
diff --git a/README.rst b/README.rst
index 384024acab..ed2bce090a 100644
--- a/README.rst
+++ b/README.rst
@@ -4,8 +4,8 @@ coala-bears
-----------
coala-bears is a Python package containing all the bears that are officially
-supported by coala. It features more than **78 bears** covering
-**54 languages**. Here is a `generated list `_
+supported by coala. It features more than **79 bears** covering
+**55 languages**. Here is a `generated list `_
that contains information about each bear, such as the languages it supports and
what fixes it can apply to your code.
@@ -69,35 +69,35 @@ To see what coala can do for your language, run:
+----------------------------+----------------------------+----------------------------+
| Languages coala provides algorithms for |
+============================+============================+============================+
-| C | Latex | SQL |
+| C | Latex | sh & bash scripts |
+----------------------------+----------------------------+----------------------------+
-| C++ | Lua | Stylus |
+| C++ | Lua | SQL |
+----------------------------+----------------------------+----------------------------+
-| C# | Markdown | Swift |
+| C# | Markdown | Stylus |
+----------------------------+----------------------------+----------------------------+
-| CMake | Matlab/Octave | TypeScript |
+| CMake | Matlab/Octave | Swift |
+----------------------------+----------------------------+----------------------------+
-| CoffeeScript | Natural Language (English) | Verilog |
+| CoffeeScript | Natural Language (English) | Typescript |
+----------------------------+----------------------------+----------------------------+
-| CSS | Perl | VHDL |
+| CSS | Perl | Verilog |
+----------------------------+----------------------------+----------------------------+
-| Dart | PHP | Vimscript |
+| Dart | PHP | VHDL |
+----------------------------+----------------------------+----------------------------+
-| Fortran | Python 2 | XML |
+| Fortran | Python 2 | Vimscript |
+----------------------------+----------------------------+----------------------------+
-| Go | Python 3 | YAML |
+| Go | Python 3 | XML |
+----------------------------+----------------------------+----------------------------+
-| Haskell | R | |
+| Haskell | R | YAML |
+----------------------------+----------------------------+----------------------------+
| HTML | reStructured Text | |
+----------------------------+----------------------------+----------------------------+
| Java | Ruby | |
+----------------------------+----------------------------+----------------------------+
-| JavaScript | Scala | |
+| JavaScript | Rust | |
+----------------------------+----------------------------+----------------------------+
-| JSP | SCSS | |
+| JSP | Scala | |
+----------------------------+----------------------------+----------------------------+
-| Julia | sh & bash scripts | |
+| Julia | SCSS | |
+----------------------------+----------------------------+----------------------------+
The number of bears grows every day! If you want to see any particular
diff --git a/bears/rust/RustClippyLintBear.py b/bears/rust/RustClippyLintBear.py
new file mode 100644
index 0000000000..6bbe3ccf09
--- /dev/null
+++ b/bears/rust/RustClippyLintBear.py
@@ -0,0 +1,67 @@
+import json
+import os
+
+from coalib.bearlib.abstractions.Linter import linter
+from coalib.results.Result import Result
+from coalib.results.RESULT_SEVERITY import RESULT_SEVERITY
+from dependency_management.requirements.CargoRequirement import (
+ CargoRequirement)
+
+
+@linter(executable='cargo',
+ global_bear=True,
+ use_stdout=False,
+ use_stderr=True)
+class RustClippyLintBear:
+ 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.exe' if os.name == 'nt' else 'cargo'
+ REQUIREMENTS = {
+ CargoRequirement('clippy')
+ }
+ SEVERITY_MAP = {
+ 'warning': RESULT_SEVERITY.NORMAL,
+ 'error': RESULT_SEVERITY.MAJOR,
+ }
+
+ @staticmethod
+ def create_arguments(config_file):
+ args = ('clippy', '--quiet', '--color', 'never',
+ '--', '-Z', 'unstable-options',
+ '--error-format', 'json',
+ '--test')
+ return args
+
+ def process_output(self, output, filename, file):
+ # Rust outputs \n's, instead of the system default.
+ for line in output.split('\n'):
+ if not line:
+ continue
+ # cargo still outputs some text, even when in quiet mode,
+ # when a project does not build. We skip this, as the
+ # real reason will be reported on another line.
+ if line.startswith('To learn more, run the command again'):
+ 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/circle.yml b/circle.yml
index 23d37a01e9..e6d9ce8646 100644
--- a/circle.yml
+++ b/circle.yml
@@ -18,6 +18,8 @@ dependencies:
- ~/bakalint-0.4.0
- ~/.julia
- ~/.local/tailor/
+ - ~/.cargo
+ - ~/.rustup
pre:
- sudo rm -rf /var/cache/apt/archives
- sudo ln -s ~/.apt-cache /var/cache/apt/archives
@@ -33,6 +35,7 @@ dependencies:
- echo 'export PATH=$PATH:~/.local/tailor/tailor-latest/bin' >> ~/.circlerc
- echo 'export PATH=$PATH:~/elm-format-0.18' >> ~/.circlerc
- echo 'export PATH=$PATH:~/phpmd' >> ~/.circlerc
+ - echo 'export PATH=$PATH:~/.cargo/bin' >> ~/.circlerc
- echo 'export R_LIB_USER=~/.RLibrary' >> ~/.circlerc
- sed -i '/source \/home\/ubuntu\/virtualenvs\//d' ~/.circlerc
- mkdir -p ~/.RLibrary
@@ -48,6 +51,12 @@ dependencies:
timeout: 900 # Allow 15 mins before timing out due to "no output"
- bash .ci/deps.coala-bears.sh
+checkout:
+ post:
+ # Workaround https://github.com/rust-lang/cargo/issues/2078
+ # and https://github.com/rust-lang/cargo/issues/2429 (explanation)
+ - git config --global --unset url.ssh://git@github.com:.insteadof
+
machine:
node:
version: 6.10.2
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..9e3b1ea689
--- /dev/null
+++ b/tests/rust/RustClippyLintBearTest.py
@@ -0,0 +1,49 @@
+import unittest
+import os
+from queue import Queue
+from shutil import which
+from unittest.case import skipIf
+
+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 set_config_dir(self, directory):
+ # Work around https://github.com/coala/coala/issues/3867
+ test_path = os.path.abspath(os.path.join(
+ os.path.dirname(__file__), directory))
+ self.uut.get_config_dir = lambda *args, **kwargs: test_path
+
+ def test_ok_source(self):
+ self.set_config_dir('test_ok')
+ results = list(self.uut.run())
+ self.assertTrue(len(results) == 0)
+
+ def test_bad_source(self):
+ self.set_config_dir('test_bad')
+ results = list(self.uut.run())
+ self.assertTrue(len(results) >= 3)
+
+ def test_error_source(self):
+ self.set_config_dir('test_error')
+ results = list(self.uut.run())
+ self.assertTrue(len(results) == 1)
+
+ result = results[0]
+ print(result)
+ self.assertTrue(result.message == 'mismatched types')
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_bad/src/lib.rs b/tests/rust/test_bad/src/lib.rs
new file mode 100644
index 0000000000..c767679a79
--- /dev/null
+++ b/tests/rust/test_bad/src/lib.rs
@@ -0,0 +1,24 @@
+// This function should trigger unused code (warning level)
+fn testssss() {
+ // This comparison should trigger a `deny` level lint
+ let mut x: f64 = 0.0;
+ if x == std::f64::NAN {
+ }
+ x += 1.; // Triggers allow style lint
+ println!("{}", x);
+}
+
+
+// We test whether bad code is found in (unit) tests
+#[cfg(test)]
+mod tests {
+ #[test]
+ fn it_works() {
+ let x = Some(1u8);
+ // This match triggers a `warning` level lint
+ match x {
+ Some(y) => println!("{:?}", y),
+ _ => ()
+ }
+ }
+}
diff --git a/tests/rust/test_error/Cargo.toml b/tests/rust/test_error/Cargo.toml
new file mode 100644
index 0000000000..ccaca8ccad
--- /dev/null
+++ b/tests/rust/test_error/Cargo.toml
@@ -0,0 +1,5 @@
+[package]
+name = "coala_test_files"
+version = "0.1.0"
+
+[dependencies]
diff --git a/tests/rust/test_error/src/lib.rs b/tests/rust/test_error/src/lib.rs
new file mode 100644
index 0000000000..3baea9f592
--- /dev/null
+++ b/tests/rust/test_error/src/lib.rs
@@ -0,0 +1,4 @@
+fn main() {
+ // This does not compile. Message is 'mismatched types'
+ let a: i32 = "";
+}
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]
diff --git a/tests/rust/test_ok/src/lib.rs b/tests/rust/test_ok/src/lib.rs
new file mode 100644
index 0000000000..a93251b65d
--- /dev/null
+++ b/tests/rust/test_ok/src/lib.rs
@@ -0,0 +1,3 @@
+#[test]
+fn it_works() {
+}