Skip to content

v0.18.0

Choose a tag to compare

@igorwojda igorwojda released this 09 Oct 11:23
· 143 commits to develop since this release
15baf2d

After a long break, I'm bringing Konsist back up to date. This release fixes the most frequently reported issue: Kotlin 2.4. Make sure to check the Migration guide: 0.18.0 breaking changes.

In the AI era, code gets generated faster and in more varied structures than ever. I hope Konsist helps you keep your codebase consistent and your architecture in check.

Community Feedback & What's Next

My next focus is processing community feedback, and I plan to dedicate more time to the project going forward. Apologies for the long silence; life had to take priority for a while. Thanks for your patience and continued support.

Feedback is welcome again! Help shape the future of Konsist: what features would make your work easier? Which bugs are getting in your way? Share your ideas in the #konsist channel or Github Discussions. Your feedback helps us decide what to tackle next.

Please help spread the word: Konsist is back!

Big thanks goes to @nataliapeterwas and @aburmeis for the contributions.

Key changes

Kotlin 2.4

Konsist is now built with Kotlin 2.4.21.

Minimum requirements have changed:

0.17.3 0.18.0
Kotlin 1.8+ 2.0+
Java (JVM) 8+ 17+

Konsist still works when your project resolves an older Kotlin compiler at runtime (e.g. Kotlin 2.3 enforced via kotlin-bom).

Companion Object Support

Companion objects can now be verified with Konsist:

// Snippet
class A {
    companion object
}

class B {
    companion object CustomCompanion
}

class C

// Konsist test
Konsist
    .scopeFromProject()
    .classes()
    .withCompanionObject() // [A, B]

Use includeNested = true to also include companion objects of nested classes:

Konsist
    .scopeFromProject()
    .classes()
    .companionObjects(includeNested = true)

Case-Insensitive Name Matching

All name-based methods (hasName..., withName..., hasXWithName..., withXNamed..., etc.) now accept an ignoreCase parameter (default false). A new hasName method was added for exact name matching.

Konsist
    .scopeFromProject()
    .classes()
    .withAnnotationNamed("sampleannotation", ignoreCase = true)
    .assertTrue { it.hasNameContaining("sample", ignoreCase = true) }

Annotation Source Declaration (⚠️ Breaking Change)

KoAnnotationDeclaration now provides sourceDeclaration, so annotation declarations can be verified directly:

Konsist
    .scopeFromProduction()
    .classes()
    .annotations
    .withSourceDeclaration { it.hasNameContaining("Sample") }
    .assertTrue { ... }

fullyQualifiedName of an annotation applied via an import alias now returns the real fully qualified name:

// Snippet
import com.domain.example.ExampleAnnotation as AnnotationAliased

@AnnotationAliased
class ExampleUseCase

// annotation.fullyQualifiedName
// Before: "AnnotationAliased"
// After:  "com.domain.example.ExampleAnnotation"

Enum Constant Improvements

Added ordinal property:

Konsist
    .scopeFromProject()
    .classes()
    .withEnumModifier()
    .enumConstants
    .filter { it.name == "UNKNOWN" }
    .assertTrue { it.ordinal == 0 }

KoEnumConstantDeclaration now provides properties, functions and classes declared in the constant body. Variable and local declaration accessors are deprecated (removal planned for 0.20.0):

enumConstant.hasProperty { it.hasGetter }    // previously hasVariable { ... }
enumConstant.hasFunction { it.hasReturnType() } // previously hasLocalFunction { ... }

Architecture Assertions

Fixed strict dependency check reporting conflicts between unrelated layers:

// Before: throws "already defined with a strict=true value"
// After: passes
presentation.dependsOn(domain, strict = true)
data.dependsOn(domain)

Layer documentation was updated to reflect the current package rules: .. wildcard is allowed at the start, middle or end of the package pattern.

Notable Bug Fixes

  • Declarations are now resolved correctly for wildcard imports and Kotlin default imports (e.g. hasParentOf(Throwable::class), hasAnnotationOf(RestController::class) with import org.springframework.web.bind.annotation.*)
  • typeArguments is now available for nullable types (e.g. List<String>?)
  • parameters is now available for nullable function types (e.g. ((String) -> Unit)?)
  • isGeneric now returns true for types with nullable type arguments (e.g. List<String?>)
  • .git directory is no longer scanned

Migration guide: 0.18.0 breaking changes

Other breaking changes are covered in Key changes: minimum Kotlin 2.0 / Java 17, and fullyQualifiedName of import-aliased annotations.

APIs deprecated in earlier releases have been removed. Properties on declarations (isNullable, isTopLevel and so on) work the same. Only code that refers to the old provider types or the removed list extensions needs changes.

Provider interfaces

Removed Use instead
KoNullableProvider KoIsNullableProvider
KoGenericTypeProvider KoIsGenericProvider (isGeneric)
KoConstructorDefinedProvider KoIsConstructorDefinedProvider
KoWildcardProvider KoIsWildcardProvider
KoInitializerProvider KoIsInitializedProvider
KoReadOnlyProvider KoIsReadOnlyProvider
KoTopLevelProvider KoIsTopLevelProvider

List extensions

Removed Use instead
withNullableType() withNullable()
withoutNullableType() withoutNullable()

Complete List Of Changes

⚠️ Breaking API Changes

🐛 API Bug Fixes

💡 API Improvements

💡 Improvements

📕 Documentation

🏗️ Maintenance

Full Changelog: v0.17.3...v0.18.0