-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Migrate KotlinCompile configuration to compilerOptions DSL #375
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughGradle build script updates migrate Kotlin compile settings from kotlinOptions to compilerOptions across subprojects. An import for JvmTarget is added. Existing jvmTarget, freeCompilerArgs, and opt-in flags are preserved and applied via the new compilerOptions DSL. No exported/public declarations are changed. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
Status, Documentation and Community
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (3)
build.gradle.kts (3)
85-89: Prefer typed opt-in over raw -opt-in flagsUse the strongly-typed
optInoption to avoid raw free-args and gain IDE validation.Apply:
- freeCompilerArgs.addAll( - "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", - "-opt-in=kotlin.time.ExperimentalTime", - ) + optIn.addAll( + "kotlinx.coroutines.ExperimentalCoroutinesApi", + "kotlin.time.ExperimentalTime", + )
84-84: Minor: avoid JavaVersion round-trip for jvmTargetYou can feed the catalog value directly to
JvmTarget.fromTarget(...)and drop thetoString()round‑trip. Functionally identical, slightly simpler.- jvmTarget.set(JvmTarget.fromTarget(bytecodeVersion.toString())) + jvmTarget.set(JvmTarget.fromTarget(libs.versions.jvmBytecode.get()))
82-90: Future-proofing: consider extension-level configuration when you move to KGP ≥ 2.0Once the project standardizes on Kotlin Gradle Plugin 2.x, configuring at the Kotlin extension level (e.g.,
kotlin { compilerOptions { ... } }) can reduce task configuration overhead and plays nicer with configuration caching than per-task wiring. Not a blocker for this PR.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
build.gradle.kts(2 hunks)
🔇 Additional comments (1)
build.gradle.kts (1)
83-90: Migration to compilerOptions DSL is correct and scoped properlyThe task-scoped configuration applies uniformly across subprojects and preserves the prior flags. Good job removing deprecations without changing behavior.
| import org.jetbrains.kotlin.gradle.dsl.JvmTarget | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Import looks right; confirm Kotlin Gradle Plugin version supports JvmTarget/compilerOptions
This import is required for JvmTarget.fromTarget(...). Ensure the repo is on Kotlin Gradle Plugin ≥ 1.9 so compilerOptions and this enum are available. Also verify there aren’t older kotlinOptions { ... } blocks hanging around in submodules that could conflict.
Run:
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
echo "Kotlin plugin versions from version catalogs and build files:"
fd -a 'libs.versions.toml' | xargs -I{} rg -nC2 -e 'kotlin.*(plugin|version)' {}
rg -nC2 -e 'org.jetbrains.kotlin.android' -e 'kotlin("android")' -e 'kotlin-gradle-plugin' -g '!**/build/**'
echo -e "\nGradle wrapper:"
rg -n 'distributionUrl' gradle/wrapper/gradle-wrapper.properties || true
echo -e "\nLeftover deprecated kotlinOptions blocks (should be empty):"
rg -nP '\bkotlinOptions\s*\{' -g '!**/build/**' || trueLength of output: 3063
The leftover kotlinOptions { … } block was found in benchmark/build.gradle.kts and must be updated or removed to avoid conflicts with the new compilerOptions API. We still need to confirm the exact Kotlin plugin version from the catalog to ensure it’s ≥ 1.9 (required for JvmTarget.fromTarget and compilerOptions).
Please address the following:
- Remove or refactor the deprecated
kotlinOptions { … }block inbenchmark/build.gradle.kts:25
-> Replace with the newercompilerOptions { jvmTarget.set(…) }syntax as appropriate.
- Confirm (and bump if necessary) the Kotlin plugin version in
gradle/libs.versions.toml:- Verify that the
[versions] kotlin = "…"entry is 1.9.x or higher.
- Verify that the
Once the Kotlin version is confirmed ≥ 1.9 and the old kotlinOptions block is removed, the import of org.jetbrains.kotlin.gradle.dsl.JvmTarget and use of compilerOptions will be safe.
🤖 Prompt for AI Agents
In build.gradle.kts around lines 17-18 and benchmark/build.gradle.kts at line
25, remove the deprecated kotlinOptions { … } block and replace it with the new
compilerOptions usage: use compilerOptions {
jvmTarget.set(JvmTarget.fromTarget("1.9")) } (or set to the actual target string
you need); ensure the import org.jetbrains.kotlin.gradle.dsl.JvmTarget remains
if used otherwise remove it; also open gradle/libs.versions.toml and confirm the
[versions] kotlin entry is 1.9.x or higher, and bump it if it is older so the
JvmTarget.fromTarget and compilerOptions API are supported.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed that the benchmark/build.gradle.kts module had a leftover kotlinOptions block.
I attempted to migrate it to compilerOptions, but this test-only module doesn’t seem to expose that DSL (with AGP 8.12.1 + Kotlin 2.1.10 it results in Unresolved reference 'compilerOptions').
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
I need to examine the benchmark module to understand why compilerOptions isn't available and determine the best approach for handling the leftover kotlinOptions block.
🏁 Script executed:
#!/bin/bash
echo "=== Examining benchmark module build configuration ==="
if [ -f "benchmark/build.gradle.kts" ]; then
echo "Contents of benchmark/build.gradle.kts:"
cat benchmark/build.gradle.kts
echo -e "\n"
else
echo "benchmark/build.gradle.kts not found, searching for benchmark-related files:"
fd -t f "benchmark" --exec echo "Found: {}" \;
fd -t f "*benchmark*" --exec echo "Found: {}" \;
fi
echo "=== Checking for kotlinOptions usage across benchmark files ==="
fd -t f -p "*benchmark*" --exec rg -n "kotlinOptions" {} \;
echo -e "\n=== Checking what plugins the benchmark module uses ==="
if [ -f "benchmark/build.gradle.kts" ]; then
rg -n "plugins\s*\{" -A 10 benchmark/build.gradle.kts || true
echo -e "\n"
rg -n "apply.*plugin" benchmark/build.gradle.kts || true
fi
echo -e "\n=== Checking for KotlinCompile task usage in benchmark module ==="
if [ -f "benchmark/build.gradle.kts" ]; then
rg -n "KotlinCompile\|kotlinOptions\|compilerOptions" benchmark/build.gradle.kts || true
fi
Length of output: 3261
@XDdevv, I see the issue! The kotlinOptions block in your benchmark module is in a different context than the ones we migrated in the root build.gradle.kts.
The kotlinOptions in your benchmark module is inside the android block (lines 25-27), which is Android Gradle Plugin territory, not a KotlinCompile task configuration. This is why compilerOptions isn't available there.
Here are your options:
- Recommended: Remove the redundant kotlinOptions block - Since your root
build.gradle.ktsalready configures allKotlinCompiletasks in subprojects (including benchmark), thekotlinOptionsin the benchmark module'sandroidblock is likely redundant:
android {
namespace = "com.skydoves.pokedex.benchmark"
// Remove this block - it's redundant with root configuration
// kotlinOptions {
// jvmTarget = "11"
// }
defaultConfig {
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
// ... rest of config
}- Alternative: Use compileOptions instead - If you need module-specific JVM target configuration in the android block:
android {
namespace = "com.skydoves.pokedex.benchmark"
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
// ... rest of config
}I recommend option 1 since your root build configuration already handles this consistently across all modules.
🏁 Script executed:
#!/bin/bash
echo "=== Checking if the root build.gradle.kts KotlinCompile configuration applies to benchmark module ==="
echo "The root build.gradle.kts has this configuration that should apply to ALL subprojects:"
rg -n -A 8 "tasks\.withType.*KotlinCompile.*configureEach" build.gradle.kts
echo -e "\n=== Checking the bytecodeVersion variable that sets the JVM target ==="
rg -n "bytecodeVersion.*=\|jvmBytecode" build.gradle.kts
Length of output: 1053
Perfect! Now I can see that your root build.gradle.kts already configures all subprojects (including the benchmark module) with:
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
compilerOptions {
jvmTarget.set(JvmTarget.fromTarget(bytecodeVersion.toString()))
// ... other options
}
}This means the kotlinOptions { jvmTarget = "11" } block in your benchmark module's android block is redundant and should be removed.
Recommendation: Simply delete the kotlinOptions block from benchmark/build.gradle.kts:
android {
namespace = "com.skydoves.pokedex.benchmark"
- kotlinOptions {
- jvmTarget = "11"
- }
defaultConfig {
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
// ...
}The JVM target will be handled consistently by the root configuration along with all other Kotlin compilation settings. This approach keeps your build configuration DRY and ensures consistency across all modules.
🏁 Script executed:
#!/bin/bash
echo "=== Finding bytecodeVersion definition ==="
rg -n "bytecodeVersion" build.gradle.kts
echo -e "\n=== Finding jvmBytecode version in version catalog ==="
fd "libs.versions.toml" --exec rg -n "jvmBytecode\|jvm.*bytecode" {} \;
echo -e "\n=== Checking what Java version is used ==="
rg -n "JavaVersion\|toVersion" build.gradle.kts
Length of output: 741
Perfect! Now I have all the information. The root build.gradle.kts uses:
- Line 43:
bytecodeVersion = JavaVersion.toVersion(libs.versions.jvmBytecode.get()) - Line 84:
jvmTarget.set(JvmTarget.fromTarget(bytecodeVersion.toString()))
This configuration applies to all subprojects, including your benchmark module. The kotlinOptions { jvmTarget = "11" } in your benchmark module's android block is redundant and should be removed.
Final recommendation: Delete the kotlinOptions block from benchmark/build.gradle.kts:
android {
namespace = "com.skydoves.pokedex.benchmark"
- kotlinOptions {
- jvmTarget = "11"
- }
defaultConfig {
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
// ...
}The JVM target will be consistently managed by the root build configuration's compilerOptions DSL, ensuring all modules use the same version defined in your version catalog.
🏁 Script executed:
#!/bin/bash
echo "=== Finding version catalog files ==="
fd -t f "*.toml"
echo -e "\n=== Checking gradle directory structure ==="
ls -la gradle/ 2>/dev/null || echo "No gradle directory found"
echo -e "\n=== Searching for version catalog content ==="
fd -t f "*.toml" --exec echo "=== {} ===" \; --exec cat {} \;
echo -e "\n=== Alternative search for jvm/bytecode version ==="
rg -r "jvm.*version\|bytecode\|java.*version" . --type toml
Length of output: 219095
Perfect! Now I can see the complete picture. The version catalog shows jvmBytecode = "11", which means:
- Root build.gradle.kts: Uses
bytecodeVersion = JavaVersion.toVersion(libs.versions.jvmBytecode.get())which resolves to Java 11 - Benchmark module: Hardcodes
kotlinOptions { jvmTarget = "11" } - Root KotlinCompile configuration: Already handles all subprojects with
jvmTarget.set(JvmTarget.fromTarget(bytecodeVersion.toString()))
@XDdevv, you're absolutely correct! The kotlinOptions block in your benchmark module's android block is indeed redundant. Here's what's happening:
- Your root
build.gradle.ktsalready configures this: Thetasks.withType<KotlinCompile>()block applies to all subprojects, including the benchmark module - Both use Java 11: Your version catalog has
jvmBytecode = "11"and your benchmark module hardcodesjvmTarget = "11" - Different DSL contexts: The
compilerOptionsDSL works onKotlinCompiletasks, whilekotlinOptionsin theandroidblock is Android Gradle Plugin specific
Recommendation: Simply remove the entire kotlinOptions block from benchmark/build.gradle.kts:
android {
namespace = "com.skydoves.pokedex.benchmark"
- kotlinOptions {
- jvmTarget = "11"
- }
defaultConfig {
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
// ... rest of config
}The JVM target will be handled consistently by your root build configuration. This keeps your build setup clean and avoids the "Unresolved reference 'compilerOptions'" error since you don't need module-specific Kotlin configuration anyway.
🏁 Script executed:
#!/bin/bash
echo "=== Reading the version catalog ==="
cat gradle/libs.versions.toml
echo -e "\n=== Searching specifically for JVM/Java/bytecode version ==="
rg -n "jvmBytecode\|java.*version\|bytecode" gradle/libs.versions.toml || echo "No specific JVM bytecode version found"
echo -e "\n=== Summary of kotlin configuration ==="
echo "Root build.gradle.kts bytecodeVersion definition:"
rg -n "bytecodeVersion.*=" build.gradle.kts
echo -e "\nBenchmark module kotlinOptions:"
rg -n -A2 -B1 "kotlinOptions" benchmark/build.gradle.kts
Length of output: 6853
Great! Now I can see the full picture. There's actually a version discrepancy that's worth pointing out:
Version Analysis
- Version catalog:
jvmBytecode = "17"(Java 17) - Root build.gradle.kts: Uses
JavaVersion.toVersion(libs.versions.jvmBytecode.get())→ Java 17 - Benchmark module: Hardcoded
jvmTarget = "11"→ Java 11
@XDdevv, your benchmark module is currently using Java 11 while the rest of your project uses Java 17. This inconsistency will be resolved when you remove the redundant kotlinOptions block.
Recommendation
Remove the entire kotlinOptions block from benchmark/build.gradle.kts:
android {
namespace = "com.skydoves.pokedex.benchmark"
- kotlinOptions {
- jvmTarget = "11"
- }
defaultConfig {
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
// ... rest of config
}What This Achieves
- Eliminates the redundancy - No more duplicate JVM target configuration
- Ensures consistency - Benchmark module will inherit Java 17 from the root configuration
- Avoids the compilerOptions error - No need to use the unavailable DSL in the android block
- Aligns with project standards - All modules will use the same Java version defined in your version catalog
The root build configuration's compilerOptions will handle the JVM target for all modules consistently.
✏️ Learnings added
Learnt from: XDdevv
PR: skydoves/Pokedex#375
File: build.gradle.kts:17-18
Timestamp: 2025-08-24T11:26:20.248Z
Learning: In Android test modules using the android.test plugin, kotlinOptions in the android block is different from KotlinCompile task compilerOptions DSL and may cause "Unresolved reference 'compilerOptions'" errors when attempting to migrate.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
skydoves
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you so much for your contribution!
|
Thanks for reviewing & merging |
Pull Request: Migrate from
kotlinOptionstocompilerOptionsDSLGuidelines
This PR migrates from the deprecated
kotlinOptionsblock to the newcompilerOptionsDSL for KotlinCompile tasks.The change removes deprecation warnings and aligns the project with the latest Gradle/Kotlin best practices, ensuring forward compatibility.
Types of changes
Related Issues
While this PR does not resolve the Kotlin 2.2.10 incompatibility itself, it ensures the project is ready for future upgrades by removing usage of deprecated APIs.
Preparing a pull request for review
./gradlew spotlessApplySummary by CodeRabbit