com.autonomousapps.model.intermediates.Usage.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dependency-analysis-gradle-plugin Show documentation
Show all versions of dependency-analysis-gradle-plugin Show documentation
Analyzes dependency usage in Android and JVM projects
package com.autonomousapps.model.intermediates
import com.autonomousapps.model.Advice
import com.autonomousapps.model.Coordinates
import com.autonomousapps.model.declaration.Bucket
import com.autonomousapps.model.declaration.Variant
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = false)
internal data class Usage(
val buildType: String?,
val flavor: String?,
val variant: Variant,
val bucket: Bucket,
val reasons: Set
) {
companion object {
val BY_VARIANT: Comparator = compareBy { it.variant }
}
/**
* Transform the variant-specific [usages][Usage] of a specific dependency, represented by its
* [coordinates][Coordinates], into a set of [advice][Advice]. This set may have zero or more elements.
*/
interface Transform {
fun reduce(usages: Set): Set
}
}
internal class UsageBuilder(
reports: Set,
private val variants: Collection
) {
val dependencyUsages: Map>
val annotationProcessingUsages: Map>
init {
val theDependencyUsages = mutableMapOf>()
val theAnnotationProcessingUsages = mutableMapOf>()
reports.forEach { report ->
report.dependencies.forEach { trace ->
theDependencyUsages.add(report, trace)
}
report.annotationProcessors.forEach { trace ->
theAnnotationProcessingUsages.add(report, trace)
}
}
addMissingVariants(theDependencyUsages)
addMissingVariants(theAnnotationProcessingUsages)
dependencyUsages = theDependencyUsages
annotationProcessingUsages = theAnnotationProcessingUsages
}
// The advice computation that follows expects every dependency to be associated with a usage for _each_ variant
// present in the build. To ensure this is the case, we add usages for missing variants
// (Bucket.NONE and Reason.UNDECLARED).
private fun addMissingVariants(map: MutableMap>) {
map.forEach { (_, theseUsages) ->
if (theseUsages.size < variants.size) {
variants.filterNot { variant ->
theseUsages.any { it.variant == variant }
}.forEach { missingVariant ->
theseUsages += Usage(
buildType = null,
flavor = null,
variant = missingVariant,
bucket = Bucket.NONE,
reasons = setOf(Reason.Undeclared)
)
}
}
}
}
private fun MutableMap>.add(
report: DependencyTraceReport,
trace: DependencyTraceReport.Trace
) {
val usage = Usage(
buildType = report.buildType,
flavor = report.flavor,
variant = report.variant,
bucket = trace.bucket,
reasons = trace.reasons
)
merge(trace.coordinates, mutableSetOf(usage)) { acc, inc ->
acc.apply { addAll(inc) }
}
}
}