Article

Android Static Code Checks — Keep Your Codebase Tidy With Detekt

Andrew Haisting

June 22, 2020

At Livefront , we’ve taken an initiative in the last year to reduce cognition spent on tasks that can be automated to save our brainwaves for the difficult tasks that count. By automating weekly releases, implementing coverage reporting on our core application logic, and bolstering our usage of static code checks, we’ve made our engineers happier and our codebases cleaner!

In this article we’ll focus on setting up detekt , a Kotlin specific linting tool that can enforce codebase documentation, give hints about code blocks that are getting a bit complicated, enforce formatting standards, and sniff out potential bugs before they hatch! Here’s how to get up and running:

1) Add the detekt gradle plugin to build/gradle¹:

Project level build.gradle

2) Reference that plugin in app level build.gradle:

apply plugin: 'io.gitlab.arturbosch.detekt'

With just those two steps, the detekt gradle plugin automatically defines a handful of new gradle tasks that we can call using the gradle wrapper (🎉). You can confirm by running the following command from the project root:

$ ./gradlew task

You should see a list of gradle tasks, including the brand new detekt ones:

Now that we’re setup, the real fun begins 😈! Run the following command to see an initial report on your codebase:

$ ./gradlew detekt
Detekt results on a blank codebase

Setting Up A Config

Detekt is highly configurable to meet your team’s requirements. To start tinkering with configuration, generate a config file by running:

 $ ./gradlew detektGenerateConfig

Open the newly generated file in <project-root>/config/detekt/detekt.yml to start playing with various configuration options. Here are a few our team has taken advantage of:

  • Setting maxIssues to 0, because why tolerate a codebase that isn’t squeaky clean?
  • Enabling UndocumentedPublicClass and UndocumentedPublicFunction to enforce codebase documentation.
  • Enabling MissingWhenCase to ensure our when statements are exhaustive.
  • Enabling ignoreOverridden on the TooManyFunctions check, so that we don’t have to suppress on Activity and Fragment classes that often require many overrides.

Setting Up Formatting Checks

Out of the box, the detekt gradle plugin will check for Kotlin code smells but does not do any checks on formatting. There is a formatting module that wraps ktlint that can be added by adding the following to your app/build.gradle:

After adding the formatting module, the formatting ruleset in detekt.yml becomes active. Out of the box, it uses the exact same rules as ktlint .

If You’re Adding To An Existing Project

The correct time to setup static code checks is always “now”, but what if your project is already in production and you have a couple hundred pre existing detekt warnings? Detekt allows you to specify a baseline file of warnings that will be ignored, so only new warnings cause failures. Here’s how to set it up:

First, run the following command to generate a baseline file:

$ ./gradlew detektBaseline

Then, add the following detekt config in app/build.gradle:

detekt {
// other detekt configuration goes here
baseline = file(“$rootDir/detekt-baseline.xml”)
}

Now, when running ./gradlew detekt, warnings listed in the baseline file will be ignored! You can update the baseline file at any time by re-running ./gradlew detektBaseline.

All of these static checks are great, but we can get even more value if we run these static checks locally before the CI and code review process. Stay tuned for part II where I’ll show how we use git pre-push hooks to catch lint and formatting errors before code review.

Andrew is an Android engineer at Livefront . He loves making apps so much, some of his friends even call him Android!

Footnotes:

  1. You can always find the latest version here: https://plugins.gradle.org/plugin/io.gitlab.arturbosch.detekt
  • Andrew Haisting

    Software Engineer

    Andrew Haisting