Skip to content

chore(deps): update dependency io.insert-koin.compiler.plugin to v1.1.0 - #225

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/koin.plugin
Open

chore(deps): update dependency io.insert-koin.compiler.plugin to v1.1.0#225
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/koin.plugin

Conversation

@renovate

@renovate renovate Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Confidence
io.insert-koin.compiler.plugin (source) 1.0.11.1.0 age confidence

Release Notes

InsertKoinIO/koin-compiler-plugin (io.insert-koin.compiler.plugin)

v1.1.0

Compare Source

A compile-safety architecture release: per-module validation is removed entirely in favor
of a single, authoritative full-graph check at each Koin entry point. This closes a real,
measured false-positive class, at the cost of leaf modules with no entry point of their own now
getting no compile-time safety diagnostics until something assembles a real graph around them.
Also ships incremental-compilation freshness hardening, allWarningsAsErrors compatibility, and a
collision-safe hint-file-naming scheme.

⚠️ Behavior change — per-module validation removed, full-graph validation only (#​32, #​51)

Why. A module validated in isolation cannot know how it will be wired into a larger app. This
stopped being theoretical: :core:notifications in a real playground app genuinely false-positived
on a dependency (PeerService) that a peer module provides — with no Gradle edge between the two,
the two are only unified downstream at the app's entry point. Per-module validation — checking a
module against its own definitions, its includes = [...], and its @Configuration siblings —
cannot see that far, and reported a hard KOIN-D001 for a dependency that resolves correctly once
the real app assembles both modules together. Rather than keep tuning the per-module oracle around
each new false-positive shape, per-module validation (and its "defer iff a provider exists
somewhere" oracle) is deleted outright. Full-graph validation — the check that runs at
startKoin/koinApplication/@KoinApplication — is now the sole compile-safety verifier.

What this means for you:

  • Rooted compiles (an app module with a real startKoin/koinApplication/@KoinApplication):
    more accurate. Genuine cross-module false positives like the peer-provider case above disappear;
    KOIN-D001 now always shows the real, assembled graph.
  • Leaf/library modules with no Koin entry point in their own compilation: KOIN-D001
    (missing dependency), KOIN-D004 (circular dependency), KOIN-D005/KOIN-D006 (parametersOf
    shape mismatches resolved via the graph), and KOIN-P001 (missing @PropertyValue) are now
    silent in that compilation — not because the module is safe, but because compile-time cannot
    know how it will be assembled downstream. The graph is still checked, correctly, at the real
    entry point once one exists in the compilation. This is disclosed via a default-visible
    (INFO-severity) message rather than failing silently; see logSeverity below to control its
    visibility.
  • KOIN-W002 (the old "deferred, no provider hint found anywhere" warning) is deleted — there
    is no more deferral machinery to warn about.
  • Circular-dependency detection (KOIN-D004) going silent for a leaf module is intentional, not a
    regression: detecting a cycle requires seeing the whole graph, and a same-module-only check was
    never a complete cycle detector even under the old per-module validation (it only ever saw
    local/sibling visibility).

Full account, including the design docs this reverses: docs/COMPILE_SAFETY_A3_PLAN.md
(superseded-banner) and docs/COMPILE_TIME_SAFETY.md.

🐛 Fixes

Orphaned @Module classes were silently treated as reachable (found during this release's own verification)

A plain @Module @​ComponentScan(...) class with no @Configuration and not referenced by anyone's
includes = [...] was silently treated as part of the graph anyway, as long as the entry point used
a bare/default-labeled @KoinApplication/startKoin — the overwhelmingly common case. Its
@ComponentScan-discovered definitions (including cross-module ones) were folded into the resolved
graph and validated as satisfied, when the actual generated module tree never wired them in at all:
build green, runtime crash. Root cause: the entry-point module-discovery step accidentally called a
label-reader meant for the entry-point class's @KoinApplication(configurations=[...]) argument
against module classes, which never carry that annotation — so it always hit that reader's
"annotation absent" fallback (["default"]), making any @Module class match. This bug predates
1.1.0 (traced to 1.0.0-GA1) but was masked by the old per-module validation, which used to
validate each such module in isolation too; removing it made this bug load-bearing. Fixed, with a
regression test
(entry_orphan_module_not_reachable_d001) proving an orphaned module without @Configuration or an
includes edge is now correctly excluded from the graph.

KOIN-D001 now names the real culprit module and source location

Missing-dependency errors now carry file:line for the failing definition and the actual owning
module's name (previously degraded to a generic app/root label once every KOIN-D001 funnels
through the one remaining full-graph check). Also fixed: attribution for FunctionDef-shaped definitions
used a bare simple name, which could collide across same-named modules in different packages — now
uses the fully-qualified name.

KOIN-D001 deduplication across multiple entry points

A module reachable from more than one startKoin/koinApplication/@KoinApplication in the same
compilation (common in test-apps: ~9 entry points is typical) previously re-validated and re-emitted
the same missing-dependency error once per entry point. Now deduplicated by (definition, missing
requirement), so a shared module with one real problem reports it exactly once.

D005/D006 (parametersOf shape checks) no longer require a Koin entry point

The parametersOf(...) argument-count/presence check is graph-independent — the expected slots come
from the target's own constructor, not from an assembled graph — so it now runs unconditionally
instead of being skipped whenever no entry point is present in the compilation, matching its actual
data dependency. KOIN-D002 (call-site resolution) correctly keeps requiring an assembled graph
and stays silent without one — the two diagnostics no longer share a gate they don't share a
dependency on.

Cross-module qualifier and typed-scope resolution verified under the new sole-verifier design

New regression coverage confirms full-graph validation matches @Named qualifiers and typed
@Scope(X::class) keys correctly across Gradle module boundaries, not just "some provider of this
type exists somewhere" — this matters more now that there's no per-module fallback to catch a wrong
match.

Known pre-existing limitation, found while writing this coverage (not new, not fixed this
release):
BindingRegistry.findProvider's scope-visibility check only matches a typed
@Scope(X::class); a named @Scope(name = "...") provider has no scopeClass and is treated
as visible everywhere regardless of name.

🔒 Incremental-compilation freshness

Removing per-module leaf-local checking made full-graph validation's own freshness across
incremental (IC) rebuilds load-bearing in a way it wasn't before — these changes close that gap:

  • strictSafety is now mandatory once an aggregator is auto-detected, not opt-in. Previously,
    an explicit strictSafety = false silently won over the plugin's own startKoin/
    koinApplication/@KoinApplication detection, letting an aggregator's compileKotlin stay
    cacheable/up-to-date even when the DI graph changed underneath it (lambda-body DSL edits and
    new @ComponentScan-covered files don't register as ABI changes IC can see). strictSafety = true
    still works everywhere; the new escape hatch for a genuine detector misfire (the marker appears
    only in a comment/string, not a real entry point) is strictSafetyForceOff = true — a separate,
    explicit acknowledgement from a plain false.
  • Extended IC tracker linking: KoinDSLTransformer's 5 DSL definition call sites now register
    with ExpectActualTracker (alongside the existing LookupTracker calls), matching the pairing
    KoinAnnotationProcessor/KoinStartTransformer already had — closes another source of stale
    incremental state around DSL hint files.
  • A theorized @ComponentScan new-file freshness gap did not reproduce: adding a new
    @Singleton/@Factory class to a scanned package is itself a source-set input change, which
    Gradle already invalidates the owning module's compileKotlin task for, independent of anything
    Koin-specific — verified live on a real playground app. No plugin-side fix was needed here.
  • Known limitation, unchanged by this release: a module going completely empty (its last
    includes() or its last local definition removed, with nothing replacing it) is not detected
    incrementally without a full clean + --no-build-cache. This is a K2-internals residual (a
    keep-alive hint's signature not being re-resolved within one IC session), not a missing source
    edge — see playground-apps/README.md's "Known limitation" note.

🔇 allWarningsAsErrors / -Werror compatibility (#​73)

Informational plugin output (userLogs/debugLogs messages, the @Monitor-tracing-enabled
summary) was emitted at WARNING severity unconditionally, which fails a build compiled with
allWarningsAsErrors even though none of it is a real diagnostic.

  • New logSeverity option ("warning" default, or "info") covers all of the above.
  • New, separate versionCheckSeverity option covers only the Kotlin-version-compatibility
    warning ("you're on an unverified Kotlin version") — kept independent because muting informational
    noise shouldn't also silence a real compiler-compatibility risk; set it to "info" only after
    assessing that risk yourself.
  • Real diagnostics (KOIN-Dxxx/KOIN-Wxxx/etc.) are unaffected by either setting — they always
    report at their own severity.
koinCompiler {
    logSeverity = "info"           // downgrade informational output, default "warning"
    versionCheckSeverity = "info"  // downgrade the version-compatibility check, default "warning"
}

🧷 Hint-file collision safety (#​75)

Five internal call sites that generate synthetic hint file names for cross-module discovery used
unbounded-length, collision-prone name sanitization (e.g. p.q_r.mod and p.q.r_mod both
flattening to p_q_r_mod). All five now go through one shared utility: a bounded, readable prefix
plus a 64-bit hash suffix computed over the untruncated input, so truncation itself can never cause
a collision — this is a plain naming fix, not a diagnostic; file names have no external
reconstructors, so this changes freely.

Separately, the frozen, cross-version-reconstructed function-name encoder
(flattenFqNameForHint) stays unchanged (other Kotlin modules built with an older plugin version
reconstruct it, so it can't just be swapped for a hash) — but two distinct DSL module ids can still
flatten to the same identifier through it. New diagnostic KOIN-D008 hard-errors on that
specific collision when it happens within one compilation (e.g. two zero-parameter keep-alive hints
sharing a signature, a real KLIB SignatureClashDetector failure mode) — there is no legitimate
scenario where two distinct modules should collide, so there's no opt-out. Detecting the same
collision across Gradle modules is a known, explicitly deferred gap (would need to run at the
entry-point aggregator over already-decoded ids) — documented, not silent.

✅ Compatibility

  • Koin: 4.2.0+
  • Kotlin: verified range 2.3.0–2.3.10 (see CLAUDE.md for the version-gate policy)

📦 Install

plugins {
    id("io.insert-koin.compiler.plugin") version "1.1.0"
}

Full changelog: InsertKoinIO/koin-compiler-plugin@1.0.2...1.1.0

v1.0.2

Compare Source

A correctness-focused maintenance release: it removes several false compile-safety errors in multi-module projects, fixes duplicate-hint KLIB failures on iOS/Native/WASM-JS, and hardens per-compilation state under parallel Gradle daemons.

🔑 Highlights

  • No more false "missing dependency" errors across modules — a @Module whose dependency is provided by a sibling module (assembled only at @KoinApplication / startKoin) no longer fails with KOIN-D001. It defers to the entry-point graph, and surfaces a new KOIN-W002 warning only when no complete closure is visible in the compilation (#​51).
  • iOS / Native / WASM-JS build reliability — cross-module @ComponentScan and cross-module top-level @Single functions no longer emit duplicate hint declarations that broke KLIB serialization (#​62).
  • Fewer false compile-safety errors on DSL code — typed DSL definitions with custom lambdas, indirect parametersOf helpers, and outer DSL qualifiers are now understood (#​36, #​49, #​61, #​41).
  • Compose entry point validatedKoinApplication(configuration = koinConfiguration { … }) now runs full-graph safety (#​38).

🐛 Fixes

False KOIN-D001 for cross-module (sibling) dependencies — #​51 (KTZ-4256)

In a layered multi-module build, a @Module is compiled without visibility of the sibling modules a downstream @KoinApplication(modules = […]) assembles alongside it. Per-module (A2) validation therefore reported a provider that lives in a sibling as a hard KOIN-D001 missing dependency. Validation now defers an unresolved binding when a provider hint for the type exists elsewhere on the build graph, settling it authoritatively at the entry-point closure (A3) or at runtime checkModules(). When no complete closure is present in the compilation (e.g. a leaf library module), it emits the new KOIN-W002 warning instead of an error.

Scope: this narrows the false positive to the common shape (provider is a compile dependency, or compiled alongside the consumer). A genuine missing dependency with no provider hint anywhere is still a hard KOIN-D001. A provider that lives in a non-dependency peer module (type declared in a shared module) is not yet distinguishable at the leaf and may still report — full A2 relaxation is planned for 1.1.

Duplicate hint declarations broke iOS / Native / WASM-JS — #​62 (KTZ-4365)

A cross-module @ComponentScan covering a dependency module's package, and cross-module top-level @Single functions, could register the same definition more than once — emitting duplicate componentscan_* / definition_function_* hint declarations. The JVM/DEX toolchain tolerated it (a D8 "multiple definitions" warning); KLIB serialization (iOS/Native/WASM-JS) rejected it with a hard SignatureClashDetector error. Definitions are now de-duplicated by class identity (and by type+qualifier for functions), so each is emitted exactly once per target.

False KOIN-D001 for typed DSL definitions with non-create lambdas — #​36, #​49

single<T> { existingInstance }, single<T> { provideX() }, viewModel { VM() } and similar shapes are now recognized as providing T, so compile-safety no longer reports T as a missing definition. The user's lambda is left untouched.

False KOIN-D006 for indirect parametersOf helpers — #​61

A call site passing an opaque params lambda (e.g. { buildParams() }) no longer triggers KOIN-D006 ("forgot parametersOf"). The diagnostic now fires only when no params lambda is present at all.

Qualifier lost on DSL create definitions — #​41

An outer DSL qualifier (single<T>(named("x")) { create(::T) }) is now propagated into the compile-safety hints, so qualified cross-module definitions resolve correctly instead of producing spurious mismatches.

Compose koinConfiguration { } entry point not validated — #​38

KoinApplication(configuration = koinConfiguration { modules(…) }) is now recognized as a Koin entry point, enabling full-graph (A3) compile-safety for Compose apps. The koinConfiguration call is only marked as an entry point — it is not rewritten, so runtime behavior is unchanged.

Flaky / order-dependent behavior under parallel Gradle daemons — (KTZ-4414)

Plugin config flags and the @PropertyValue registry were held in process-global mutable state shared across every compilation in a Gradle daemon. Parallel or interleaved compilations could read another build's flags or have a @PropertyValue default dropped. State is now held per-compilation (thread-local, rebound onto the IR phase), matching the existing per-compilation message-collector handling.

⚠️ Auto-binding excludes framework/marker supertypes — #​43, #​64

This changes generated code and can affect runtime resolution. Auto-detected bindings no longer include framework plumbing / marker supertypes: kotlin.Any, org.koin.core.component.KoinComponent, KoinScopeComponent, and androidx.lifecycle.ViewModel / AndroidViewModel. Previously a @KoinViewModel / @Single class implementing one of these could be auto-bound to the framework base type, letting get<ViewModel>() / get<KoinComponent>() resolve to an arbitrary component (silent wrong-instance resolution). A definition is now registered under its own type and its genuine domain interfaces only.

Explicit bindings are unaffected@Single(binds = [ViewModel::class]) still binds exactly what you list. If you relied on auto-binding to one of the excluded supertypes, add it explicitly with binds = [...].

✅ Compatibility

Kotlin 2.3.20 Kotlin 2.4.0
JVM / Android
iOS / Native
WASM/JS — DSL
WASM/JS — annotations ⚠️ KT-82395
  • Koin: 4.2.0+

📦 Install

plugins {
    id("io.insert-koin.compiler.plugin") version "1.0.2"
}

Full changelog: InsertKoinIO/koin-compiler-plugin@1.0.1...1.0.2


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate
renovate Bot force-pushed the renovate/koin.plugin branch 2 times, most recently from ff222c7 to cfbe07b Compare July 23, 2026 07:16
@renovate
renovate Bot force-pushed the renovate/koin.plugin branch from cfbe07b to f60d685 Compare July 29, 2026 15:33
@renovate renovate Bot changed the title chore(deps): update dependency io.insert-koin.compiler.plugin to v1.0.2 chore(deps): update dependency io.insert-koin.compiler.plugin to v1.1.0 Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants