autonomousapps / autonomousapps/dependency-analysis-gradle-plugin
Incorrect advice to change dependency from implementation to api
- Dominant language
- Kotlin
- Stars
- 2.2k
- Forks
- 158
- Avg merge
- 16h 25m
- Merged PRs (30d)
- 46
Description
**Plugin version**
"1.29.0"
**Gradle version**
Gradle-8.2
**JDK version**
openjdk version "17" 2021-09-14
OpenJDK Runtime Environment (build 17+35-2724)
OpenJDK 64-Bit Server VM (build 17+35-2724, mixed mode, sharing)
**(Optional) Kotlin and Kotlin Gradle Plugin (KGP) version**
"1.9.0"
**(Optional) Android Gradle Plugin (AGP) version**
8.2.0
**(Optional) `reason` output for bugs relating to incorrect advice**
```
> Task :feature:reason
----------------------------------------
You asked about the dependency 'androidx.compose.foundation:foundation-layout-android:1.6.0'.
You have been advised to change this dependency to 'api' from 'implementation'.
----------------------------------------
Shortest path from :feature to androidx.compose.foundation:foundation-layout-android:1.6.0 for debugCompileClasspath:
:feature
\--- androidx.compose.foundation:foundation-layout-android:1.6.0
Source: debug, main
-------------------
* Exposes 1 class: androidx.compose.foundation.layout.BoxScope (implies api).
```
**Describe the bug**
As per this article: https://dev.to/autonomousapps/dependency-analysis-gradle-plugin-what-s-an-abi-3l2h this plugin uses application binary interface as a source of advices. Unfortunately, compiler can add some optimizations, such as cache for lambdas:
```
@Lkotlin/Metadata;
public final class com/github/dependency/analysis/feature/ComposableSingletons$FeatureElementKt {
public static final field INSTANCE Lcom/github/dependency/analysis/feature/ComposableSingletons$FeatureElementKt;
public static field lambda-1 Lkotlin/jvm/functions/Function3;
public fun ()V
public final fun getLambda-1$feature_debug ()Lkotlin/jvm/functions/Function3;
}
```
And due to these transformations it is possible, that some classes will be treated as exposed (`BoxScope` from steps to reproduce section), but in fact they are not a part of actual public module API.
**To Reproduce**
Steps to reproduce the behavior:
1) Create library module, for example `uikit` with compose elements for android development.
```
@Composable
fun BaseFooter(subContent: @Composable BoxScope.() -> Unit) {
Box(modifier = Modifier.fillMaxSize()) {
subContent()
}
Text(text = "footer")
}
```
It exposes `BoxScope`, hence has `api("androidx.compose.foundation:foundation-layout-android")`
2) Create `feature` module and use `uikit` as a dependency:
```
@Composable
fun FeatureElement(text: String) {
Text(text = text)
// It triggers incorrect api suggestion due to cached lambda
BaseFooter {}
// This variant pass without any advice
// val someString = remember { "text" }
// BaseFooter { println(someString) }
}
```
This module doesn't expose BoxScope directly, just uses it internally, but plugin treats it as public usage.
**Expected behavior**
Plugin shouldn't advice to change from `implementation("androidx.compose.foundation:foundation-layout-android")` to `api("androidx.compose.foundation:foundation-layout-android")` for `feature` module.
**Additional context**
Test project: [DependencyAnalysisTest.zip](https://github.com/autonomousapps/dependency-analysis-gradle-plugin/files/14112408/DependencyAnalysisTest.zip) (don't forget to add `local.properties` with `sdk.dir=YOUR_PATH`)
Launch the `projectHealth` task for `feature` module
```
./gradlew :feature:projectHealth --no-configuration-cache
```
and check reason:
```
./gradlew :feature:reason --no-configuration-cache --id androidx.compose.foundation:foundation-layout-android
```
Contributor guide
Research direction
Start with the attached DependencyAnalysisTest.zip and run :feature:projectHealth, followed by :feature:reason --no-configuration-cache --id androidx.compose.foundation:foundation-layout-android. Compare the reason output for the BaseFooter and FeatureElement reproduction with the expected dependency advice; done when the feature module is no longer advised to change implementation to api.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, kotlin
- Domain
- build-system, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100