diff --git a/.ci/appveyor.yml b/.ci/appveyor.yml index c075afbe5a..531296bc2e 100644 --- a/.ci/appveyor.yml +++ b/.ci/appveyor.yml @@ -41,6 +41,9 @@ install: - "python -c \"import struct; print(struct.calcsize('P') * 8)\"" + - > + "curl -sSLO + https://github.com/shyiko/ktlint/releases/download/0.15.0/ktlint" - > "%CMD_IN_ENV% pip install --cache-dir=C:\\pip_cache -r requirements.txt -r test-requirements.txt diff --git a/.ci/deps.sh b/.ci/deps.sh index d3b544702b..a770490d9a 100644 --- a/.ci/deps.sh +++ b/.ci/deps.sh @@ -61,3 +61,8 @@ wget "https://downloads.sourceforge.net/project/astyle/astyle/astyle%203.0.1/ast tar -xvzf ~/astyle.tar.gz -C ~/ make -C ~/astyle/build/gcc sudo make install -C ~/astyle/build/gcc + +# ktlint installation +curl -sSLO https://github.com/shyiko/ktlint/releases/download/0.15.0/ktlint +sudo chmod a+x ktlint +sudo mv ktlint /usr/local/bin/ diff --git a/bears/kotlin/KotlinLintBear.py b/bears/kotlin/KotlinLintBear.py new file mode 100644 index 0000000000..12da57922c --- /dev/null +++ b/bears/kotlin/KotlinLintBear.py @@ -0,0 +1,27 @@ +from coalib.bearlib.abstractions.Linter import linter +from dependency_management.requirements.DistributionRequirement import ( + DistributionRequirement) + + +@linter(executable='ktlint', + global_bear=True, + output_format='regex', + output_regex=r'(?P.*):(?P\d+):' + r'(?P\d+): (?P.+)') +class KotlinLintBear: + """ + Lints your Kotlin Files. + Check code for coding standards or semantical problems that might lead + to problems in execution of the code. + See https://ktlint.github.io for more info. + """ + LANGUAGES = {'kotlin'} + REQUIREMENTS = {DistributionRequirement(brew='shyiko/ktlint/ktlint')} + AUTHORS = {'The coala developers'} + AUTHORS_EMAILS = {'coala-devel@googlegroups.com'} + LICENSE = 'AGPL-3.0' + CAN_DETECT = {'Formatting', 'Syntax'} + + @staticmethod + def create_arguments(config_file): + return () diff --git a/bears/kotlin/__init__.py b/bears/kotlin/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/kotlin/KotlinLintBearTest.py b/tests/kotlin/KotlinLintBearTest.py new file mode 100644 index 0000000000..d1b8ec1a44 --- /dev/null +++ b/tests/kotlin/KotlinLintBearTest.py @@ -0,0 +1,32 @@ +import unittest +import os +from queue import Queue + +from coalib.settings.Section import Section +from bears.kotlin.KotlinLintBear import KotlinLintBear +from coalib.testing.BearTestHelper import generate_skip_decorator + + +@generate_skip_decorator(KotlinLintBear) +class KotlinLintBearTest(unittest.TestCase): + + def setUp(self): + self.section = Section('Kotlin') + self.queue = Queue() + self.file_dict = {} + self.uut = KotlinLintBear(self.file_dict, self.section, self.queue) + + def set_config_dir(self, directory): + 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_bad_files(self): + self.set_config_dir('bad_files') + results = list(self.uut.run_bear_from_section([], {})) + self.assertTrue(len(results) > 5) + + def test_good_files(self): + self.set_config_dir('good_files') + results = list(self.uut.run_bear_from_section([], {})) + self.assertTrue(len(results) == 0) diff --git a/tests/kotlin/__init__.py b/tests/kotlin/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/kotlin/bad_files/bad_blanklines.kt b/tests/kotlin/bad_files/bad_blanklines.kt new file mode 100644 index 0000000000..a133eb4940 --- /dev/null +++ b/tests/kotlin/bad_files/bad_blanklines.kt @@ -0,0 +1,8 @@ +fun a() { + + +} +fun b() { + + +} \ No newline at end of file diff --git a/tests/kotlin/bad_files/bad_indent.kt b/tests/kotlin/bad_files/bad_indent.kt new file mode 100644 index 0000000000..08161e8e2f --- /dev/null +++ b/tests/kotlin/bad_files/bad_indent.kt @@ -0,0 +1,19 @@ +/** + * _ + */ +fun main() { + val a = 0 + val b = 0 + if (a == 0) { + println(a) + } + val b = builder().setX().setY() + .build() + val c = builder("long_string" + + "") +} +class A { + var x: String + get() = "" + set(v: String) { x = v } +} \ No newline at end of file diff --git a/tests/kotlin/bad_files/bad_semicolon.kt b/tests/kotlin/bad_files/bad_semicolon.kt new file mode 100644 index 0000000000..afe1efc5f7 --- /dev/null +++ b/tests/kotlin/bad_files/bad_semicolon.kt @@ -0,0 +1,6 @@ + package a.b.c; + fun main() { + fun name() { a(); return b } + println(";") + println(); + } \ No newline at end of file diff --git a/tests/kotlin/bad_files/bad_spacing.kt b/tests/kotlin/bad_files/bad_spacing.kt new file mode 100644 index 0000000000..237431246f --- /dev/null +++ b/tests/kotlin/bad_files/bad_spacing.kt @@ -0,0 +1 @@ +fun main() { x(1,3); x(1, 3)\n \n } \ No newline at end of file diff --git a/tests/kotlin/good_files/good_file.kt b/tests/kotlin/good_files/good_file.kt new file mode 100644 index 0000000000..7669a5d7df --- /dev/null +++ b/tests/kotlin/good_files/good_file.kt @@ -0,0 +1,6 @@ +fun a() { + val x = 5 + if (x == 0) { + println(a) + } +} \ No newline at end of file