com.netflix.nebula.lint.rule.dependency.DuplicateDependencyService.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle-lint-plugin Show documentation
Show all versions of gradle-lint-plugin Show documentation
Pluggable and configurable linter tool for identifying and reporting on patterns of misuse or deprecations in Gradle scripts
package com.netflix.nebula.lint.rule.dependency
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.ModuleVersionIdentifier
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import java.util.*
class DuplicateDependencyService(val project: Project) {
companion object {
val BLACKLISTED_CLASSES = setOf(
"package-info",
"module-info"
)
}
val logger: Logger = LoggerFactory.getLogger(DuplicateDependencyService::class.java)
fun violationsForModules(moduleIds: List, conf: Configuration, ignoredDependencies: Set): List =
moduleIds.flatMap { violationsForModule(it, conf.name, ignoredDependencies) }
fun violationsForModule(mvid: ModuleVersionIdentifier, conf: String, ignoredDependencies: Set): List {
val dependencyService = DependencyService.forProject(project)
if (ignoredDependencies.contains(mvid)) {
return emptyList()
}
val dependencyClasses = dependencyService.jarContents(mvid.module)?.classes ?: return emptyList()
val dupeDependencyClasses = dependencyService.artifactsByClass(conf)
.filter {
var allowable = true
BLACKLISTED_CLASSES.forEach { bc ->
if (it.key.contains(bc)) {
allowable = false
}
}
allowable
}
.filter {
// don't count artifacts that have the same ModuleIdentifier, which are different versions of the same
// module coming from extended configurations that are ultimately conflict resolved away anyway
val artifacts = it.value
dependencyClasses.contains(it.key) && artifacts.any {
!ignoredDependencies.contains(it.moduleVersion.id) && it.moduleVersion.id.module != mvid.module
}
}
val dupeClassesByDependency = TreeMap>(DependencyService.DEPENDENCY_COMPARATOR)
dupeDependencyClasses.forEach { (className, resolvedArtifacts) ->
resolvedArtifacts.forEach { artifact ->
val moduleId = artifact.moduleVersion.id
if (!dupeClassesByDependency.containsKey(moduleId)) {
dupeClassesByDependency.put(moduleId, mutableSetOf())
}
dupeClassesByDependency[artifact.moduleVersion.id]!!.add(className)
}
}
val violations = mutableListOf()
val configuration = project.configurations.getByName(conf)
if (!dupeClassesByDependency.isEmpty() && mvid == dupeClassesByDependency.keys.first()) {
dupeClassesByDependency.forEach { (resolvedMvid, classes) ->
if (mvid != resolvedMvid) {
val message = "$mvid in $configuration has ${classes.size} classes duplicated by $resolvedMvid"
logger.info("$message. Duplicate classes: $classes")
violations.add("$message (use --info for detailed class list)")
}
}
}
return violations
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy