android-templates icon indicating copy to clipboard operation
android-templates copied to clipboard

[#541] Integrate the Twitter Jetpack Compose Rules Detekt plugin

Open ryan-conway opened this issue 1 year ago β€’ 5 comments

closes #541

What happened πŸ‘€

  • Added the compose-rules detekt plugin
  • Updated detekt-config.yml
  • Added kotlinx.collections.immutable dependency and updated UI lists to use ImmutableList
  • Brought detekt rules changes to sample-compose

Insight πŸ“

  • As the Twitter compose-rules detekt plugin seems abandoned, we should instead use a forked version from one of the original maintainers which is being actively worked on πŸ™πŸ»
  • Because compose treats all instances of Collection (i.e., List, Set, etc.) as unstable, we should update all UI usages of collections to use their ImmutableX counterpart to reduce unnecessary recomposition.
    • Reference: https://medium.com/androiddevelopers/jetpack-compose-stability-explained-79c10db270c8
  • We have added ignoreAnnotated: [ 'Preview' ] to the MagicNumber rule as preview composables typically contain hard-coded values and we don't want these to be flagged πŸ‘€

Proof Of Work πŸ“Ή

With incorrect composable name (homeScreenContent), public @Preview and unstable lists:

ryanconway@Ryans-MacBook-Pro-13-2020-Nimble template-compose % detekt

> Task :detekt
.....................................................

53 kotlin files were analyzed.
/Users/ryanconway/Projects/Nimble/android-templates/template-compose/app/src/main/java/co/nimblehq/template/compose/ui/screens/home/HomeScreen.kt:41:13: Composable functions that return Unit should start with an uppercase letter.
They are considered declarative entities that can be either present or absent in a composition and therefore follow the naming rules for classes.

See https://mrmans0n.github.io/compose-rules/rules/#naming-composable-functions-properly for more information. [ComposableNaming]
/Users/ryanconway/Projects/Nimble/android-templates/template-compose/app/src/main/java/co/nimblehq/template/compose/ui/screens/home/HomeScreen.kt:62:5: Composables annotated with @Preview that are used only for previewing the UI should not be public.

See https://mrmans0n.github.io/compose-rules/rules/#preview-composables-should-not-be-public for more information. [PreviewPublic]
/Users/ryanconway/Projects/Nimble/android-templates/template-compose/app/src/main/java/co/nimblehq/template/compose/ui/screens/home/HomeScreen.kt:43:15: The Compose Compiler cannot infer the stability of a parameter if a List<UiModel> is used in it, even if the item type is stable.
You should use Kotlinx Immutable Collections instead: `uiModels: ImmutableList<UiModel>` or create an `@Immutable` wrapper for this class: `@Immutable data class UiModelsList(val items: List<UiModel>)`

See https://mrmans0n.github.io/compose-rules/rules/#avoid-using-unstable-collections for more information. [UnstableCollections]

/Users/ryanconway/Projects/Nimble/android-templates/template-compose/app/src/main/java/co/nimblehq/template/compose/ui/screens/home/HomeScreen.kt - 35min debt
        ComposableNaming - [Composable functions that return Unit should start with an uppercase letter. The(...)] at /Users/ryanconway/Projects/Nimble/android-templates/template-compose/app/src/main/java/co/nimblehq/template/compose/ui/screens/home/HomeScreen.kt:41:13
        PreviewPublic - [Composables annotated with @Preview that are used only for previewing the UI sho(...)] at /Users/ryanconway/Projects/Nimble/android-templates/template-compose/app/src/main/java/co/nimblehq/template/compose/ui/screens/home/HomeScreen.kt:62:5
        UnstableCollections - [The Compose Compiler cannot infer the stability of a parameter if a List<UiModel(...)] at /Users/ryanconway/Projects/Nimble/android-templates/template-compose/app/src/main/java/co/nimblehq/template/compose/ui/screens/home/HomeScreen.kt:43:15

Overall debt: 35min

Compose - 35min debt
        ComposableNaming - [Composable functions that return Unit should start with an uppercase letter. The(...)] at /Users/ryanconway/Projects/Nimble/android-templates/template-compose/app/src/main/java/co/nimblehq/template/compose/ui/screens/home/HomeScreen.kt:41:13
        PreviewPublic - [Composables annotated with @Preview that are used only for previewing the UI sho(...)] at /Users/ryanconway/Projects/Nimble/android-templates/template-compose/app/src/main/java/co/nimblehq/template/compose/ui/screens/home/HomeScreen.kt:62:5
        UnstableCollections - [The Compose Compiler cannot infer the stability of a parameter if a List<UiModel(...)] at /Users/ryanconway/Projects/Nimble/android-templates/template-compose/app/src/main/java/co/nimblehq/template/compose/ui/screens/home/HomeScreen.kt:43:15

Overall debt: 35min

Complexity Report:
        - 1,201 lines of code (loc)
        - 915 source lines of code (sloc)
        - 544 logical lines of code (lloc)
        - 22 comment lines of code (cloc)
        - 86 cyclomatic complexity (mcc)
        - 19 cognitive complexity
        - 3 number of total code smells
        - 2% comment source ratio
        - 158 mcc per 1,000 lloc
        - 5 code smells per 1,000 lloc

Project Statistics:
        - number of properties: 145
        - number of functions: 53
        - number of classes: 32
        - number of packages: 23
        - number of kt files: 53

Successfully generated Checkstyle XML report at /Users/ryanconway/Projects/Nimble/android-templates/template-compose/build/reports/detekt/detekt.xml
Successfully generated plain text report at /Users/ryanconway/Projects/Nimble/android-templates/template-compose/build/reports/detekt/detekt.txt
Successfully generated HTML report at /Users/ryanconway/Projects/Nimble/android-templates/template-compose/build/reports/detekt/detekt.html
Successfully generated SARIF: a standard format for the output of static analysis tools at /Users/ryanconway/Projects/Nimble/android-templates/template-compose/build/reports/detekt/detekt.sarif
Successfully generated Markdown report at /Users/ryanconway/Projects/Nimble/android-templates/template-compose/build/reports/detekt/detekt.md

BUILD SUCCESSFUL in 15s
5 actionable tasks: 1 executed, 4 up-to-date

With fixes applied:

ryanconway@Ryans-MacBook-Pro-13-2020-Nimble template-compose % detekt

> Task :detekt
.....................................................

53 kotlin files were analyzed.
Complexity Report:
        - 1,203 lines of code (loc)
        - 917 source lines of code (sloc)
        - 544 logical lines of code (lloc)
        - 22 comment lines of code (cloc)
        - 86 cyclomatic complexity (mcc)
        - 19 cognitive complexity
        - 0 number of total code smells
        - 2% comment source ratio
        - 158 mcc per 1,000 lloc
        - 0 code smells per 1,000 lloc

Project Statistics:
        - number of properties: 145
        - number of functions: 53
        - number of classes: 32
        - number of packages: 23
        - number of kt files: 53

Successfully generated Checkstyle XML report at /Users/ryanconway/Projects/Nimble/android-templates/template-compose/build/reports/detekt/detekt.xml
Successfully generated plain text report at /Users/ryanconway/Projects/Nimble/android-templates/template-compose/build/reports/detekt/detekt.txt
Successfully generated HTML report at /Users/ryanconway/Projects/Nimble/android-templates/template-compose/build/reports/detekt/detekt.html
Successfully generated SARIF: a standard format for the output of static analysis tools at /Users/ryanconway/Projects/Nimble/android-templates/template-compose/build/reports/detekt/detekt.sarif
Successfully generated Markdown report at /Users/ryanconway/Projects/Nimble/android-templates/template-compose/build/reports/detekt/detekt.md

BUILD SUCCESSFUL in 2s
5 actionable tasks: 1 executed, 4 up-to-date

ryan-conway avatar Nov 03 '23 08:11 ryan-conway

2 Warnings
:warning: Uh oh! HomeScreen.kt is under 95% coverage!
:warning: Uh oh! Your project is under 80% coverage!

Kover report for template-compose:

πŸ§› Template - Compose Unit Tests Code Coverage: 61.24%

Coverage of Modified Files:

File Coverage
HomeScreen.kt 61.42%
HomeViewModel.kt 100.00%

Modified Files Not Found In Coverage Report:

Dependencies.kt ItemList.kt Plugins.kt SecondScreen.kt ThirdScreen.kt Versions.kt Versions.kt build.gradle.kts build.gradle.kts build.gradle.kts build.gradle.kts detekt-config.yml detekt-config.yml

Codebase cunningly covered by count Shroud πŸ§›

Generated by :no_entry_sign: Danger

github-actions[bot] avatar Nov 03 '23 08:11 github-actions[bot]

Don't we need to apply these changes to sample @ryan-conway ?

kaungkhantsoe avatar Nov 24 '23 09:11 kaungkhantsoe

@ryan-conway Conflict πŸ˜Άβ€πŸŒ«οΈ

lydiasama avatar Dec 07 '23 03:12 lydiasama

IMO, the unstable list should be handled in another PR instead. This PR is about to update the Jetpack Compose Rule. πŸ€” Please correct me if I'm wrong. πŸ™‡πŸ»

lydiasama avatar Dec 07 '23 03:12 lydiasama

Don't we need to apply these changes to sample @ryan-conway ?

@kaungkhantsoe Updated in bfda1aa

IMO, the unstable list should be handled in another PR instead. This PR is about to update the Jetpack Compose Rule. πŸ€” Please correct me if I'm wrong. πŸ™‡πŸ»

@lydiasama That's a fair point, but since these are new rules introduced in this task it made sense to me to handle them here as well instead of opening another task, what do you think? πŸ€”

ryan-conway avatar Dec 15 '23 05:12 ryan-conway