-
-
Notifications
You must be signed in to change notification settings - Fork 766
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
Add support to Kotlin Multiplatform Projects #3453
Conversation
Codecov Report
@@ Coverage Diff @@
## master #3453 +/- ##
============================================
+ Coverage 80.26% 80.72% +0.45%
- Complexity 2785 2804 +19
============================================
Files 454 455 +1
Lines 8418 8461 +43
Branches 1609 1616 +7
============================================
+ Hits 6757 6830 +73
+ Misses 789 758 -31
- Partials 872 873 +1
Continue to review full report at Codecov.
|
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.
Looking good overall. I have been wondering if you have an example project to do end-to-end test.
...kt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/internal/DetektMultiplatform.kt
Show resolved
Hide resolved
else -> false | ||
} | ||
|
||
val inputSource = compilation.allKotlinSourceSets.map { |
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.
The original documentation on KotlinCompilation is missing, so I read the code would like to confirm the logic with the logic at line 26:
allKotlinSourceSets seem to include both the target source set and all its dependants (which I imagine is common). This means we will be running detekt on both target source set + common set in this target-specific task.
Please correct me if my understanding is inaccurate or incorrect.
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.
Yes it's correct. That's how sourcesets are composed:
Task detektAndroidDebug - SourceSets: [ androidDebug commonMain androidMain ]
Task detektAndroidDebugAndroidTest - SourceSets: [ androidDebugAndroidTest commonTest androidAndroidTest androidAndroidTestDebug ]
Task detektAndroidDebugUnitTest - SourceSets: [ androidDebugUnitTest commonTest androidTest androidTestDebug ]
Task detektAndroidRelease - SourceSets: [ androidRelease commonMain androidMain ]
Task detektAndroidReleaseUnitTest - SourceSets: [ androidReleaseUnitTest commonTest androidTest androidTestRelease ]
Task detektIosArm64Main - SourceSets: [ iosArm64Main commonMain iosMain ]
Task detektIosArm64Test - SourceSets: [ iosArm64Test commonTest iosTest ]
Task detektIosX64Main - SourceSets: [ iosX64Main commonMain iosMain ]
Task detektIosX64Test - SourceSets: [ iosX64Test commonTest iosTest ]
Task detektJsMain - SourceSets: [ jsMain commonMain ]
Task detektJsTest - SourceSets: [ jsTest commonTest ]
Task detektJvmBackendMain - SourceSets: [ jvmBackendMain commonMain ]
Task detektJvmBackendTest - SourceSets: [ jvmBackendTest commonTest ]
Task detektJvmDesktopMain - SourceSets: [ jvmDesktopMain commonMain ]
Task detektJvmDesktopTest - SourceSets: [ jvmDesktopTest commonTest ]
So this means that if there is a finding in the common code, it will be reported for all the tasks until it gets fixed.
The alternative would be to remove the filter from line 26 and make sure that every task is excluding the common*
source sets from the input (I had troubles here with type resolution).
The result is that we will have 3 extra tasks that so composed:
Task detektMetadataCommonMain - SourceSets: [ ]
Task detektMetadataIosMain - SourceSets: [ ]
Task detektMetadataMain - SourceSets: [ commonMain ]
That turns to be really confusing (at least for me) as KMM creates a target called "metadata" for the common code with 3 compilations (main
, commonMain
and iosMain
).
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.
KMM creates a target called "metadata" for the common
If there are tasks already created with the name like compileMetadataMain
, I feel detekt should follow the convention.
I have also received some feedback (only a few) that certain rules are doubly reported, and reporting the same issue more than twice seems quite unsatisfactory to our users.
Do you know anyone else with KMM experience? We could seek their opinion if possible.
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.
Do you know anyone else with KMM experience? We could seek their opinion if possible.
I wrote here on Slack https://kotlinlang.slack.com/archives/C3PQML5NU/p1612899305397200 Let's see if we can get someone with KMM experience onboard
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.
Given that KMM is still in Alpha, I think simplicity (not filtering common
seems simpler) would make future migration easier since the tooling can be changed dramatically.
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 think simplicity (not filtering
common
seems simpler) would make future migration easier since the tooling can be changed dramatically.
Just to make sure I got you right, you're suggesting we remove filter { it.platformType != common }
but we still add it to all the tasks (given we use allKotlinSourceSets
)?
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 would vote for filter { it.platformType != common }
and use kotlinSourceSets
instead of allKotlinSourceSets
. But I am open to merge this in as-is and get inputs from other KMM experts or wait for feedback. I bet the API may get changed in the near future so it's probably not worth deciding everything at the moment.
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 would vote for filter { it.platformType != common } and use kotlinSourceSets instead of allKotlinSourceSets.
Removed the filter + changed. Just as a side note, kotlinSourceSets
for Android still includes the common source set, while this is not true for the other targets (that's also one of the reason why I switched to allKotlinSourceSets
as we would have had the common targets everywhere.
Here is what kotlinSourceSets
and allKotlinSourceSets
look like for all the tasks:
### Task detektAndroidDebug
allKotlinSourceSets = [androidDebug, commonMain, androidMain]
kotlinSourceSets = [androidDebug, commonMain, androidMain]
### Task detektAndroidDebugAndroidTest
allKotlinSourceSets = [androidDebugAndroidTest, commonTest, androidAndroidTest, androidAndroidTestDebug]
kotlinSourceSets = [androidDebugAndroidTest, commonTest, androidAndroidTest, androidAndroidTestDebug]
### Task detektAndroidDebugUnitTest
allKotlinSourceSets = [androidDebugUnitTest, commonTest, androidTest, androidTestDebug]
kotlinSourceSets = [androidDebugUnitTest, commonTest, androidTest, androidTestDebug]
### Task detektAndroidRelease
allKotlinSourceSets = [androidRelease, commonMain, androidMain]
kotlinSourceSets = [androidRelease, commonMain, androidMain]
### Task detektAndroidReleaseUnitTest
allKotlinSourceSets = [androidReleaseUnitTest, commonTest, androidTest, androidTestRelease]
kotlinSourceSets = [androidReleaseUnitTest, commonTest, androidTest, androidTestRelease]
### Task detektIosArm64Main
allKotlinSourceSets = [iosArm64Main, commonMain, iosMain]
kotlinSourceSets = [iosArm64Main]
### Task detektIosArm64Test
allKotlinSourceSets = [iosArm64Test, commonTest, iosTest]
kotlinSourceSets = [iosArm64Test]
### Task detektIosX64Main
allKotlinSourceSets = [iosX64Main, commonMain, iosMain]
kotlinSourceSets = [iosX64Main]
### Task detektIosX64Test
allKotlinSourceSets = [iosX64Test, commonTest, iosTest]
kotlinSourceSets = [iosX64Test]
### Task detektJsMain
allKotlinSourceSets = [jsMain, commonMain]
kotlinSourceSets = [jsMain]
### Task detektJsTest
allKotlinSourceSets = [jsTest, commonTest]
kotlinSourceSets = [jsTest]
### Task detektJvmBackendMain
allKotlinSourceSets = [jvmBackendMain, commonMain]
kotlinSourceSets = [jvmBackendMain]
### Task detektJvmBackendTest
allKotlinSourceSets = [jvmBackendTest, commonTest]
kotlinSourceSets = [jvmBackendTest]
### Task detektJvmDesktopMain
allKotlinSourceSets = [jvmDesktopMain, commonMain]
kotlinSourceSets = [jvmDesktopMain]
### Task detektJvmDesktopTest
allKotlinSourceSets = [jvmDesktopTest, commonTest]
kotlinSourceSets = [jvmDesktopTest]
@cortinico not sure if it complicates things, but would be nice to have a |
That will be added as soon as you add the |
This PR adds support to generate detekt tasks for Kotlin Multiplatform projects. Specifically, tasks for
jvm
andandroid
targets have Type Resolution enabled, whilejs
andnative
don't (as I still haven't found a way to properly invoke the compiler with the correct classpath/dependency).For a KMM project like this one:
The following tasks will be added to the graph:
Alongside
detektBaseline*
tasks for each of them.I still haven't managed to write documentation for this, since I'd like to kickoff the discussion to understand if this is going in the right direction.
Also with the KMM ecosystem growing quickly, I believe this could be a great addition to the ecosystem.
Related to #3414
Closes #3385