d48cda4081
CI / Test (ubuntu-latest, Node 18.x, bun) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, npm) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, pnpm) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, yarn) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 20.x, bun) (push) Failing after 17m13s
CI / Test (ubuntu-latest, Node 20.x, npm) (push) Failing after 18m42s
CI / Test (ubuntu-latest, Node 20.x, pnpm) (push) Failing after 15m0s
CI / Test (ubuntu-latest, Node 20.x, yarn) (push) Failing after 49m44s
CI / Test (ubuntu-latest, Node 22.x, bun) (push) Failing after 51m55s
CI / Test (ubuntu-latest, Node 22.x, pnpm) (push) Failing after 21m57s
CI / Test (ubuntu-latest, Node 22.x, npm) (push) Failing after 37m39s
CI / Test (ubuntu-latest, Node 22.x, yarn) (push) Failing after 34m7s
CI / Validate Components (push) Failing after 37m15s
CI / Python Tests (push) Failing after 10m1s
CI / Security Scan (push) Failing after 10m1s
CI / Lint (push) Failing after 17m12s
CI / Coverage (push) Failing after 20m19s
CI / Test (macos-latest, Node 18.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, yarn) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, yarn) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, yarn) (push) Has been cancelled
2.6 KiB
2.6 KiB
paths
| paths | ||
|---|---|---|
|
Kotlin Coding Style
This file extends common/coding-style.md with Kotlin-specific content.
Formatting
- ktlint or Detekt for style enforcement
- Official Kotlin code style (
kotlin.code.style=officialingradle.properties)
Immutability
- Prefer
valovervar— default tovaland only usevarwhen mutation is required - Use
data classfor value types; use immutable collections (List,Map,Set) in public APIs - Copy-on-write for state updates:
state.copy(field = newValue)
Naming
Follow Kotlin conventions:
camelCasefor functions and propertiesPascalCasefor classes, interfaces, objects, and type aliasesSCREAMING_SNAKE_CASEfor constants (const valor@JvmStatic)- Prefix interfaces with behavior, not
I:ClickablenotIClickable
Null Safety
- Never use
!!— prefer?.,?:,requireNotNull(), orcheckNotNull() - Use
?.let {}for scoped null-safe operations - Return nullable types from functions that can legitimately have no result
// BAD
val name = user!!.name
// GOOD
val name = user?.name ?: "Unknown"
val name = requireNotNull(user) { "User must be set before accessing name" }.name
Sealed Types
Use sealed classes/interfaces to model closed state hierarchies:
sealed interface UiState<out T> {
data object Loading : UiState<Nothing>
data class Success<T>(val data: T) : UiState<T>
data class Error(val message: String) : UiState<Nothing>
}
Always use exhaustive when with sealed types — no else branch.
Extension Functions
Use extension functions for utility operations, but keep them discoverable:
- Place in a file named after the receiver type (
StringExt.kt,FlowExt.kt) - Keep scope limited — don't add extensions to
Anyor overly generic types
Scope Functions
Use the right scope function:
let— null check + transform:user?.let { greet(it) }run— compute a result using receiver:service.run { fetch(config) }apply— configure an object:builder.apply { timeout = 30 }also— side effects:result.also { log(it) }- Avoid deep nesting of scope functions (max 2 levels)
Error Handling
- Use
Result<T>or custom sealed types - Use
runCatching {}for wrapping throwable code - Never catch
CancellationException— always rethrow it - Avoid
try-catchfor control flow
// BAD — using exceptions for control flow
val user = try { repository.getUser(id) } catch (e: NotFoundException) { null }
// GOOD — nullable return
val user: User? = repository.findUser(id)