Make Your Code Clean with Ktlint
Kotlin is a new programing language, which has a beautiful syntax. Although people start using kotlin for Android development, it often takes time to discuss the rules how you write Kotlin. This is where ktlint comes in.
Ktlint is a static code analysis tool for kotlin. You can lint your code and even format them.
There are the things that Ktlint can do.
・lint your code and output the result in any way you want like xml, json.
・format your code based off of the result of the lint.
・exclude rules to a specific code or add your own rule.
In this article, I will go through all the Ktlint features from basic usage to custom rule or CI integration.
Topic
- Basic Usage
- Custom Output
- Rule Exclusion
- Custom Rule
- CI Integration
Basic Usage
It is easy to start ktlint for Android development. Add these lines to your build.gradle.
Now you are ready to start ktlint.
What you have to do now is to add a task for ktlint.
Let’s add two tasks, one is for lint and the other is for format.
You can see these tasks you’ve just created with ./gradlew tasks
Now you can lint your code with ./gradlew ktlint
and format them with ./gradlew ktFormat
Custom Output
After you lint your code, ktlint will output the result. There are three types of output. plain, checkstyle, json. or you can even customize the way it outputs.
plain (default)
checkstyle
json
custom output
To customize the output, you need to extend Reporter class
This CustomReporter
finds the number of lint errors and output “hello custom reporter” then “found [error num] errors”
Once you defined your custom reporter, just add it to the ReporterProvider
This is the output of your custom reporter
--reporter=custom-ktlint-rule
Rule Exclusion
What if you want to exclude a specific rule? There is a way to do so.
Turn on the --verbose
option and add a comment to the line you want to disable rules.
You could also disable rule adding /* ktlint-disable no-wildcard-imports */
until /* ktlint-enable no-wildcard-imports */
(https://medium.com/@shyiko/thanks-for-the-article-taku-semba-bd9898a3c011)
However, It is so much trouble to add a comment to each line.
Unfortunately there is no way to disable a specific rule other than the ways I showed above.
https://github.com/shyiko/ktlint/issues/21
Even though, you can use .editorconfig
file to specify your own style. ktlint will look at the .editorconfig
first, and lint the code based off of the config file.
Custom Rule
Sometimes you might want to add your own rule to Ktlint. Ktlint is capable of adding a new rule.
First thing you have to do is extend Rule Class
and override visit
function.
Did you notice the ASTNode
argument of the visit function. To add a custom rule, you need to understand what ASTNode is.
What is ASTNode
? AST is shorten for Abstract Syntax Tree.
Any code, regardless of programing language, can be represented as a collection of ASTNode. And They are Tree structured.
For example, the Add function shown above is a ASTNode of KtNamedFunction
, and it can be broken into smaller pieces like below.
And these nodes above can be broken into even smaller pieces until it can not be any smaller.
If you do not know what is what ASTNode, --print-ast
option will help.
Now that you understood what ASTNode is, let’s dive into how you can add your own custom rule to Ktlint.
Let’s say you want to specify the return type if it is a one-line expression function
First, you make your CustomRule class
Once you’ve defined the custom rule class, add it to RuleSetProvider
Still there are few more steps you have to get through.
Add META-INF/services/com.github.shyiko.ktlint.core.RuleSetProvider
file containing a fully qualified name of your provider and make your code into a jar file.
That’s it. Now you can apply your own rule to your code with option -R
If you want to write a test code for your rule, it would look like this.
And make sure the test passes.
CI Integration
You might have thought it is a bit hard to lint-check every time you write code.
Using CI will make your life so much better.
For example, with Danger, you can lint your project when a new pull-request is created and add a comment on GitHub.
I will not get into Danger any deeper for now, but Danger is helpful.
This is how it looks like, when you integrate with Danger.
Lastly
Ktlint is a good choice if you want to keep your kotlin code clean.