Kotlin static code analysis using Detekt

Akshata Shelar
Globant
Published in
4 min readApr 9, 2021
Designed by freepik

Introduction

Static Code Analysis is the analysis of software, which is performed without actually executing programs.

It addresses weaknesses in the source code, this could be achieved through manual code reviews; however, using automated tools is much more effective and a preferred way.

For example, in the below code snippet, the sampleMethod() has almost 10 parameters to it, which can be really hard to maintain if the number of parameters keeps on increasing. These kinds of issues are difficult to identify manually, and here such automated tools play an important role.

In this article, we are going to explore one of the Static code check tools that is Detekt.

Detekt tries to improve the codebase by enforcing a set of rules including complexity, naming, etc. It can be integrated with CI, where it will act as a safety net in case we try to merge code with some code smells.

Features

  • Code smell analysis for Kotlin projects
  • Highly configurable
  • Suppress findings with Kotlin’s @Suppress and Java’s @SuppressWarnings annotations
  • Code Smell baseline and ignore lists for legacy projects
  • Specify code smell thresholds to break your build or print a warning
  • SonarQube integration

Having said that Detekt has an extensive range of rules available, lets have a look at some of them:

Rule Sets

  • Comments: Rules based on the principle that public things such as functions and properties should always have documentation.
  • Complexity: Rules that define a maximum size for a class/method, the maximum number of methods in classes, and the number of nested blocks.
  • Empty blocks: Rules to keep your code easy to read and identify any empty block.
  • Exceptions: Rules for issues related to how you throw and handle exceptions.
  • Formatting: Rules for formatting issues.
  • Naming: Rule related to names in your codebase, such as classes, functions, and packages, etc.
  • Performance: Rule for unnecessary variables and forEach on ranges.
  • Potential bugs: Rules for deprecation, redundant else, and unchecked casts.
  • Style: Rules for code style like collapse if statements, magic numbers, and optional braces.

Now, let's see how to configure Detekt:

  1. Add the detekt plugin to build.gradle

We need to add it to the top-level build.gradle under the allprojects section so it is applied to all of our modules & we also add the Detekt plugin under the plugins section, as shown in the below code snippet.

2. Setup a config

Detekt is highly configurable to meet your requirements. To generate a configuration file with various rules, we need to run the below command:

./gradlew detektGenerateConfig

Open the newly generated file in <project-root>/config/detekt/detekt.yml to start playing with various configuration options. This file contains various options and we can enable or disable them based on our requirements.

Example of Rule:

Here LongParameterList is the rule, which can be enabled or disabled using an active option. Threshold defines how many violations of this rule are allowed, and when the count reached a threshold, the given rule will fail.

3. Run detekt

Now the interesting part is to run the detekt command to check the health of our codebase.

./gradlew detekt

This command will apply all active rules and give us the result whether it is successful or not. If it fails then all the details of failed rules and code location will be shown and we can take corrective actions on them.

For example, if we run the detekt on the above DetektSample class, we will get the below error and the build will fail. The error is self-explanatory, the threshold for LongParameterList is defined as 6 but in the implementation, we have 10 parameters which is violating the rule.

Though sometimes we really can not fix the code in order to adapt to the failed rule. Don't worry we have a way to get a successful build…

We can use @Suppress() annotation to suppress any of the rules. To suppress an issue, the id of the issue must be written inside the values field of the annotation. For example @Suppress(“LongMethod”)

Note: We should use the above option in the worst case only.

Integrating Detekt into an ongoing project

When we integrate such static analysis tools at the beginning of the project, it works perfectly fine, but what about adding them in the middle of an ongoing project. Believe me, adding detekt to an ongoing project will result in many errors due to multiple rule sets available, however, we can decide on which rule sets we need and enable only those at the beginning, and the rest can be included as we progress.

Integrate Detekt to CI

So far what we understood is, whenever any developer is done with the task, the developer needs to run the detekt command to check if it has any code smells. But as the process is manual, developers may tend to forget this step. The best thing is with detekt gradle script we can easily automate it to run within a continuous integration (CI) process.

We just need to add the Gradle script to our pipeline in the appropriate step. They are lightweight tasks that are not at all time-consuming but have a lot of benefits.

Conclusion

And that was it for this article, we have set up really effective tool in such simple steps. Configuring such tools definitely helps maintain the good health of our code. We have many such tools available, but in my opinion, Detekt is a really effective tool in automatically finding and fixing minor issues throughout the development, because of the extensive range of rule sets available and those can be customized based on the project needs.

Happy Coding… :)

--

--