Konsist
Konsist is a powerful static code analyzer tailored for Kotlin, focused on ensuring codebase consistency and adherence to coding conventions.
Install / Use
/learn @LemonAppDev/KonsistREADME
<img src="https://img.shields.io/maven-central/v/com.lemonappdev/konsist?label=Release"/>
Konsist is a linter that guards the consistency of Kotlin projects by enforcing a cohesive code structure and unified architecture. Konsist guards are written in the form of unit tests (JUnit / Kotest).
<p align="left"> <a href="https://kotlinfoundation.org/news/grants-program-winners-24/" target="_blank"> <img src="misc/library-grant-program-winner.png" alt="Library Grant Program Winner 2024" title="Library Grant Program Winner 2024" width="210"> </a> </p>Dependencies
Gradle Kotlin:
testImplementation("com.lemonappdev:konsist:0.17.3")
Gradle Groovy:
testImplementation "com.lemonappdev:konsist:0.17.3"
Maven:
<dependency>
<groupId>com.lemonappdev</groupId>
<artifactId>konsist</artifactId>
<version>0.17.3</version>
<scope>test</scope>
</dependency>
Getting Started
To begin using Konsist in your project, consider these steps:
- See Konsist Documentation to familiarize yourself with Konsist's features and usage guidelines.
- Check Starter Projects to see Konsist in action.
- Review Konsist API Reference to learn about the available API methods.
Examples
Konsist API reflects the structure of Kotlin code. All declarations such as classes, functions, and properties can be queried and verified with the Konsist API. Take a look at a few examples below.
General Kotlin Check
@Test
fun `classes with 'UseCase' suffix should reside in 'usecase' package`() {
Konsist.scopeFromProject()
.classes()
.withNameEndingWith("UseCase")
.assertTrue { it.resideInPackage("..usecase..") }
}
Android Specific Check
@Test
fun `classes extending 'ViewModel' should have 'ViewModel' suffix`() {
Konsist.scopeFromProject()
.classes()
.withAllParentsOf(ViewModel::class)
.assertTrue { it.name.endsWith("ViewModel") }
}
Spring Specific Check
@Test
fun `interfaces with 'Repository' annotation should have 'Repository' suffix`() {
Konsist
.scopeFromProject()
.interfaces()
.withAllAnnotationsOf(Repository::class)
.assertTrue { it.hasNameEndingWith("Repository") }
}
Architecture Layers Check
Test that Presentation and Data layers depend on Domain layer and Domain layer don't have any dependencies
from Presentation and Data layers.
%%{init: {'theme': 'forest'}}%%
flowchart
Presentation[Presentation Layer] & Data[Data Layer] --> Domain[Domain Layer]
@Test
fun `clean architecture layers have correct dependencies`() {
Konsist
.scopeFromProduction()
.assertArchitecture {
// Define layers
val domain = Layer("Domain", "com.myapp.domain..")
val presentation = Layer("Presentation", "com.myapp.presentation..")
val data = Layer("Data", "com.myapp.data..")
// Define architecture assertions
domain.dependsOnNothing()
presentation.dependsOn(domain)
data.dependsOn(domain)
}
}
Check out our snippet page for a feast of examples!
Articles & Videos
Check the videos & articles.
Star History
<picture> <source media="(prefers-color-scheme: dark)" srcset=" https://api.star-history.com/svg?repos=LemonAppDev/konsist/&type=Date&theme=dark " /> <source media="(prefers-color-scheme: light)" srcset=" https://api.star-history.com/svg?repos=LemonAppDev/konsisty&type=Date " /> <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=LemonAppDev/konsist&type=Date" /> </picture>Support
We're here to help you make the most of Konsist. Here are the best ways to get support:
For quick inquiries and general discussions, join our #konsist Slack channel. Use GitHub Discussion for bug reports, issues, and feature requests.
Sponsor Konsist
We appreciate your interest in Konsist. If you've found our project beneficial, please consider supportting the project.
Contributing
Please be sure to review Konsist contributing guidelines to learn how to support the project.
Licence
Konsist is distributed under the terms of the Apache License (Version 2.0). See LICENSE.md for details.
