Skip to content

fix(manifest): emit Kotlin, Android and sbt base-dir sources - #1662

Merged
Jeppe Fredsgaard Blaabjerg (jfblaa) merged 1 commit into
v1.xfrom
jfblaa/rea-1026-producer-source-roots
Oct 28, 2026
Merged

Jeppe Fredsgaard Blaabjerg (jfblaa) merged 1 commit into
v1.xfrom
jfblaa/rea-1026-producer-source-roots

Conversation

@jfblaa

@jfblaa Jeppe Fredsgaard Blaabjerg (jfblaa) commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

LLM Description written by Claude Code:claude-opus-5-5

Companion to coana-tech/coana-package-manager#2658 (REA-1026). With it, Coana skips a JVM project that has no source files in its sources and no class files in its targets, rather than halting. That turns producer gaps that hide real code into silent skips, so this closes the gaps we know of. It should land no later than the Coana bump that brings #2658.

  • Gradle, Kotlin: Kotlin source sets and class dirs of JVM and Android Kotlin compilations, including Kotlin Multiplatform's commonMain/jvmMain. Previously only Java source sets were emitted.
  • Gradle, Android: source sets from the android extension, plus the output dirs of the javac and Kotlin compile tasks. Previously nothing was emitted. AGP 9's built-in Kotlin leaves the compilations' class dirs empty, so those come from the compile tasks.
  • sbt: sources compiled from a project's base dir (sourcesInBase), taken from sbt's resolved unmanagedSources and emitted as individual files. sbt includes them non-recursively, and the base dir as a source root would pull nested subprojects into the parent. spar-jvm accepts file roots, so Coana needs no change.

Tested:

  • run-compat.sh sbt (0.13.18 to 1.9.9, plus Ivy) and run-compat.sh gradle (1.12 to 9.2.1). The sbt smoke test now asserts that a base-dir source is emitted as a file and the base dir never is.
  • Manual runs:
    • Kotlin Multiplatform on Gradle 9.2.1;
    • AGP 8.7.3 with and without Kotlin-Android on Gradle 8.10.2;
    • AGP 9.4.1 with built-in Kotlin on Gradle 9.6.0;
    • an sbt 1.9.9 build with base-dir sources in a root and a nested subproject, including a symlinked one.

The compat matrix runs offline against stub repositories, so it has no Kotlin or Android rows.

Known cost: on Android projects the script now realizes the javac and Kotlin compile tasks to read their output dirs.

🤖 Generated with Claude Code


Note

Medium Risk
Changes how JVM manifest scripts discover sources and class outputs for reachability; Android builds may realize compile tasks, and reflective Kotlin/AGP integration could behave differently across plugin versions.

Overview
Fixes reachability gaps where Gradle and sbt Socket facts omitted real application code, so downstream analysis could skip modules that looked sourceless.

Gradle (socket-facts.init.gradle) still walks Java sourceSets, and now also collects Kotlin JVM/Android compilation inputs and outputs (including KMP shared sets like commonMain) via the kotlin extension, plus Android java/kotlin/resources from the android extension. Compiled output for AGP (including built-in Kotlin on AGP 9) is taken from JavaCompile / KotlinCompileTool task destination dirs when compilation class dirs are empty.

sbt (socket-facts.plugin.scala) adds baseDirSources: files sbt compiles from the project base directory (sourcesInBase) are merged into module source lists as individual paths, avoiding emitting the base dir as a source root that would pull in nested subprojects.

The sbt compat smoke test adds Base.scala and asserts projectSrc lists the file, not the base directory. CHANGELOG documents the user-facing fix.

Reviewed by Cursor Bugbot for commit 6c3c07c. Configure here.

Reachability treats a JVM project with no source or class files as having
no code, so code the facts producers fail to report is silently skipped.

- Gradle: Kotlin source sets and class dirs of JVM and Android Kotlin
  compilations (Kotlin Multiplatform's commonMain/jvmMain included), and
  Android source sets plus the javac and Kotlin compile tasks' outputs.
  AGP's built-in Kotlin leaves the compilations' class dirs empty, so
  those come from the compile tasks.
- sbt: sources sbt compiles from a project's base dir (`sourcesInBase`),
  taken from `unmanagedSources` and emitted as files, since sbt includes
  them non-recursively and the base dir as a root would pull in nested
  subprojects.
@jfblaa
Jeppe Fredsgaard Blaabjerg (jfblaa) merged commit b7879ec into v1.x Oct 28, 2026
11 checks passed
@jfblaa
Jeppe Fredsgaard Blaabjerg (jfblaa) deleted the jfblaa/rea-1026-producer-source-roots branch October 28, 2026 11:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants