Skip to content

Commit

Permalink
KotlinLintBear.py: Add bear wrapping ktlint
Browse files Browse the repository at this point in the history
Checks for coding standards or semantic problems
in Kotlin files.

Closes coala#2152
  • Loading branch information
saksham189 committed Apr 14, 2018
1 parent b650a4b commit a6727cc
Show file tree
Hide file tree
Showing 15 changed files with 118 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .ci/appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ install:
- "python -c \"import struct; print(struct.calcsize('P') * 8)\""


- >
curl -sSLO
https://github.com/shyiko/ktlint/releases/download/0.15.0/ktlint
chmod a+x ktlint
sudo mv ktlint /usr/local/bin/
- >
"%CMD_IN_ENV% pip install
--cache-dir=C:\\pip_cache -r requirements.txt -r test-requirements.txt
Expand Down
5 changes: 5 additions & 0 deletions .ci/deps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,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/
26 changes: 26 additions & 0 deletions bears/kotlin/KotlinLintBear.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
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<line>\d+):(?P<column>\d+): '
r'(?P<message>.+)')
class KotlinLintBear:
"""
Lints your Kotlin files.
Checks for coding standards or semantic problems in Kotlin files.
"""
LANGUAGES = {'kotlin'}
REQUIREMENTS = {DistributionRequirement(brew='shyiko/ktlint/ktlint')}
AUTHORS = {'The coala developers'}
AUTHORS_EMAILS = {'[email protected]'}
LICENSE = 'AGPL-3.0'
CAN_DETECT = {'Formatting', 'Syntax'}
SEE_MORE = 'https://ktlint.github.io'

@staticmethod
def create_arguments(config_file):
return ()
Empty file added bears/kotlin/__init__.py
Empty file.
39 changes: 39 additions & 0 deletions tests/kotlin/KotlinLintBearTest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import os
import unittest
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) >10)

def test_good_files(self):
self.set_config_dir('good_files')
results = list(self.uut.run_bear_from_section([], {}))
self.assertTrue(len(results) == 0)

def test_config_files(self):
self.set_config_dir('test_files')
results = list(self.uut.run_bear_from_section([], {}))
self.assertTrue(len(results) == 1)
self.assertEqual(results[0].message,
'File must end with a newline (\\n)')
Empty file added tests/kotlin/__init__.py
Empty file.
3 changes: 3 additions & 0 deletions tests/kotlin/bad_files/bad_import.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import io.vertx.core.*
import com.google.inject.*
import pkg.UnusedClass
6 changes: 6 additions & 0 deletions tests/kotlin/bad_files/bad_modifier_order.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
abstract internal class A {
open protected val v = ""
open suspend internal fun f(v: Any): Any = ""
lateinit public var lv: String
tailrec abstract fun findFixPoint(x: Double = 1.0): Double
}
6 changes: 6 additions & 0 deletions tests/kotlin/bad_files/bad_semicolon.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package a.b.c;
fun main() {
fun name() { a(); return b }
println(";")
println();
}
2 changes: 2 additions & 0 deletions tests/kotlin/bad_files/bad_string_templates.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
val a = "class = ${String::class.toString()}"
val b = "not ${a}"
6 changes: 6 additions & 0 deletions tests/kotlin/good_files/good_file.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fun a() {
val x = 5
if (x == 0) {
println(a)
}
}
6 changes: 6 additions & 0 deletions tests/kotlin/good_files/good_modifier_order.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
internal abstract class A {
protected open val v = ""
internal open suspend fun f(v: Any): Any = ""
public lateinit var lv: String
abstract tailrec fun findFixPoint(x: Double = 1.0): Double
}
6 changes: 6 additions & 0 deletions tests/kotlin/good_files/good_string_templates.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
internal abstract class A {
protected open val v = ""
internal open suspend fun f(v: Any): Any = ""
public lateinit var lv: String
abstract tailrec fun findFixPoint(x: Double = 1.0): Double
}
2 changes: 2 additions & 0 deletions tests/kotlin/test_files/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[*.{kt,kts}]
insert_final_newline=true
6 changes: 6 additions & 0 deletions tests/kotlin/test_files/good_file.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fun a() {
val x = 5
if (x == 0) {
println(a)
}
}

0 comments on commit a6727cc

Please sign in to comment.